summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Duong <joshuaduong@google.com>2020-04-17 16:17:42 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-04-17 16:17:42 +0000
commitc5724f3543b630f5a1f9c2d72b651997b830564b (patch)
treec0540aa188dee7beb33fe40942f3d262ecb13f0a
parent25402d17091c9126ab205c3e0bef8028bfe8c693 (diff)
parent9a419cda53f415465431ac9e48e4950191c19c6c (diff)
Merge "Fix PendingIntent hijacking for adb notifications." into rvc-dev am: 9a419cda53
Change-Id: I8f96b2aa8ca127380891f9a0a790224f092e9118
-rw-r--r--core/java/android/debug/AdbNotifications.java90
-rw-r--r--core/tests/coretests/AndroidManifest.xml3
-rw-r--r--core/tests/coretests/src/android/debug/AdbNotificationsTest.java79
-rw-r--r--services/core/java/com/android/server/adb/AdbDebuggingManager.java34
-rw-r--r--services/usb/java/com/android/server/usb/UsbDeviceManager.java36
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;