diff options
5 files changed, 179 insertions, 63 deletions
diff --git a/core/java/android/debug/AdbNotifications.java b/core/java/android/debug/AdbNotifications.java new file mode 100644 index 000000000000..fed5f5f9a0bf --- /dev/null +++ b/core/java/android/debug/AdbNotifications.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 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 android.debug; + +import android.annotation.NonNull; +import android.app.Notification; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.UserHandle; +import android.provider.Settings; + +import com.android.internal.notification.SystemNotificationChannels; + +/** + * Utility class for building adb notifications. + * @hide + */ +public final class AdbNotifications { + /** + * Notification channel for tv types. + */ + private static final String ADB_NOTIFICATION_CHANNEL_ID_TV = "usbdevicemanager.adb.tv"; + + /** + * Builds a notification to show connected state for adb over a transport type. + * @param context the context + * @param transportType the adb transport type. + * @return a newly created Notification for the transport type. + */ + public static Notification createNotification(@NonNull Context context, + byte transportType) { + Resources resources = context.getResources(); + int titleId; + int messageId; + + if (transportType == AdbTransportType.USB) { + titleId = com.android.internal.R.string.adb_active_notification_title; + messageId = com.android.internal.R.string.adb_active_notification_message; + } else if (transportType == AdbTransportType.WIFI) { + titleId = com.android.internal.R.string.adbwifi_active_notification_title; + messageId = com.android.internal.R.string.adbwifi_active_notification_message; + } else { + throw new IllegalArgumentException( + "createNotification called with unknown transport type=" + transportType); + } + + CharSequence title = resources.getText(titleId); + CharSequence message = resources.getText(messageId); + + Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + intent.setPackage(context.getPackageManager().resolveActivity(intent, + PackageManager.MATCH_SYSTEM_ONLY).activityInfo.packageName); + PendingIntent pIntent = PendingIntent.getActivityAsUser(context, 0, intent, + PendingIntent.FLAG_IMMUTABLE, null, UserHandle.CURRENT); + + return new Notification.Builder(context, SystemNotificationChannels.DEVELOPER_IMPORTANT) + .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) + .setWhen(0) + .setOngoing(true) + .setTicker(title) + .setDefaults(0) // please be quiet + .setColor(context.getColor( + com.android.internal.R.color.system_notification_accent_color)) + .setContentTitle(title) + .setContentText(message) + .setContentIntent(pIntent) + .setVisibility(Notification.VISIBILITY_PUBLIC) + .extend(new Notification.TvExtender() + .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV)) + .build(); + } +} diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 45490ae2bf33..cc9c91441e84 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -142,6 +142,9 @@ <!-- WindowMetricsTest permissions --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> + <!-- Allow use of PendingIntent.getIntent() --> + <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" /> + <application android:theme="@style/Theme" android:supportsRtl="true"> <uses-library android:name="android.test.runner" /> <uses-library android:name="org.apache.http.legacy" android:required="false" /> diff --git a/core/tests/coretests/src/android/debug/AdbNotificationsTest.java b/core/tests/coretests/src/android/debug/AdbNotificationsTest.java new file mode 100644 index 000000000000..6c187ea6e17a --- /dev/null +++ b/core/tests/coretests/src/android/debug/AdbNotificationsTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2020 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 android.debug; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import android.app.Notification; +import android.content.Context; +import android.platform.test.annotations.Presubmit; +import android.text.TextUtils; + +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.SmallTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +@Presubmit +public final class AdbNotificationsTest { + private Context mContext; + + @Before + public void setUp() throws Exception { + mContext = InstrumentationRegistry.getContext(); + } + + @Test + public void testCreateNotification_UsbTransportType() throws Exception { + CharSequence title = mContext.getResources().getText( + com.android.internal.R.string.adb_active_notification_title); + CharSequence message = mContext.getResources().getText( + com.android.internal.R.string.adb_active_notification_message); + + Notification notification = AdbNotifications.createNotification(mContext, + AdbTransportType.USB); + + // Verify that the adb notification for usb connections has the correct text. + assertEquals(title, notification.extras.getCharSequence(Notification.EXTRA_TITLE, "")); + assertEquals(message, notification.extras.getCharSequence(Notification.EXTRA_TEXT, "")); + // Verify the PendingIntent has an explicit intent (b/153356209). + assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage())); + } + + @Test + public void testCreateNotification_WifiTransportType() throws Exception { + CharSequence title = mContext.getResources().getText( + com.android.internal.R.string.adbwifi_active_notification_title); + CharSequence message = mContext.getResources().getText( + com.android.internal.R.string.adbwifi_active_notification_message); + + Notification notification = AdbNotifications.createNotification(mContext, + AdbTransportType.WIFI); + + // Verify that the adb notification for usb connections has the correct text. + assertEquals(title, notification.extras.getCharSequence(Notification.EXTRA_TITLE, "")); + assertEquals(message, notification.extras.getCharSequence(Notification.EXTRA_TEXT, "")); + // Verify the PendingIntent has an explicit intent (b/153356209). + assertFalse(TextUtils.isEmpty(notification.contentIntent.getIntent().getPackage())); + } +} diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index e49357bee896..86f4966a5356 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -23,7 +23,6 @@ import android.app.ActivityManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -36,6 +35,7 @@ import android.content.pm.UserInfo; import android.content.res.Resources; import android.database.ContentObserver; import android.debug.AdbManager; +import android.debug.AdbNotifications; import android.debug.AdbProtoEnums; import android.debug.AdbTransportType; import android.debug.PairDevice; @@ -69,7 +69,6 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; -import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.XmlUtils; @@ -760,40 +759,13 @@ public class AdbDebuggingManager { // Show when at least one device is connected. public void showAdbConnectedNotification(boolean show) { final int id = SystemMessage.NOTE_ADB_WIFI_ACTIVE; - final int titleRes = com.android.internal.R.string.adbwifi_active_notification_title; if (show == mAdbNotificationShown) { return; } setupNotifications(); if (!mAdbNotificationShown) { - Resources r = mContext.getResources(); - CharSequence title = r.getText(titleRes); - CharSequence message = r.getText( - com.android.internal.R.string.adbwifi_active_notification_message); - - Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_CLEAR_TASK); - PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, - intent, 0, null, UserHandle.CURRENT); - - Notification notification = - new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER) - .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) - .setWhen(0) - .setOngoing(true) - .setTicker(title) - .setDefaults(0) // please be quiet - .setColor(mContext.getColor( - com.android.internal.R.color - .system_notification_accent_color)) - .setContentTitle(title) - .setContentText(message) - .setContentIntent(pi) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .extend(new Notification.TvExtender() - .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV)) - .build(); + Notification notification = AdbNotifications.createNotification(mContext, + AdbTransportType.WIFI); mAdbNotificationShown = true; mNotificationManager.notifyAsUser(null, id, notification, UserHandle.ALL); diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 747c8d9d0890..7595e3f249ce 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -41,6 +41,7 @@ import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Resources; import android.debug.AdbManagerInternal; +import android.debug.AdbNotifications; import android.debug.AdbTransportType; import android.debug.IAdbTransport; import android.hardware.usb.ParcelableUsbPort; @@ -1180,7 +1181,6 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser protected void updateAdbNotification(boolean force) { if (mNotificationManager == null) return; final int id = SystemMessage.NOTE_ADB_ACTIVE; - final int titleRes = com.android.internal.R.string.adb_active_notification_title; if (isAdbEnabled() && mConnected) { if ("0".equals(getSystemProperty("persist.adb.notify", ""))) return; @@ -1191,38 +1191,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser } if (!mAdbNotificationShown) { - Resources r = mContext.getResources(); - CharSequence title = r.getText(titleRes); - CharSequence message = r.getText( - com.android.internal.R.string.adb_active_notification_message); - - Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_CLEAR_TASK); - PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0, - intent, 0, null, UserHandle.CURRENT); - - Notification notification = - new Notification.Builder(mContext, - SystemNotificationChannels.DEVELOPER_IMPORTANT) - .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) - .setWhen(0) - .setOngoing(true) - .setTicker(title) - .setDefaults(0) // please be quiet - .setColor(mContext.getColor( - com.android.internal.R.color - .system_notification_accent_color)) - .setContentTitle(title) - .setContentText(message) - .setContentIntent(pi) - .setVisibility(Notification.VISIBILITY_PUBLIC) - .extend(new Notification.TvExtender() - .setChannelId(ADB_NOTIFICATION_CHANNEL_ID_TV)) - .build(); + Notification notification = AdbNotifications.createNotification(mContext, + AdbTransportType.USB); mAdbNotificationShown = true; - mNotificationManager.notifyAsUser(null, id, notification, - UserHandle.ALL); + mNotificationManager.notifyAsUser(null, id, notification, UserHandle.ALL); } } else if (mAdbNotificationShown) { mAdbNotificationShown = false; |