Merge branch 'usb-otg-nearby-repos' into 'master'
fix repo handling on SDCard/USB-OTG See merge request fdroid/fdroidclient!950
This commit is contained in:
		
						commit
						f4ae1aacc7
					
				@ -100,7 +100,6 @@
 | 
			
		||||
                    android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
 | 
			
		||||
                    android:resource="@xml/device_filter"/>
 | 
			
		||||
        </receiver>
 | 
			
		||||
 | 
			
		||||
        <receiver
 | 
			
		||||
                android:name=".nearby.UsbDeviceDetachedReceiver">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
@ -110,6 +109,17 @@
 | 
			
		||||
                    android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
 | 
			
		||||
                    android:resource="@xml/device_filter"/>
 | 
			
		||||
        </receiver>
 | 
			
		||||
        <receiver android:name=".nearby.UsbDeviceMediaMountedReceiver">
 | 
			
		||||
            <intent-filter>
 | 
			
		||||
                <action android:name="android.intent.action.MEDIA_EJECT" />
 | 
			
		||||
                <action android:name="android.intent.action.MEDIA_REMOVED" />
 | 
			
		||||
                <action android:name="android.intent.action.MEDIA_MOUNTED" />
 | 
			
		||||
                <action android:name="android.intent.action.MEDIA_BAD_REMOVAL" />
 | 
			
		||||
 | 
			
		||||
                <data android:scheme="content" />
 | 
			
		||||
                <data android:scheme="file" />
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </receiver>
 | 
			
		||||
 | 
			
		||||
        <activity
 | 
			
		||||
                android:name=".panic.PanicPreferencesActivity"
 | 
			
		||||
 | 
			
		||||
@ -28,11 +28,10 @@ import android.net.Uri;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Environment;
 | 
			
		||||
import android.os.Process;
 | 
			
		||||
import androidx.core.content.ContextCompat;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import androidx.core.content.ContextCompat;
 | 
			
		||||
import org.fdroid.fdroid.IndexUpdater;
 | 
			
		||||
import org.fdroid.fdroid.IndexV1Updater;
 | 
			
		||||
import org.fdroid.fdroid.Preferences;
 | 
			
		||||
import org.fdroid.fdroid.Utils;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
@ -55,7 +54,7 @@ import java.util.List;
 | 
			
		||||
 * "External Storage"
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Scanning the removable storage requires that the user allowed it.  This
 | 
			
		||||
 * requires both the {@link Preferences#isScanRemovableStorageEnabled()}
 | 
			
		||||
 * requires both the {@link org.fdroid.fdroid.Preferences#isScanRemovableStorageEnabled()}
 | 
			
		||||
 * and the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
 | 
			
		||||
 * permission to be enabled.
 | 
			
		||||
 *
 | 
			
		||||
@ -75,11 +74,9 @@ public class SDCardScannerService extends IntentService {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void scan(Context context) {
 | 
			
		||||
        if (Preferences.get().isScanRemovableStorageEnabled()) {
 | 
			
		||||
            Intent intent = new Intent(context, SDCardScannerService.class);
 | 
			
		||||
            intent.setAction(ACTION_SCAN);
 | 
			
		||||
            context.startService(intent);
 | 
			
		||||
        }
 | 
			
		||||
        Intent intent = new Intent(context, SDCardScannerService.class);
 | 
			
		||||
        intent.setAction(ACTION_SCAN);
 | 
			
		||||
        context.startService(intent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,6 @@
 | 
			
		||||
package org.fdroid.fdroid.nearby;
 | 
			
		||||
 | 
			
		||||
import android.annotation.TargetApi;
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.app.IntentService;
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
@ -28,15 +27,14 @@ import android.content.Intent;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Process;
 | 
			
		||||
import androidx.documentfile.provider.DocumentFile;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
import androidx.documentfile.provider.DocumentFile;
 | 
			
		||||
import org.apache.commons.io.FileUtils;
 | 
			
		||||
import org.apache.commons.io.IOUtils;
 | 
			
		||||
import org.fdroid.fdroid.AddRepoIntentService;
 | 
			
		||||
import org.fdroid.fdroid.IndexUpdater;
 | 
			
		||||
import org.fdroid.fdroid.IndexV1Updater;
 | 
			
		||||
import org.fdroid.fdroid.Preferences;
 | 
			
		||||
import org.fdroid.fdroid.R;
 | 
			
		||||
import org.fdroid.fdroid.Utils;
 | 
			
		||||
import org.fdroid.fdroid.data.Repo;
 | 
			
		||||
@ -76,18 +74,21 @@ public class TreeUriScannerIntentService extends IntentService {
 | 
			
		||||
    public static final String TAG = "TreeUriScannerIntentSer";
 | 
			
		||||
 | 
			
		||||
    private static final String ACTION_SCAN_TREE_URI = "org.fdroid.fdroid.nearby.action.SCAN_TREE_URI";
 | 
			
		||||
    /**
 | 
			
		||||
     * @see <a href="https://android.googlesource.com/platform/frameworks/base/+/android-10.0.0_r38/core/java/android/provider/DocumentsContract.java#238">DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY</a>
 | 
			
		||||
     * @see <a href="https://android.googlesource.com/platform/frameworks/base/+/android-10.0.0_r38/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java#70">ExternalStorageProvider.AUTHORITY</a>
 | 
			
		||||
     */
 | 
			
		||||
    public static final String EXTERNAL_STORAGE_PROVIDER_AUTHORITY = "com.android.externalstorage.documents";
 | 
			
		||||
 | 
			
		||||
    public TreeUriScannerIntentService() {
 | 
			
		||||
        super("TreeUriScannerIntentService");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void scan(Context context, Uri data) {
 | 
			
		||||
        if (Preferences.get().isScanRemovableStorageEnabled()) {
 | 
			
		||||
            Intent intent = new Intent(context, TreeUriScannerIntentService.class);
 | 
			
		||||
            intent.setAction(ACTION_SCAN_TREE_URI);
 | 
			
		||||
            intent.setData(data);
 | 
			
		||||
            context.startService(intent);
 | 
			
		||||
        }
 | 
			
		||||
        Intent intent = new Intent(context, TreeUriScannerIntentService.class);
 | 
			
		||||
        intent.setAction(ACTION_SCAN_TREE_URI);
 | 
			
		||||
        intent.setData(data);
 | 
			
		||||
        context.startService(intent);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -19,28 +19,21 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.nearby;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.IntentFilter;
 | 
			
		||||
import android.content.UriPermission;
 | 
			
		||||
import android.database.ContentObserver;
 | 
			
		||||
import android.hardware.usb.UsbManager;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.annotation.RequiresApi;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import org.fdroid.fdroid.views.main.MainActivity;
 | 
			
		||||
import androidx.annotation.RequiresApi;
 | 
			
		||||
import org.fdroid.fdroid.views.main.NearbyViewBinder;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is just a shim to receive {@link UsbManager#ACTION_USB_ACCESSORY_ATTACHED}
 | 
			
		||||
@ -49,7 +42,6 @@ import java.util.HashMap;
 | 
			
		||||
public class UsbDeviceAttachedReceiver extends BroadcastReceiver {
 | 
			
		||||
    public static final String TAG = "UsbDeviceAttachedReceiv";
 | 
			
		||||
 | 
			
		||||
    private static final HashMap<Uri, ContentObserver> contentObservers = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @RequiresApi(api = 19)
 | 
			
		||||
    @Override
 | 
			
		||||
@ -77,6 +69,7 @@ public class UsbDeviceAttachedReceiver extends BroadcastReceiver {
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
            contentResolver.registerContentObserver(uri, true, contentObserver);
 | 
			
		||||
            UsbDeviceDetachedReceiver.contentObservers.put(uri, contentObserver);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -19,25 +19,17 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.nearby;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.ComponentName;
 | 
			
		||||
import android.content.ContentResolver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.content.IntentFilter;
 | 
			
		||||
import android.content.UriPermission;
 | 
			
		||||
import android.database.ContentObserver;
 | 
			
		||||
import android.hardware.usb.UsbManager;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Build;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import androidx.annotation.Nullable;
 | 
			
		||||
import androidx.annotation.RequiresApi;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import org.fdroid.fdroid.views.main.MainActivity;
 | 
			
		||||
import androidx.annotation.RequiresApi;
 | 
			
		||||
import org.fdroid.fdroid.views.main.NearbyViewBinder;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
@ -49,7 +41,7 @@ import java.util.HashMap;
 | 
			
		||||
public class UsbDeviceDetachedReceiver extends BroadcastReceiver {
 | 
			
		||||
    public static final String TAG = "UsbDeviceDetachedReceiv";
 | 
			
		||||
 | 
			
		||||
    private static final HashMap<Uri, ContentObserver> contentObservers = new HashMap<>();
 | 
			
		||||
    static final HashMap<Uri, ContentObserver> contentObservers = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    @RequiresApi(api = 19)
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,23 @@
 | 
			
		||||
package org.fdroid.fdroid.nearby;
 | 
			
		||||
 | 
			
		||||
import android.content.BroadcastReceiver;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.content.Intent;
 | 
			
		||||
import android.os.Environment;
 | 
			
		||||
import org.fdroid.fdroid.views.main.NearbyViewBinder;
 | 
			
		||||
 | 
			
		||||
public class UsbDeviceMediaMountedReceiver extends BroadcastReceiver {
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onReceive(Context context, Intent intent) {
 | 
			
		||||
        if (intent == null || intent.getAction() == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        String action = intent.getAction();
 | 
			
		||||
        if (Environment.MEDIA_BAD_REMOVAL.equals(action)
 | 
			
		||||
                || Environment.MEDIA_MOUNTED.equals(action)
 | 
			
		||||
                || Environment.MEDIA_REMOVED.equals(action)
 | 
			
		||||
                || Environment.MEDIA_EJECTING.equals(action)) {
 | 
			
		||||
            NearbyViewBinder.updateUsbOtg(context);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -13,6 +13,7 @@ import android.os.Build;
 | 
			
		||||
import android.os.Environment;
 | 
			
		||||
import android.os.storage.StorageManager;
 | 
			
		||||
import android.os.storage.StorageVolume;
 | 
			
		||||
import android.provider.DocumentsContract;
 | 
			
		||||
import android.text.TextUtils;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
@ -21,11 +22,9 @@ import android.widget.FrameLayout;
 | 
			
		||||
import android.widget.ImageView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.RequiresApi;
 | 
			
		||||
import androidx.core.app.ActivityCompat;
 | 
			
		||||
import androidx.core.content.ContextCompat;
 | 
			
		||||
 | 
			
		||||
import org.fdroid.fdroid.R;
 | 
			
		||||
import org.fdroid.fdroid.Utils;
 | 
			
		||||
import org.fdroid.fdroid.nearby.SDCardScannerService;
 | 
			
		||||
@ -61,6 +60,8 @@ import java.util.List;
 | 
			
		||||
 *
 | 
			
		||||
 * @see TreeUriScannerIntentService
 | 
			
		||||
 * @see org.fdroid.fdroid.nearby.SDCardScannerService
 | 
			
		||||
 * <p>
 | 
			
		||||
 * TODO use {@link StorageManager#registerStorageVolumeCallback(Executor, StorageManager.StorageVolumeCallback)}
 | 
			
		||||
 */
 | 
			
		||||
public class NearbyViewBinder {
 | 
			
		||||
    public static final String TAG = "NearbyViewBinder";
 | 
			
		||||
@ -165,11 +166,26 @@ public class NearbyViewBinder {
 | 
			
		||||
        for (final StorageVolume storageVolume : storageManager.getStorageVolumes()) {
 | 
			
		||||
            if (storageVolume.isRemovable() && !storageVolume.isPrimary()) {
 | 
			
		||||
                Log.i(TAG, "StorageVolume: " + storageVolume);
 | 
			
		||||
                final Intent intent = storageVolume.createAccessIntent(null);
 | 
			
		||||
                if (intent == null) {
 | 
			
		||||
                Intent tmpIntent = null;
 | 
			
		||||
                if (Build.VERSION.SDK_INT < 29) {
 | 
			
		||||
                    tmpIntent = storageVolume.createAccessIntent(null);
 | 
			
		||||
                } else {
 | 
			
		||||
                    tmpIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
 | 
			
		||||
                    tmpIntent.putExtra(DocumentsContract.EXTRA_INITIAL_URI,
 | 
			
		||||
                            Uri.parse("content://"
 | 
			
		||||
                                    + TreeUriScannerIntentService.EXTERNAL_STORAGE_PROVIDER_AUTHORITY
 | 
			
		||||
                                    + "/tree/"
 | 
			
		||||
                                    + storageVolume.getUuid()
 | 
			
		||||
                                    + "%3A/document/"
 | 
			
		||||
                                    + storageVolume.getUuid()
 | 
			
		||||
                                    + "%3A"));
 | 
			
		||||
                }
 | 
			
		||||
                if (tmpIntent == null) {
 | 
			
		||||
                    Utils.debugLog(TAG, "Got null Storage Volume access Intent");
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                final Intent intent = tmpIntent;
 | 
			
		||||
 | 
			
		||||
                storageVolumeText.setVisibility(View.VISIBLE);
 | 
			
		||||
 | 
			
		||||
                String text = storageVolume.getDescription(context);
 | 
			
		||||
@ -196,8 +212,23 @@ public class NearbyViewBinder {
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        ((Activity) context).startActivityForResult(intent,
 | 
			
		||||
                            MainActivity.REQUEST_STORAGE_ACCESS);
 | 
			
		||||
 | 
			
		||||
                        Activity activity = null;
 | 
			
		||||
                        if (context instanceof Activity) {
 | 
			
		||||
                            activity = (Activity) context;
 | 
			
		||||
                        } else if (swapView != null && swapView.getContext() instanceof Activity) {
 | 
			
		||||
                            activity = (Activity) swapView.getContext();
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (activity != null) {
 | 
			
		||||
                            activity.startActivityForResult(intent, MainActivity.REQUEST_STORAGE_ACCESS);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            // scan in the background without requesting permissions
 | 
			
		||||
                            Toast.makeText(context.getApplicationContext(),
 | 
			
		||||
                                    context.getString(R.string.scan_removable_storage_toast, externalStorage),
 | 
			
		||||
                                    Toast.LENGTH_SHORT).show();
 | 
			
		||||
                            SDCardScannerService.scan(context);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -539,7 +539,9 @@ public class FDroidApp extends Application {
 | 
			
		||||
            atStartTime.edit().remove(queryStringKey).apply();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        SDCardScannerService.scan(this);
 | 
			
		||||
        if (Preferences.get().isScanRemovableStorageEnabled()) {
 | 
			
		||||
            SDCardScannerService.scan(this);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -21,14 +21,14 @@
 | 
			
		||||
 | 
			
		||||
package org.fdroid.fdroid.views.main;
 | 
			
		||||
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import android.util.SparseIntArray;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
import android.view.ViewGroup;
 | 
			
		||||
import android.widget.FrameLayout;
 | 
			
		||||
import android.widget.PopupMenu;
 | 
			
		||||
import androidx.annotation.NonNull;
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity;
 | 
			
		||||
import androidx.recyclerview.widget.RecyclerView;
 | 
			
		||||
import org.fdroid.fdroid.R;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -76,6 +76,8 @@ class MainViewAdapter extends RecyclerView.Adapter<MainViewController> {
 | 
			
		||||
        long viewType = getItemId(holder.getAdapterPosition());
 | 
			
		||||
        if (viewType == R.id.updates) {
 | 
			
		||||
            holder.bindUpdates();
 | 
			
		||||
        } else if (viewType == R.id.nearby) {
 | 
			
		||||
            NearbyViewBinder.updateUsbOtg(activity);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user