File indexing completed on 2024-12-22 04:41:41

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Richard Wagler <riwag@posteo.de>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 package org.kde.kdeconnect.Plugins.SharePlugin;
0008 
0009 import android.app.Activity;
0010 import android.content.Context;
0011 import android.content.Intent;
0012 import android.content.SharedPreferences;
0013 import android.net.Uri;
0014 import android.os.Bundle;
0015 import android.os.Environment;
0016 import android.util.Log;
0017 
0018 import androidx.annotation.NonNull;
0019 import androidx.documentfile.provider.DocumentFile;
0020 import androidx.preference.Preference;
0021 import androidx.preference.PreferenceManager;
0022 import androidx.preference.PreferenceScreen;
0023 import androidx.preference.SwitchPreference;
0024 
0025 import org.kde.kdeconnect.UserInterface.PluginSettingsFragment;
0026 
0027 import java.io.File;
0028 
0029 public class ShareSettingsFragment extends PluginSettingsFragment {
0030 
0031     private final static String PREFERENCE_CUSTOMIZE_DESTINATION = "share_destination_custom";
0032     private final static String PREFERENCE_DESTINATION = "share_destination_folder_uri";
0033 
0034     private static final int RESULT_PICKER = Activity.RESULT_FIRST_USER;
0035 
0036     private Preference filePicker;
0037 
0038     public static ShareSettingsFragment newInstance(@NonNull String pluginKey, int layout) {
0039         ShareSettingsFragment fragment = new ShareSettingsFragment();
0040         fragment.setArguments(pluginKey, layout);
0041 
0042         return fragment;
0043     }
0044 
0045     @Override
0046     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
0047         super.onCreatePreferences(savedInstanceState, rootKey);
0048 
0049         PreferenceScreen preferenceScreen = getPreferenceScreen();
0050         final SwitchPreference customDownloads = preferenceScreen.findPreference("share_destination_custom");
0051         filePicker = preferenceScreen.findPreference("share_destination_folder_preference");
0052 
0053         customDownloads.setOnPreferenceChangeListener((preference, newValue) -> {
0054             updateFilePickerStatus((Boolean) newValue);
0055             return true;
0056         });
0057         filePicker.setOnPreferenceClickListener(preference -> {
0058             Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
0059             startActivityForResult(intent, RESULT_PICKER);
0060             return true;
0061         });
0062 
0063 
0064         boolean customized = PreferenceManager
0065                 .getDefaultSharedPreferences(requireContext())
0066                 .getBoolean(PREFERENCE_CUSTOMIZE_DESTINATION, false);
0067 
0068         updateFilePickerStatus(customized);
0069     }
0070 
0071     private void updateFilePickerStatus(boolean enabled) {
0072         filePicker.setEnabled(enabled);
0073         String path = PreferenceManager
0074                 .getDefaultSharedPreferences(requireContext())
0075                 .getString(PREFERENCE_DESTINATION, null);
0076 
0077         if (enabled && path != null) {
0078             filePicker.setSummary(Uri.parse(path).getPath());
0079         } else {
0080             filePicker.setSummary(getDefaultDestinationDirectory().getAbsolutePath());
0081         }
0082     }
0083 
0084     public static File getDefaultDestinationDirectory() {
0085         return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
0086     }
0087 
0088     public static boolean isCustomDestinationEnabled(Context context) {
0089         return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREFERENCE_CUSTOMIZE_DESTINATION, false);
0090     }
0091 
0092     //Will return the appropriate directory, whether it is customized or not
0093     public static DocumentFile getDestinationDirectory(Context context) {
0094         if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREFERENCE_CUSTOMIZE_DESTINATION, false)) {
0095             String path = PreferenceManager.getDefaultSharedPreferences(context).getString(PREFERENCE_DESTINATION, null);
0096             if (path != null) {
0097                 //There should be no way to enter here on api level < kitkat
0098                 DocumentFile treeDocumentFile = DocumentFile.fromTreeUri(context, Uri.parse(path));
0099                 if (treeDocumentFile.canWrite()) { //Checks for FLAG_DIR_SUPPORTS_CREATE on directories
0100                     return treeDocumentFile;
0101                 } else {
0102                     //Maybe permission was revoked
0103                     Log.w("SharePlugin", "Share destination is not writable, falling back to default path.");
0104                 }
0105             }
0106         }
0107         try {
0108             getDefaultDestinationDirectory().mkdirs();
0109         } catch (Exception e) {
0110             Log.e("KDEConnect", "Exception", e);
0111         }
0112         return DocumentFile.fromFile(getDefaultDestinationDirectory());
0113     }
0114 
0115     @Override
0116     public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
0117         if (requestCode == RESULT_PICKER
0118                 && resultCode == Activity.RESULT_OK
0119                 && resultData != null) {
0120             Uri uri = resultData.getData();
0121             saveStorageLocationPreference(requireContext(), uri);
0122 
0123             Preference filePicker = findPreference("share_destination_folder_preference");
0124             filePicker.setSummary(uri.getPath());
0125         }
0126     }
0127 
0128     public static void saveStorageLocationPreference(Context context, Uri uri) {
0129         context.getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION |
0130                 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
0131 
0132         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
0133         prefs.edit().putString(PREFERENCE_DESTINATION, uri.toString()).apply();
0134         prefs.edit().putBoolean(PREFERENCE_CUSTOMIZE_DESTINATION, true).apply();
0135     }
0136 }