diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9a152789e53b1..03de8c01e6b0b 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1763,6 +1763,12 @@ com.android.systemui/com.android.systemui.usb.UsbDebuggingActivity + + com.android.systemui/com.android.systemui.usb.UsbDebuggingSecondaryUserActivity + com.android.vpndialogs/com.android.vpndialogs.ConfirmDialog diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 9d56f13675852..de13f5431170f 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1825,6 +1825,7 @@ + diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index cc8e46bafed80..c25957350e70c 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -276,6 +276,11 @@ android:finishOnCloseSystemDialogs="true" android:excludeFromRecents="true"> + + Always allow from this computer + + USB debugging not allowed + + + The user currently signed in to this device can\'t turn on USB debugging. To use this feature, switch to the primary user \u201C%s\u201D. + Zoom to fill screen diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java new file mode 100644 index 0000000000000..9ce771bd9ee43 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingSecondaryUserActivity.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.content.pm.UserInfo; +import android.hardware.usb.UsbManager; +import android.os.Bundle; +import android.os.SystemProperties; +import android.os.UserHandle; +import android.os.UserManager; + +import com.android.internal.app.AlertActivity; +import com.android.internal.app.AlertController; +import com.android.systemui.R; + +public class UsbDebuggingSecondaryUserActivity extends AlertActivity + implements DialogInterface.OnClickListener { + private UsbDisconnectedReceiver mDisconnectedReceiver; + + @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); + UserInfo user = UserManager.get(this).getUserInfo(UserHandle.USER_OWNER); + ap.mMessage = getString(R.string.usb_debugging_secondary_user_message, user.name); + ap.mPositiveButtonText = getString(android.R.string.ok); + ap.mPositiveButtonListener = this; + + setupAlert(); + } + + private class UsbDisconnectedReceiver extends BroadcastReceiver { + private final Activity mActivity; + public 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); + registerReceiver(mDisconnectedReceiver, filter); + } + + @Override + protected void onStop() { + if (mDisconnectedReceiver != null) { + unregisterReceiver(mDisconnectedReceiver); + } + super.onStop(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + } +} diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java index 8849acd11ab12..9a04e8bb278a8 100644 --- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java +++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java @@ -16,6 +16,7 @@ package com.android.server.usb; +import android.app.ActivityManager; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; @@ -24,20 +25,21 @@ import android.content.pm.PackageManager; import android.content.res.Resources; import android.net.LocalSocket; import android.net.LocalSocketAddress; -import android.os.Handler; import android.os.Environment; import android.os.FileUtils; +import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; -import android.util.Slog; +import android.os.UserManager; import android.util.Base64; +import android.util.Slog; +import com.android.internal.R; import com.android.server.FgThread; -import java.lang.Thread; import java.io.File; import java.io.FileDescriptor; import java.io.FileOutputStream; @@ -319,28 +321,39 @@ public class UsbDebuggingManager { } private void startConfirmation(String key, String fingerprints) { - String nameString = Resources.getSystem().getString( - com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent); - ComponentName componentName = ComponentName.unflattenFromString(nameString); - if (startConfirmationActivity(componentName, key, fingerprints) - || startConfirmationService(componentName, key, fingerprints)) { + int currentUserId = ActivityManager.getCurrentUser(); + UserHandle userHandle = + UserManager.get(mContext).getUserInfo(currentUserId).getUserHandle(); + String componentString; + if (currentUserId == UserHandle.USER_OWNER) { + componentString = Resources.getSystem().getString( + com.android.internal.R.string.config_customAdbPublicKeyConfirmationComponent); + } else { + // If the current foreground user is not the primary user we send a different + // notification specific to secondary users. + componentString = Resources.getSystem().getString( + R.string.config_customAdbPublicKeyConfirmationSecondaryUserComponent); + } + ComponentName componentName = ComponentName.unflattenFromString(componentString); + if (startConfirmationActivity(componentName, userHandle, key, fingerprints) + || startConfirmationService(componentName, userHandle, key, fingerprints)) { return; } - Slog.e(TAG, "unable to start customAdbPublicKeyConfirmationComponent " - + nameString + " as an Activity or a Service"); + Slog.e(TAG, "unable to start customAdbPublicKeyConfirmation[SecondaryUser]Component " + + componentString + " as an Activity or a Service"); } /** * @returns true if the componentName led to an Activity that was started. */ - private boolean startConfirmationActivity(ComponentName componentName, String key, - String fingerprints) { + private boolean startConfirmationActivity(ComponentName componentName, UserHandle userHandle, + String key, String fingerprints) { PackageManager packageManager = mContext.getPackageManager(); Intent intent = createConfirmationIntent(componentName, key, fingerprints); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) { try { - mContext.startActivityAsUser(intent, UserHandle.OWNER); + mContext.startActivityAsUser(intent, userHandle); return true; } catch (ActivityNotFoundException e) { Slog.e(TAG, "unable to start adb whitelist activity: " + componentName, e); @@ -352,11 +365,11 @@ public class UsbDebuggingManager { /** * @returns true if the componentName led to a Service that was started. */ - private boolean startConfirmationService(ComponentName componentName, String key, - String fingerprints) { + private boolean startConfirmationService(ComponentName componentName, UserHandle userHandle, + String key, String fingerprints) { Intent intent = createConfirmationIntent(componentName, key, fingerprints); try { - if (mContext.startService(intent) != null) { + if (mContext.startServiceAsUser(intent, userHandle) != null) { return true; } } catch (SecurityException e) {