From 48dd9eee1ca8a26e2d26650d5371294ffa653da3 Mon Sep 17 00:00:00 2001 From: Thu-Huong Vu Date: Tue, 25 Feb 2025 00:51:33 +0000 Subject: [PATCH] Register SimpleBroadcastReceiver permission. Update SimpleBroadcastReceiver API to pass in broadcast permission and register Growth Broadcast Receiver with permission to prevent other apps from triggering Growth Nudge on their behalf. Flag: EXEMPT add separately Test: Manual Bug: 397739323 Change-Id: I3a9d5e131ced752af0a1b35d400eed6d170fc81e --- .../launcher3/taskbar/TaskbarManager.java | 5 ++-- .../taskbar/growth/GrowthConstants.java | 8 ++++++ .../util/SimpleBroadcastReceiver.java | 26 +++++++++++++++++++ .../util/SimpleBroadcastReceiverTest.kt | 23 ++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index bee0997d16..c6102154b1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -26,6 +26,7 @@ import static com.android.launcher3.Flags.enableUnfoldStateAnimation; import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION; import static com.android.launcher3.config.FeatureFlags.enableTaskbarNoRecreate; import static com.android.launcher3.taskbar.growth.GrowthConstants.BROADCAST_SHOW_NUDGE; +import static com.android.launcher3.taskbar.growth.GrowthConstants.GROWTH_NUDGE_PERMISSION; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_DESKTOP_MODE; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; @@ -442,7 +443,7 @@ public class TaskbarManager { mGrowthBroadcastReceiver = new SimpleBroadcastReceiver( mPrimaryWindowContext, UI_HELPER_EXECUTOR, this::showGrowthNudge); - mGrowthBroadcastReceiver.register(RECEIVER_EXPORTED, + mGrowthBroadcastReceiver.register(null, GROWTH_NUDGE_PERMISSION, RECEIVER_EXPORTED, BROADCAST_SHOW_NUDGE); } else { mGrowthBroadcastReceiver = null; @@ -504,7 +505,7 @@ public class TaskbarManager { debugPrimaryTaskbar("destroyTaskbarForDisplay"); // TODO: make this code displayId specific TaskbarActivityContext taskbar = getTaskbarForDisplay(getDefaultDisplayId()); - if (ACTION_SHOW_TASKBAR.equals(intent.getAction())) { + if (ACTION_SHOW_TASKBAR.equals(intent.getAction()) && taskbar != null) { taskbar.showTaskbarFromBroadcast(); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/growth/GrowthConstants.java b/quickstep/src/com/android/launcher3/taskbar/growth/GrowthConstants.java index 78ef152601..7d760fc9bb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/growth/GrowthConstants.java +++ b/quickstep/src/com/android/launcher3/taskbar/growth/GrowthConstants.java @@ -24,5 +24,13 @@ public final class GrowthConstants { */ public static final String BROADCAST_SHOW_NUDGE = "com.android.launcher3.growth.BROADCAST_SHOW_NUDGE"; + + /** + * For filtering package of broadcast intent received. + */ + public static final String GROWTH_NUDGE_PERMISSION = + "com.android.growth.permission.GROWTH_NUDGE_PERMISSION" + + " android:protectionLevel=\"signature|preinstalled\""; + private GrowthConstants() {} } diff --git a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java index 7a40abe62b..53e0bce182 100644 --- a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java +++ b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java @@ -123,6 +123,32 @@ public class SimpleBroadcastReceiver extends BroadcastReceiver { } } + /** + * Same as {@link #register(Runnable, int, String...)} above but with additional permission + * params utilizine the original {@link Context}. + */ + @AnyThread + public void register(@Nullable Runnable completionCallback, + String broadcastPermission, int flags, String... actions) { + if (Looper.myLooper() == mHandler.getLooper()) { + registerInternal(mContext, completionCallback, broadcastPermission, flags, actions); + } else { + mHandler.post(() -> registerInternal(mContext, completionCallback, broadcastPermission, + flags, actions)); + } + } + + /** Register broadcast receiver with permission and run completion callback if passed. */ + @AnyThread + private void registerInternal( + @NonNull Context context, @Nullable Runnable completionCallback, + String broadcastPermission, int flags, String... actions) { + context.registerReceiver(this, getFilter(actions), broadcastPermission, null, flags); + if (completionCallback != null) { + completionCallback.run(); + } + } + /** Same as {@link #register(Runnable, String...)} above but with pkg name. */ @AnyThread public void registerPkgActions(@Nullable String pkg, String... actions) { diff --git a/tests/multivalentTests/src/com/android/launcher3/util/SimpleBroadcastReceiverTest.kt b/tests/multivalentTests/src/com/android/launcher3/util/SimpleBroadcastReceiverTest.kt index 17933f202b..97651d3dab 100644 --- a/tests/multivalentTests/src/com/android/launcher3/util/SimpleBroadcastReceiverTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/util/SimpleBroadcastReceiverTest.kt @@ -126,6 +126,29 @@ class SimpleBroadcastReceiverTest { assertThat(intentFilter.getAction(1)).isEqualTo("test_action_2") } + @Test + fun sync_register_withCompletionRunnable_and_permission_and_flag() { + underTest = + SimpleBroadcastReceiver(context, Handler(Looper.getMainLooper()), intentConsumer) + + underTest.register(completionRunnable, "permission", 1, "test_action_1", "test_action_2") + getInstrumentation().waitForIdleSync() + + verify(context) + .registerReceiver( + same(underTest), + intentFilterCaptor.capture(), + eq("permission"), + eq(null), + eq(1), + ) + verify(completionRunnable).run() + val intentFilter = intentFilterCaptor.value + assertThat(intentFilter.countActions()).isEqualTo(2) + assertThat(intentFilter.getAction(0)).isEqualTo("test_action_1") + assertThat(intentFilter.getAction(1)).isEqualTo("test_action_2") + } + @Test fun async_unregister() { underTest.unregisterReceiverSafely()