summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/StatusBarManager.java18
-rw-r--r--core/java/android/service/quicksettings/TileService.java34
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl5
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java61
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarManagerService.java48
-rw-r--r--services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java108
9 files changed, 261 insertions, 69 deletions
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index c6e36a36701b..89854bbab3e8 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -844,6 +844,24 @@ public class StatusBarManager {
}
/**
+ * Sets an active {@link android.service.quicksettings.TileService} to listening state
+ *
+ * The {@code componentName}'s package must match the calling package.
+ *
+ * @param componentName the tile to set into listening state
+ * @see android.service.quicksettings.TileService#requestListeningState
+ * @hide
+ */
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ Objects.requireNonNull(componentName);
+ try {
+ getService().requestTileServiceListeningState(componentName, mContext.getUserId());
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request to the user to add a {@link android.service.quicksettings.TileService}
* to the set of current QS tiles.
* <p>
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index b507328d21a1..0829d2813c83 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -15,18 +15,19 @@
*/
package android.service.quicksettings;
-import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.Dialog;
import android.app.Service;
+import android.app.StatusBarManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Icon;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -147,13 +148,6 @@ public class TileService extends Service {
"android.service.quicksettings.TOGGLEABLE_TILE";
/**
- * Used to notify SysUI that Listening has be requested.
- * @hide
- */
- public static final String ACTION_REQUEST_LISTENING =
- "android.service.quicksettings.action.REQUEST_LISTENING";
-
- /**
* @hide
*/
public static final String EXTRA_SERVICE = "service";
@@ -482,14 +476,24 @@ public class TileService extends Service {
*
* This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
* as true on their TileService Manifest declaration, and will do nothing otherwise.
+ *
+ * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or later, this call may throw
+ * the following exceptions if the request is not valid:
+ * <ul>
+ * <li> {@link NullPointerException} if {@code component} is {@code null}.</li>
+ * <li> {@link SecurityException} if the package of {@code component} does not match
+ * the calling package or if the calling user cannot act on behalf of the user from the
+ * {@code context}.</li>
+ * <li> {@link IllegalArgumentException} if the user of the {@code context} is not the
+ * current user.</li>
+ * </ul>
*/
public static final void requestListeningState(Context context, ComponentName component) {
- final ComponentName sysuiComponent = ComponentName.unflattenFromString(
- context.getResources().getString(
- com.android.internal.R.string.config_systemUIServiceComponent));
- Intent intent = new Intent(ACTION_REQUEST_LISTENING);
- intent.putExtra(Intent.EXTRA_COMPONENT_NAME, component);
- intent.setPackage(sysuiComponent.getPackageName());
- context.sendBroadcast(intent, Manifest.permission.BIND_QUICK_SETTINGS_TILE);
+ StatusBarManager sbm = context.getSystemService(StatusBarManager.class);
+ if (sbm == null) {
+ Log.e(TAG, "No StatusBarManager service found");
+ return;
+ }
+ sbm.requestTileServiceListeningState(component);
}
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index d629d66d1c31..089179dbba27 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -297,6 +297,11 @@ oneway interface IStatusBar
*/
void runGcForTest();
+ /**
+ * Send a request to SystemUI to put a given active tile in listening state
+ */
+ void requestTileServiceListeningState(in ComponentName componentName);
+
void requestAddTile(in ComponentName componentName, in CharSequence appName, in CharSequence label, in Icon icon, in IAddTileResultCallback callback);
void cancelRequestAddTile(in String packageName);
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 9163b6d6215e..3bfd21440f9b 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -171,6 +171,11 @@ interface IStatusBarService
*/
void suppressAmbientDisplay(boolean suppress);
+ /**
+ * Send a request to SystemUI to put a given active tile in listening state
+ */
+ void requestTileServiceListeningState(in ComponentName componentName, int userId);
+
void requestAddTile(in ComponentName componentName, in CharSequence label, in Icon icon, int userId, in IAddTileResultCallback callback);
void cancelRequestAddTile(in String packageName);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index 5bcf9f8a0534..4cacbbacec2f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -15,11 +15,8 @@
*/
package com.android.systemui.qs.external;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Icon;
@@ -30,10 +27,10 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.service.quicksettings.IQSService;
import android.service.quicksettings.Tile;
-import android.service.quicksettings.TileService;
import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.statusbar.StatusBarIcon;
@@ -41,6 +38,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -69,6 +67,7 @@ public class TileServices extends IQSService.Stub {
private final QSTileHost mHost;
private final KeyguardStateController mKeyguardStateController;
private final BroadcastDispatcher mBroadcastDispatcher;
+ private final CommandQueue mCommandQueue;
private final UserTracker mUserTracker;
private int mMaxBound = DEFAULT_MAX_BOUND;
@@ -79,7 +78,8 @@ public class TileServices extends IQSService.Stub {
@Main Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher,
UserTracker userTracker,
- KeyguardStateController keyguardStateController) {
+ KeyguardStateController keyguardStateController,
+ CommandQueue commandQueue) {
mHost = host;
mKeyguardStateController = keyguardStateController;
mContext = mHost.getContext();
@@ -87,12 +87,8 @@ public class TileServices extends IQSService.Stub {
mHandlerProvider = handlerProvider;
mMainHandler = mHandlerProvider.get();
mUserTracker = userTracker;
- mBroadcastDispatcher.registerReceiver(
- mRequestListeningReceiver,
- new IntentFilter(TileService.ACTION_REQUEST_LISTENING),
- null, // Use the default Executor
- UserHandle.ALL
- );
+ mCommandQueue = commandQueue;
+ mCommandQueue.addCallback(mRequestListeningCallback);
}
public Context getContext() {
@@ -354,21 +350,14 @@ public class TileServices extends IQSService.Stub {
public void destroy() {
synchronized (mServices) {
mServices.values().forEach(service -> service.handleDestroy());
- mBroadcastDispatcher.unregisterReceiver(mRequestListeningReceiver);
}
+ mCommandQueue.removeCallback(mRequestListeningCallback);
}
- private final BroadcastReceiver mRequestListeningReceiver = new BroadcastReceiver() {
+ private final CommandQueue.Callbacks mRequestListeningCallback = new CommandQueue.Callbacks() {
@Override
- public void onReceive(Context context, Intent intent) {
- if (TileService.ACTION_REQUEST_LISTENING.equals(intent.getAction())) {
- try {
- ComponentName c = intent.getParcelableExtra(Intent.EXTRA_COMPONENT_NAME);
- requestListening(c);
- } catch (ClassCastException ex) {
- Log.e(TAG, "Bad component name", ex);
- }
- }
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ mMainHandler.post(() -> requestListening(componentName));
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 5932a64c1c71..d9a98b165795 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -163,6 +163,7 @@ public class CommandQueue extends IStatusBar.Stub implements
private static final int MSG_MEDIA_TRANSFER_RECEIVER_STATE = 65 << MSG_SHIFT;
private static final int MSG_REGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 66 << MSG_SHIFT;
private static final int MSG_UNREGISTER_NEARBY_MEDIA_DEVICE_PROVIDER = 67 << MSG_SHIFT;
+ private static final int MSG_TILE_SERVICE_REQUEST_LISTENING_STATE = 68 << MSG_SHIFT;
public static final int FLAG_EXCLUDE_NONE = 0;
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -433,6 +434,11 @@ public class CommandQueue extends IStatusBar.Stub implements
default void setNavigationBarLumaSamplingEnabled(int displayId, boolean enable) {}
/**
+ * @see IStatusBar#requestTileServiceListeningState
+ */
+ default void requestTileServiceListeningState(@NonNull ComponentName componentName) {}
+
+ /**
* @see IStatusBar#requestAddTile
*/
default void requestAddTile(
@@ -1190,6 +1196,12 @@ public class CommandQueue extends IStatusBar.Stub implements
}
@Override
+ public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
+ mHandler.obtainMessage(MSG_TILE_SERVICE_REQUEST_LISTENING_STATE, componentName)
+ .sendToTarget();
+ }
+
+ @Override
public void requestAddTile(
@NonNull ComponentName componentName,
@NonNull CharSequence appName,
@@ -1686,6 +1698,12 @@ public class CommandQueue extends IStatusBar.Stub implements
mCallbacks.get(i).unregisterNearbyMediaDevicesProvider(provider);
}
break;
+ case MSG_TILE_SERVICE_REQUEST_LISTENING_STATE:
+ ComponentName component = (ComponentName) msg.obj;
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ mCallbacks.get(i).requestTileServiceListeningState(component);
+ }
+ break;
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index e75780166f05..6b7e5b9335f2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -20,20 +20,18 @@ import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.IntentFilter;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.quicksettings.TileService;
+import android.service.quicksettings.IQSTileService;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -48,6 +46,7 @@ import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -75,12 +74,17 @@ import javax.inject.Provider;
public class TileServicesTest extends SysuiTestCase {
private static int NUM_FAKES = TileServices.DEFAULT_MAX_BOUND * 2;
+ private static final ComponentName TEST_COMPONENT =
+ ComponentName.unflattenFromString("pkg/.cls");
+
private TileServices mTileService;
private TestableLooper mTestableLooper;
private ArrayList<TileServiceManager> mManagers;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
+ private CommandQueue mCommandQueue;
+ @Mock
private StatusBarIconController mStatusBarIconController;
@Mock
private QSFactoryImpl mQSFactory;
@@ -146,7 +150,7 @@ public class TileServicesTest extends SysuiTestCase {
mTileServiceRequestControllerBuilder,
mTileLifecycleManagerFactory);
mTileService = new TestTileServices(host, provider, mBroadcastDispatcher,
- mUserTracker, mKeyguardStateController);
+ mUserTracker, mKeyguardStateController, mCommandQueue);
}
@After
@@ -157,24 +161,6 @@ public class TileServicesTest extends SysuiTestCase {
}
@Test
- public void testActiveTileListenerRegisteredOnAllUsers() {
- ArgumentCaptor<IntentFilter> captor = ArgumentCaptor.forClass(IntentFilter.class);
- verify(mBroadcastDispatcher).registerReceiver(any(), captor.capture(), any(), eq(
- UserHandle.ALL));
- assertTrue(captor.getValue().hasAction(TileService.ACTION_REQUEST_LISTENING));
- }
-
- @Test
- public void testBadComponentName_doesntCrash() {
- ArgumentCaptor<BroadcastReceiver> captor = ArgumentCaptor.forClass(BroadcastReceiver.class);
- verify(mBroadcastDispatcher).registerReceiver(captor.capture(), any(), any(), eq(
- UserHandle.ALL));
- Intent intent = new Intent(TileService.ACTION_REQUEST_LISTENING)
- .putExtra(Intent.EXTRA_COMPONENT_NAME, "abc");
- captor.getValue().onReceive(mContext, intent);
- }
-
- @Test
public void testRecalculateBindAllowance() {
// Add some fake tiles.
for (int i = 0; i < NUM_FAKES; i++) {
@@ -230,11 +216,36 @@ public class TileServicesTest extends SysuiTestCase {
}
}
+ @Test
+ public void testRegisterCommand() {
+ verify(mCommandQueue).addCallback(any());
+ }
+
+ @Test
+ public void testRequestListeningStatusCommand() throws RemoteException {
+ ArgumentCaptor<CommandQueue.Callbacks> captor =
+ ArgumentCaptor.forClass(CommandQueue.Callbacks.class);
+ verify(mCommandQueue).addCallback(captor.capture());
+
+ CustomTile mockTile = mock(CustomTile.class);
+ when(mockTile.getComponent()).thenReturn(TEST_COMPONENT);
+
+ TileServiceManager manager = mTileService.getTileWrapper(mockTile);
+ when(manager.isActiveTile()).thenReturn(true);
+ when(manager.getTileService()).thenReturn(mock(IQSTileService.class));
+
+ captor.getValue().requestTileServiceListeningState(TEST_COMPONENT);
+ mTestableLooper.processAllMessages();
+ verify(manager).setBindRequested(true);
+ verify(manager.getTileService()).onStartListening();
+ }
+
private class TestTileServices extends TileServices {
TestTileServices(QSTileHost host, Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
- KeyguardStateController keyguardStateController) {
- super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController);
+ KeyguardStateController keyguardStateController, CommandQueue commandQueue) {
+ super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController,
+ commandQueue);
}
@Override
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 59b9daf709d8..60ede3bcda4d 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -36,6 +36,7 @@ import android.app.Notification;
import android.app.StatusBarManager;
import android.app.compat.CompatChanges;
import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledAfter;
import android.compat.annotation.EnabledSince;
import android.content.ComponentName;
import android.content.Context;
@@ -135,6 +136,17 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
private static final long LOCK_DOWN_COLLAPSE_STATUS_BAR = 173031413L;
+ /**
+ * In apps targeting {@link android.os.Build.VERSION_CODES#TIRAMISU} or higher, calling
+ * {@link android.service.quicksettings.TileService#requestListeningState} will check that the
+ * calling package (uid) and the package of the target {@link android.content.ComponentName}
+ * match. It'll also make sure that the context used can take actions on behalf of the current
+ * user.
+ */
+ @ChangeId
+ @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
+ static final long REQUEST_LISTENING_MUST_MATCH_PACKAGE = 172251878L;
+
private final Context mContext;
private final Handler mHandler = new Handler();
@@ -1776,6 +1788,42 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
}
@Override
+ public void requestTileServiceListeningState(
+ @NonNull ComponentName componentName,
+ int userId
+ ) {
+ int callingUid = Binder.getCallingUid();
+ String packageName = componentName.getPackageName();
+
+ boolean mustPerformChecks = CompatChanges.isChangeEnabled(
+ REQUEST_LISTENING_MUST_MATCH_PACKAGE, callingUid);
+
+ if (mustPerformChecks) {
+ // Check calling user can act on behalf of current user
+ userId = mActivityManagerInternal.handleIncomingUser(Binder.getCallingPid(), callingUid,
+ userId, false, ActivityManagerInternal.ALLOW_NON_FULL,
+ "requestTileServiceListeningState", packageName);
+
+ // Check calling uid matches package
+ checkCallingUidPackage(packageName, callingUid, userId);
+
+ int currentUser = mActivityManagerInternal.getCurrentUserId();
+
+ // Check current user
+ if (userId != currentUser) {
+ throw new IllegalArgumentException("User " + userId + " is not the current user.");
+ }
+ }
+ if (mBar != null) {
+ try {
+ mBar.requestTileServiceListeningState(componentName);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "requestTileServiceListeningState", e);
+ }
+ }
+ }
+
+ @Override
public void requestAddTile(
@NonNull ComponentName componentName,
@NonNull CharSequence label,
diff --git a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
index 1442f1c82d42..d76a1de1b1b0 100644
--- a/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/statusbar/StatusBarManagerServiceTest.java
@@ -23,9 +23,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.eq;
@@ -37,6 +39,7 @@ import static org.mockito.Mockito.when;
import android.Manifest;
import android.app.ActivityManagerInternal;
import android.app.StatusBarManager;
+import android.compat.testing.PlatformCompatChangeRule;
import android.content.ComponentName;
import android.content.Intent;
import android.content.om.IOverlayManager;
@@ -62,10 +65,13 @@ import com.android.server.LocalServices;
import com.android.server.policy.GlobalActionsProvider;
import com.android.server.wm.ActivityTaskManagerInternal;
+import libcore.junit.util.compat.CoreCompatChangeRule;
+
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.ArgumentCaptor;
@@ -73,6 +79,7 @@ import org.mockito.ArgumentMatcher;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
@RunWith(JUnit4.class)
public class StatusBarManagerServiceTest {
@@ -88,6 +95,9 @@ public class StatusBarManagerServiceTest {
public final TestableContext mContext =
new NoBroadcastContextWrapper(InstrumentationRegistry.getContext());
+ @Rule
+ public TestRule mCompatChangeRule = new PlatformCompatChangeRule();
+
@Mock
private ActivityTaskManagerInternal mActivityTaskManagerInternal;
@Mock
@@ -127,6 +137,7 @@ public class StatusBarManagerServiceTest {
when(mMockStatusBar.asBinder()).thenReturn(mMockStatusBar);
when(mApplicationInfo.loadLabel(any())).thenReturn(APP_NAME);
+ mockHandleIncomingUser();
mStatusBarManagerService = new StatusBarManagerService(mContext);
LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
@@ -142,6 +153,80 @@ public class StatusBarManagerServiceTest {
}
@Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_OKCall() throws RemoteException {
+ int user = 0;
+ mockEverything(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_differentPackage_fail() throws RemoteException {
+ when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+ .thenReturn(Binder.getCallingUid() + 1);
+ try {
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+ fail("Should cause security exception");
+ } catch (SecurityException e) { }
+ verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.EnableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeEnabled_notCurrentUser_fail() throws RemoteException {
+ mockUidCheck();
+ int user = 0;
+ mockCurrentUserCheck(user);
+ try {
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+ fail("Should cause illegal argument exception");
+ } catch (IllegalArgumentException e) { }
+
+ // Do not call into SystemUI
+ verify(mMockStatusBar, never()).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_pass() throws RemoteException {
+ int user = 0;
+ mockEverything(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_differentPackage_pass() throws RemoteException {
+ when(mPackageManagerInternal.getPackageUid(TEST_PACKAGE, 0L, mContext.getUserId()))
+ .thenReturn(Binder.getCallingUid() + 1);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, 0);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
+ @CoreCompatChangeRule.DisableCompatChanges(
+ {StatusBarManagerService.REQUEST_LISTENING_MUST_MATCH_PACKAGE})
+ public void testRequestActive_changeDisabled_notCurrentUser_pass() throws RemoteException {
+ mockUidCheck();
+ int user = 0;
+ mockCurrentUserCheck(user);
+ mStatusBarManagerService.requestTileServiceListeningState(TEST_COMPONENT, user + 1);
+
+ verify(mMockStatusBar).requestTileServiceListeningState(TEST_COMPONENT);
+ }
+
+ @Test
public void testHandleIncomingUserCalled() {
int fakeUser = 17;
try {
@@ -252,7 +337,7 @@ public class StatusBarManagerServiceTest {
mockCurrentUserCheck(user);
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(null);
Callback callback = new Callback();
@@ -272,7 +357,7 @@ public class StatusBarManagerServiceTest {
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -294,7 +379,7 @@ public class StatusBarManagerServiceTest {
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -318,7 +403,7 @@ public class StatusBarManagerServiceTest {
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -342,7 +427,7 @@ public class StatusBarManagerServiceTest {
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(TEST_COMPONENT));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(TEST_COMPONENT,
Binder.getCallingUid(), user)).thenReturn(
@@ -641,7 +726,7 @@ public class StatusBarManagerServiceTest {
}
private void mockUidCheck(String packageName) {
- when(mPackageManagerInternal.getPackageUid(eq(packageName), anyInt(), anyInt()))
+ when(mPackageManagerInternal.getPackageUid(eq(packageName), anyLong(), anyInt()))
.thenReturn(Binder.getCallingUid());
}
@@ -667,7 +752,7 @@ public class StatusBarManagerServiceTest {
IntentMatcher im = new IntentMatcher(
new Intent(TileService.ACTION_QS_TILE).setComponent(componentName));
- when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0),
+ when(mPackageManagerInternal.resolveService(argThat(im), nullable(String.class), eq(0L),
eq(user), anyInt())).thenReturn(r);
when(mPackageManagerInternal.getComponentEnabledSetting(componentName,
Binder.getCallingUid(), user)).thenReturn(
@@ -679,6 +764,15 @@ public class StatusBarManagerServiceTest {
PROCESS_STATE_TOP);
}
+ private void mockHandleIncomingUser() {
+ when(mActivityManagerInternal.handleIncomingUser(anyInt(), anyInt(), anyInt(), anyBoolean(),
+ anyInt(), anyString(), anyString())).thenAnswer(
+ (Answer<Integer>) invocation -> {
+ return invocation.getArgument(2); // same user
+ }
+ );
+ }
+
private void mockEverything(int user) {
mockUidCheck();
mockCurrentUserCheck(user);