From 580483eb72e45214f82f55f103a7134b3d83c7b6 Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Fri, 5 Jun 2020 13:10:29 -0700 Subject: [PATCH 1/2] Revert "Don't dismiss adb authorization prompt upon USB disconnect." This reverts commit e34087b1b3a84d49cc42af9bff276f7ad97e4ae5. Reason for revert: Restoring UsbDisconnectedReceiver to allow dialog in the background to be closed and redisplayed in the foreground by reseating the usb cable. Bug: 156323450 Test: Removed usb cable, verified dialog was closed Change-Id: I84a636ba3c9f7e35beb0769ae80aa6c6df0c2f2c --- .../dagger/DefaultActivityBinder.java | 15 +++++ .../systemui/usb/UsbDebuggingActivity.java | 55 ++++++++++++++++++ .../UsbDebuggingSecondaryUserActivity.java | 56 +++++++++++++++++++ 3 files changed, 126 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index 91f032d86a94a..28bcf3a351177 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -24,6 +24,8 @@ import com.android.systemui.keyguard.WorkLockActivity; import com.android.systemui.screenrecord.ScreenRecordDialog; import com.android.systemui.settings.BrightnessDialog; import com.android.systemui.tuner.TunerActivity; +import com.android.systemui.usb.UsbDebuggingActivity; +import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity; import dagger.Binds; import dagger.Module; @@ -70,4 +72,17 @@ public abstract class DefaultActivityBinder { @IntoMap @ClassKey(BubbleOverflowActivity.class) public abstract Activity bindBubbleOverflowActivity(BubbleOverflowActivity activity); + + /** Inject into UsbDebuggingActivity. */ + @Binds + @IntoMap + @ClassKey(UsbDebuggingActivity.class) + public abstract Activity bindUsbDebuggingActivity(UsbDebuggingActivity activity); + + /** Inject into UsbDebuggingSecondaryUserActivity. */ + @Binds + @IntoMap + @ClassKey(UsbDebuggingSecondaryUserActivity.class) + public abstract Activity bindUsbDebuggingSecondaryUserActivity( + UsbDebuggingSecondaryUserActivity activity); } diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java index 2973e0aedd436..6e041f6f9ee0f 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java @@ -16,13 +16,19 @@ package com.android.systemui.usb; +import android.app.Activity; import android.app.AlertDialog; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; import android.debug.IAdbManager; +import android.hardware.usb.UsbManager; import android.os.Bundle; import android.os.IBinder; import android.os.ServiceManager; +import android.os.SystemProperties; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -33,14 +39,25 @@ import android.widget.CheckBox; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.systemui.R; +import com.android.systemui.broadcast.BroadcastDispatcher; + +import javax.inject.Inject; public class UsbDebuggingActivity extends AlertActivity implements DialogInterface.OnClickListener { private static final String TAG = "UsbDebuggingActivity"; private CheckBox mAlwaysAllow; + private UsbDisconnectedReceiver mDisconnectedReceiver; + private final BroadcastDispatcher mBroadcastDispatcher; private String mKey; + @Inject + public UsbDebuggingActivity(BroadcastDispatcher broadcastDispatcher) { + super(); + mBroadcastDispatcher = broadcastDispatcher; + } + @Override public void onCreate(Bundle icicle) { Window window = getWindow(); @@ -50,6 +67,10 @@ public class UsbDebuggingActivity extends AlertActivity super.onCreate(icicle); + if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) { + mDisconnectedReceiver = new UsbDisconnectedReceiver(this); + } + Intent intent = getIntent(); String fingerprints = intent.getStringExtra("fingerprints"); mKey = intent.getStringExtra("key"); @@ -83,6 +104,40 @@ public class UsbDebuggingActivity extends AlertActivity super.onWindowAttributesChanged(params); } + private class UsbDisconnectedReceiver extends BroadcastReceiver { + private final Activity mActivity; + UsbDisconnectedReceiver(Activity activity) { + mActivity = activity; + } + + @Override + public void onReceive(Context content, Intent intent) { + String action = intent.getAction(); + if (!UsbManager.ACTION_USB_STATE.equals(action)) { + return; + } + boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); + if (!connected) { + mActivity.finish(); + } + } + } + + @Override + public void onStart() { + super.onStart(); + IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); + mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + } + + @Override + protected void onStop() { + if (mDisconnectedReceiver != null) { + mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver); + } + super.onStop(); + } + @Override public void onClick(DialogInterface dialog, int which) { boolean allow = (which == AlertDialog.BUTTON_POSITIVE); diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java index 4214242063705..8d3428a52e3b8 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java @@ -16,19 +16,41 @@ package com.android.systemui.usb; +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.hardware.usb.UsbManager; import android.os.Bundle; +import android.os.SystemProperties; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; import com.android.systemui.R; +import com.android.systemui.broadcast.BroadcastDispatcher; + +import javax.inject.Inject; public class UsbDebuggingSecondaryUserActivity extends AlertActivity implements DialogInterface.OnClickListener { + private UsbDisconnectedReceiver mDisconnectedReceiver; + private final BroadcastDispatcher mBroadcastDispatcher; + + @Inject + public UsbDebuggingSecondaryUserActivity(BroadcastDispatcher broadcastDispatcher) { + mBroadcastDispatcher = broadcastDispatcher; + } + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); + if (SystemProperties.getInt("service.adb.tcp.port", 0) == 0) { + mDisconnectedReceiver = new UsbDisconnectedReceiver(this); + } + final AlertController.AlertParams ap = mAlertParams; ap.mTitle = getString(R.string.usb_debugging_secondary_user_title); ap.mMessage = getString(R.string.usb_debugging_secondary_user_message); @@ -38,6 +60,40 @@ public class UsbDebuggingSecondaryUserActivity extends AlertActivity setupAlert(); } + private class UsbDisconnectedReceiver extends BroadcastReceiver { + private final Activity mActivity; + UsbDisconnectedReceiver(Activity activity) { + mActivity = activity; + } + + @Override + public void onReceive(Context content, Intent intent) { + String action = intent.getAction(); + if (UsbManager.ACTION_USB_STATE.equals(action)) { + boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); + if (!connected) { + mActivity.finish(); + } + } + } + } + + @Override + public void onStart() { + super.onStart(); + + IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); + mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + } + + @Override + protected void onStop() { + if (mDisconnectedReceiver != null) { + mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver); + } + super.onStop(); + } + @Override public void onClick(DialogInterface dialog, int which) { finish(); From d5d60d50eafd3a722871e2797c3fd4c305d387ce Mon Sep 17 00:00:00 2001 From: Michael Groover Date: Mon, 8 Jun 2020 18:39:57 -0700 Subject: [PATCH 2/2] Notify adb service on usb disconnect and activity stop When a system with a new key attempts to connect to adb adbd passes the key to the system_server which then launches an activity to prompt the user to allow the key; adbd then waits for a response from the system_server. For adb over usb if the user disconnects the usb cable before responding to the prompt the system_server will not send a response to adbd requiring a restart of adbd before a new connection can be established. This commit notifies the adb service when the usb cable is disconnected or when the activity is stopped through some other means (back, home, or recent apps buttons); the system_server then sends a response to adbd to deny the connection which allows subsequent connections to succeed. Fixes: 156323450 Test: Disconnected usb cable, used back, home, and recent buttons to stop app and verified subsequent connections displayed a prompt and adb sessions were successful when allowed. Change-Id: I50d5ce3a4a1fbdc2caa843b85e2905260a37a7e9 --- .../systemui/usb/UsbDebuggingActivity.java | 40 +++++++++++++++++-- .../UsbDebuggingSecondaryUserActivity.java | 20 ++++++++-- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java index 6e041f6f9ee0f..bc2a55c8d5c49 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java @@ -51,6 +51,7 @@ public class UsbDebuggingActivity extends AlertActivity private UsbDisconnectedReceiver mDisconnectedReceiver; private final BroadcastDispatcher mBroadcastDispatcher; private String mKey; + private boolean mServiceNotified; @Inject public UsbDebuggingActivity(BroadcastDispatcher broadcastDispatcher) { @@ -118,6 +119,7 @@ public class UsbDebuggingActivity extends AlertActivity } boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false); if (!connected) { + notifyService(false); mActivity.finish(); } } @@ -126,8 +128,10 @@ public class UsbDebuggingActivity extends AlertActivity @Override public void onStart() { super.onStart(); - IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); - mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + if (mDisconnectedReceiver != null) { + IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); + mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + } } @Override @@ -135,6 +139,12 @@ public class UsbDebuggingActivity extends AlertActivity if (mDisconnectedReceiver != null) { mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver); } + // If the ADB service has not yet been notified due to this dialog being closed in some + // other way then notify the service to deny the connection to ensure system_server sends + // a response to adbd. + if (!mServiceNotified) { + notifyService(false); + } super.onStop(); } @@ -142,6 +152,30 @@ public class UsbDebuggingActivity extends AlertActivity public void onClick(DialogInterface dialog, int which) { boolean allow = (which == AlertDialog.BUTTON_POSITIVE); boolean alwaysAllow = allow && mAlwaysAllow.isChecked(); + notifyService(allow, alwaysAllow); + finish(); + } + + /** + * Notifies the ADB service as to whether the current ADB request should be allowed; if the + * request is allowed it is only allowed for this session, and the user should be prompted again + * on subsequent requests from this key. + * + * @param allow whether the connection should be allowed for this session + */ + private void notifyService(boolean allow) { + notifyService(allow, false); + } + + /** + * Notifies the ADB service as to whether the current ADB request should be allowed, and if + * subsequent requests from this key should be allowed without user consent. + * + * @param allow whether the connection should be allowed + * @param alwaysAllow whether subsequent requests from this key should be allowed without user + * consent + */ + private void notifyService(boolean allow, boolean alwaysAllow) { try { IBinder b = ServiceManager.getService(ADB_SERVICE); IAdbManager service = IAdbManager.Stub.asInterface(b); @@ -150,9 +184,9 @@ public class UsbDebuggingActivity extends AlertActivity } else { service.denyDebugging(); } + mServiceNotified = true; } catch (Exception e) { Log.e(TAG, "Unable to notify Usb service", e); } - finish(); } } diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java index 8d3428a52e3b8..4850a025b6841 100644 --- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java @@ -22,9 +22,14 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.debug.IAdbManager; import android.hardware.usb.UsbManager; import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemProperties; +import android.util.Log; import com.android.internal.app.AlertActivity; import com.android.internal.app.AlertController; @@ -35,6 +40,7 @@ import javax.inject.Inject; public class UsbDebuggingSecondaryUserActivity extends AlertActivity implements DialogInterface.OnClickListener { + private static final String TAG = "UsbDebuggingSecondaryUserActivity"; private UsbDisconnectedReceiver mDisconnectedReceiver; private final BroadcastDispatcher mBroadcastDispatcher; @@ -81,9 +87,10 @@ public class UsbDebuggingSecondaryUserActivity extends AlertActivity @Override public void onStart() { super.onStart(); - - IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); - mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + if (mDisconnectedReceiver != null) { + IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE); + mBroadcastDispatcher.registerReceiver(mDisconnectedReceiver, filter); + } } @Override @@ -91,6 +98,13 @@ public class UsbDebuggingSecondaryUserActivity extends AlertActivity if (mDisconnectedReceiver != null) { mBroadcastDispatcher.unregisterReceiver(mDisconnectedReceiver); } + try { + IBinder b = ServiceManager.getService(ADB_SERVICE); + IAdbManager service = IAdbManager.Stub.asInterface(b); + service.denyDebugging(); + } catch (RemoteException e) { + Log.e(TAG, "Unable to notify Usb service", e); + } super.onStop(); }