From 1469c78b58e40d0400487e61078b1297899d8956 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 10 Jun 2015 09:40:03 -0700 Subject: Fix USB access control when adb is disabled. When adb is disabled, the default usb mode would be "none", which would turn off the driver and prevent UsbDeviceManager from receiving any new USB connect / disconnect messages. This prevents the user from ever enabling MTP and sharing data when adb is turned off. As discussed in bug 21429947, we work around this problem by keeping the USB driver in MTP mode most of the time, so that we continue to receive USB connect / disconnect messages. To avoid leaking confidential user photos, this change honors the unlock state sent to us by the UsbDeviceManager code. We only expose user data if explicitly authorized by the user. MTP being enabled is decoupled from data being exposed on the USB connection. Bug: 21429947 Change-Id: I495011aa4e3e18c5e5e6fe7b9d0e1a3efe747ee7 --- src/com/android/providers/media/MtpReceiver.java | 10 ++++-- src/com/android/providers/media/MtpService.java | 43 +++--------------------- 2 files changed, 13 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/com/android/providers/media/MtpReceiver.java b/src/com/android/providers/media/MtpReceiver.java index 23d529bd..1f97f56f 100644 --- a/src/com/android/providers/media/MtpReceiver.java +++ b/src/com/android/providers/media/MtpReceiver.java @@ -23,9 +23,11 @@ import android.content.IntentFilter; import android.hardware.usb.UsbManager; import android.net.Uri; import android.os.Bundle; +import android.util.Log; public class MtpReceiver extends BroadcastReceiver { - private final static String TAG = "UsbReceiver"; + private static final String TAG = MtpReceiver.class.getSimpleName(); + private static final boolean DEBUG = false; @Override public void onReceive(Context context, Intent intent) { @@ -46,18 +48,22 @@ public class MtpReceiver extends BroadcastReceiver { boolean connected = extras.getBoolean(UsbManager.USB_CONFIGURED); boolean mtpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_MTP); boolean ptpEnabled = extras.getBoolean(UsbManager.USB_FUNCTION_PTP); + boolean unlocked = extras.getBoolean(UsbManager.USB_DATA_UNLOCKED); // Start MTP service if USB is connected and either the MTP or PTP function is enabled if (connected && (mtpEnabled || ptpEnabled)) { intent = new Intent(context, MtpService.class); + intent.putExtra(UsbManager.USB_DATA_UNLOCKED, unlocked); if (ptpEnabled) { intent.putExtra(UsbManager.USB_FUNCTION_PTP, true); } + if (DEBUG) { Log.d(TAG, "handleUsbState startService"); } context.startService(intent); // tell MediaProvider MTP is connected so it can bind to the service context.getContentResolver().insert(Uri.parse( "content://media/none/mtp_connected"), null); } else { - context.stopService(new Intent(context, MtpService.class)); + boolean status = context.stopService(new Intent(context, MtpService.class)); + if (DEBUG) { Log.d(TAG, "handleUsbState stopService status=" + status); } // tell MediaProvider MTP is disconnected so it can unbind from the service context.getContentResolver().delete(Uri.parse( "content://media/none/mtp_connected"), null, null); diff --git a/src/com/android/providers/media/MtpService.java b/src/com/android/providers/media/MtpService.java index 7f61d8ba..32e7f17c 100644 --- a/src/com/android/providers/media/MtpService.java +++ b/src/com/android/providers/media/MtpService.java @@ -17,12 +17,8 @@ package com.android.providers.media; import android.app.ActivityManager; -import android.app.KeyguardManager; import android.app.Service; -import android.content.BroadcastReceiver; -import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.hardware.usb.UsbManager; import android.mtp.MtpDatabase; import android.mtp.MtpServer; @@ -40,7 +36,7 @@ import java.util.HashMap; public class MtpService extends Service { private static final String TAG = "MtpService"; - private static final boolean LOGD = true; + private static final boolean LOGD = false; // We restrict PTP to these subdirectories private static final String[] PTP_DIRECTORIES = new String[] { @@ -66,32 +62,6 @@ public class MtpService extends Service { } } - private final BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (Intent.ACTION_USER_PRESENT.equals(action)) { - // If the media scanner is running, it may currently be calling - // sendObjectAdded/Removed, which also synchronizes on mBinder - // (and in addition to that, all the native MtpServer methods - // lock the same Mutex). If it happens to be in an mtp device - // write(), it may block for some time, so process this broadcast - // in a thread. - new Thread(new Runnable() { - @Override - public void run() { - synchronized (mBinder) { - // Unhide the storage units when the user has unlocked the lockscreen - if (mMtpDisabled) { - addStorageDevicesLocked(); - mMtpDisabled = false; - } - } - }}, "addStorageDevices").start(); - } - } - }; - private final StorageEventListener mStorageEventListener = new StorageEventListener() { @Override public void onStorageStateChanged(String path, String oldState, String newState) { @@ -114,6 +84,7 @@ public class MtpService extends Service { private StorageManager mStorageManager; /** Flag indicating if MTP is disabled due to keyguard */ private boolean mMtpDisabled; + private boolean mUnlocked; private boolean mPtpMode; private final HashMap mVolumeMap = new HashMap(); private final HashMap mStorageMap = new HashMap(); @@ -121,8 +92,6 @@ public class MtpService extends Service { @Override public void onCreate() { - registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_USER_PRESENT)); - mStorageManager = StorageManager.from(this); synchronized (mBinder) { updateDisabledStateLocked(); @@ -141,6 +110,8 @@ public class MtpService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { + mUnlocked = intent.getBooleanExtra(UsbManager.USB_DATA_UNLOCKED, false); + if (LOGD) { Log.d(TAG, "onStartCommand intent=" + intent + " mUnlocked=" + mUnlocked); } synchronized (mBinder) { updateDisabledStateLocked(); mPtpMode = (intent == null ? false @@ -171,10 +142,7 @@ public class MtpService extends Service { private void updateDisabledStateLocked() { final boolean isCurrentUser = UserHandle.myUserId() == ActivityManager.getCurrentUser(); - final KeyguardManager keyguardManager = (KeyguardManager) getSystemService( - Context.KEYGUARD_SERVICE); - mMtpDisabled = (keyguardManager.isKeyguardLocked() && keyguardManager.isKeyguardSecure()) - || !isCurrentUser; + mMtpDisabled = !mUnlocked || !isCurrentUser; if (LOGD) { Log.d(TAG, "updating state; isCurrentUser=" + isCurrentUser + ", mMtpLocked=" + mMtpDisabled); @@ -205,7 +173,6 @@ public class MtpService extends Service { @Override public void onDestroy() { - unregisterReceiver(mReceiver); mStorageManager.unregisterListener(mStorageEventListener); if (mDatabase != null) { mDatabase.setServer(null); -- cgit v1.2.3