Cleanup communal mode shared app logic.
We will no longer be shipping shared apps in Android T Test: atest CommunalManagerServiceTest Test: locally on device Bug: 211633044 Change-Id: I96ff51f1e10801722dd74de110f5c2caacf0d8d3
This commit is contained in:
@@ -23,9 +23,6 @@ import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.annotation.TestApi;
|
||||
import android.compat.annotation.ChangeId;
|
||||
import android.compat.annotation.Disabled;
|
||||
import android.compat.annotation.Overridable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.RemoteException;
|
||||
@@ -46,31 +43,10 @@ public final class CommunalManager {
|
||||
private final ICommunalManager mService;
|
||||
private final ArrayMap<CommunalModeListener, ICommunalModeListener> mCommunalModeListeners;
|
||||
|
||||
/**
|
||||
* This change id is used to annotate packages which can run in communal mode by default,
|
||||
* without requiring user opt-in.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Overridable
|
||||
@Disabled
|
||||
public static final long ALLOW_COMMUNAL_MODE_BY_DEFAULT = 203673428L;
|
||||
|
||||
/**
|
||||
* This change id is used to annotate packages which are allowed to run in communal mode.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Overridable
|
||||
@Disabled
|
||||
public static final long ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT = 200324021L;
|
||||
|
||||
/** @hide */
|
||||
public CommunalManager(ICommunalManager service) {
|
||||
mService = service;
|
||||
mCommunalModeListeners = new ArrayMap<CommunalModeListener, ICommunalModeListener>();
|
||||
mCommunalModeListeners = new ArrayMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10466,13 +10466,6 @@ public final class Settings {
|
||||
*/
|
||||
public static final String COMMUNAL_MODE_ENABLED = "communal_mode_enabled";
|
||||
|
||||
/**
|
||||
* An array of all the packages which have been enabled for hub mode by the user.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final String COMMUNAL_MODE_PACKAGES = "communal_mode_packages";
|
||||
|
||||
/**
|
||||
* An array of SSIDs of Wi-Fi networks that, when connected, are considered safe to enable
|
||||
* the communal mode.
|
||||
|
||||
@@ -16,117 +16,34 @@
|
||||
|
||||
package com.android.server.communal;
|
||||
|
||||
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
|
||||
import static android.app.communal.CommunalManager.ALLOW_COMMUNAL_MODE_BY_DEFAULT;
|
||||
import static android.app.communal.CommunalManager.ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT;
|
||||
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
|
||||
|
||||
import static com.android.server.wm.ActivityInterceptorCallback.COMMUNAL_MODE_ORDERED_ID;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.communal.ICommunalManager;
|
||||
import android.app.communal.ICommunalModeListener;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.IIntentSender;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteCallbackList;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.app.LaunchAfterAuthenticationActivity;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.wm.ActivityInterceptorCallback;
|
||||
import com.android.server.wm.ActivityTaskManagerInternal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* System service for handling Communal Mode state.
|
||||
*/
|
||||
public final class CommunalManagerService extends SystemService {
|
||||
private static final String TAG = CommunalManagerService.class.getSimpleName();
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
private static final String DELIMITER = ",";
|
||||
private final Context mContext;
|
||||
private final ActivityTaskManagerInternal mAtmInternal;
|
||||
private final KeyguardManager mKeyguardManager;
|
||||
private final AtomicBoolean mCommunalViewIsShowing = new AtomicBoolean(false);
|
||||
private final BinderService mBinderService;
|
||||
private final PackageReceiver mPackageReceiver;
|
||||
private final PackageManager mPackageManager;
|
||||
private final DreamManagerInternal mDreamManagerInternal;
|
||||
private final RemoteCallbackList<ICommunalModeListener> mListeners =
|
||||
new RemoteCallbackList<>();
|
||||
|
||||
private final ActivityInterceptorCallback mActivityInterceptorCallback =
|
||||
new ActivityInterceptorCallback() {
|
||||
@Nullable
|
||||
@Override
|
||||
public ActivityInterceptResult intercept(ActivityInterceptorInfo info) {
|
||||
if (!shouldIntercept(info.aInfo)) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Activity allowed, not intercepting: "
|
||||
+ info.aInfo.getComponentName());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final IIntentSender target = mAtmInternal.getIntentSender(
|
||||
INTENT_SENDER_ACTIVITY,
|
||||
info.callingPackage,
|
||||
info.callingFeatureId,
|
||||
info.callingUid,
|
||||
info.userId,
|
||||
/* token= */null,
|
||||
/* resultWho= */ null,
|
||||
/* requestCode= */ 0,
|
||||
new Intent[]{info.intent},
|
||||
new String[]{info.resolvedType},
|
||||
PendingIntent.FLAG_IMMUTABLE,
|
||||
/* bOptions= */ null);
|
||||
|
||||
return new ActivityInterceptResult(
|
||||
LaunchAfterAuthenticationActivity.createLaunchAfterAuthenticationIntent(
|
||||
new IntentSender(target)),
|
||||
info.checkedOptions);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public CommunalManagerService(Context context) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
|
||||
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
|
||||
mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
|
||||
mBinderService = new BinderService();
|
||||
mPackageReceiver = new PackageReceiver(mContext);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -139,116 +56,6 @@ public final class CommunalManagerService extends SystemService {
|
||||
publishBinderService(Context.COMMUNAL_SERVICE, mBinderService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBootPhase(int phase) {
|
||||
if (phase != SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) return;
|
||||
mAtmInternal.registerActivityStartInterceptor(
|
||||
COMMUNAL_MODE_ORDERED_ID,
|
||||
mActivityInterceptorCallback);
|
||||
mPackageReceiver.register();
|
||||
removeUninstalledPackagesFromSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
mPackageReceiver.unregister();
|
||||
}
|
||||
|
||||
private Set<String> getUserEnabledApps() {
|
||||
final String encodedApps = Settings.Secure.getStringForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.COMMUNAL_MODE_PACKAGES,
|
||||
UserHandle.USER_SYSTEM);
|
||||
|
||||
return TextUtils.isEmpty(encodedApps)
|
||||
? Collections.emptySet()
|
||||
: new HashSet<>(Arrays.asList(encodedApps.split(DELIMITER)));
|
||||
}
|
||||
|
||||
private void removeUninstalledPackagesFromSettings() {
|
||||
for (String packageName : getUserEnabledApps()) {
|
||||
if (!isPackageInstalled(packageName, mPackageManager)) {
|
||||
removePackageFromSettings(packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removePackageFromSettings(String packageName) {
|
||||
Set<String> enabledPackages = getUserEnabledApps();
|
||||
if (enabledPackages.remove(packageName)) {
|
||||
Settings.Secure.putStringForUser(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.COMMUNAL_MODE_PACKAGES,
|
||||
String.join(DELIMITER, enabledPackages),
|
||||
UserHandle.USER_SYSTEM);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isPackageInstalled(String packageName, PackageManager packageManager) {
|
||||
if (packageManager == null) return false;
|
||||
try {
|
||||
return packageManager.getPackageInfo(packageName, 0) != null;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAppAllowed(ApplicationInfo appInfo) {
|
||||
if (isActiveDream(appInfo) || isChangeEnabled(ALLOW_COMMUNAL_MODE_BY_DEFAULT, appInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, appInfo)) {
|
||||
if (DEBUG) Slog.d(TAG, "App is not allowlisted: " + appInfo.packageName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getUserEnabledApps().contains(appInfo.packageName)) {
|
||||
if (DEBUG) Slog.d(TAG, "App does not have user consent: " + appInfo.packageName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isActiveDream(ApplicationInfo appInfo) {
|
||||
final ComponentName activeDream = mDreamManagerInternal.getActiveDreamComponent(
|
||||
/* doze= */ false);
|
||||
final ComponentName activeDoze = mDreamManagerInternal.getActiveDreamComponent(
|
||||
/* doze= */ true);
|
||||
return isFromPackage(activeDream, appInfo) || isFromPackage(activeDoze, appInfo);
|
||||
}
|
||||
|
||||
private static boolean isFromPackage(ComponentName componentName, ApplicationInfo appInfo) {
|
||||
if (componentName == null) return false;
|
||||
return TextUtils.equals(appInfo.packageName, componentName.getPackageName());
|
||||
}
|
||||
|
||||
private static boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
|
||||
return CompatChanges.isChangeEnabled(changeId, appInfo.packageName, UserHandle.SYSTEM);
|
||||
}
|
||||
|
||||
private boolean shouldIntercept(ActivityInfo activityInfo) {
|
||||
if (!mCommunalViewIsShowing.get() || !mKeyguardManager.isKeyguardLocked()) return false;
|
||||
ApplicationInfo appInfo = activityInfo.applicationInfo;
|
||||
// Dreams are allowed to show, and don't require the showWhenLocked attribute.
|
||||
if (isActiveDream(appInfo)) return false;
|
||||
|
||||
// If the activity doesn't have showWhenLocked enabled, disallow the activity.
|
||||
final boolean showWhenLocked =
|
||||
(activityInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0;
|
||||
if (!showWhenLocked) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Activity does not contain showWhenLocked attribute: "
|
||||
+ activityInfo.getComponentName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isAppAllowed(appInfo);
|
||||
}
|
||||
|
||||
private void dispatchCommunalMode(boolean isShowing) {
|
||||
synchronized (mListeners) {
|
||||
int i = mListeners.beginBroadcast();
|
||||
@@ -319,50 +126,4 @@ public final class CommunalManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link BroadcastReceiver} that listens on package removed events and updates any stored
|
||||
* package state in Settings.
|
||||
*/
|
||||
private final class PackageReceiver extends BroadcastReceiver {
|
||||
private final Context mContext;
|
||||
private final IntentFilter mIntentFilter;
|
||||
|
||||
private PackageReceiver(Context context) {
|
||||
mContext = context;
|
||||
mIntentFilter = new IntentFilter();
|
||||
mIntentFilter.addAction(ACTION_PACKAGE_REMOVED);
|
||||
mIntentFilter.addDataScheme("package");
|
||||
}
|
||||
|
||||
private void register() {
|
||||
mContext.registerReceiverAsUser(
|
||||
this,
|
||||
UserHandle.SYSTEM,
|
||||
mIntentFilter,
|
||||
/* broadcastPermission= */null,
|
||||
/* scheduler= */ null,
|
||||
Context.RECEIVER_EXPORTED_UNAUDITED);
|
||||
}
|
||||
|
||||
private void unregister() {
|
||||
mContext.unregisterReceiver(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(@NonNull final Context context, @NonNull final Intent intent) {
|
||||
final Uri data = intent.getData();
|
||||
if (data == null) {
|
||||
Slog.w(TAG, "Failed to get package name in package receiver");
|
||||
return;
|
||||
}
|
||||
final String packageName = data.getSchemeSpecificPart();
|
||||
final String action = intent.getAction();
|
||||
if (ACTION_PACKAGE_REMOVED.equals(action)) {
|
||||
removePackageFromSettings(packageName);
|
||||
} else {
|
||||
Slog.w(TAG, "Unsupported action in package receiver: " + action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,58 +16,28 @@
|
||||
|
||||
package com.android.server.communal;
|
||||
|
||||
import static android.app.communal.CommunalManager.ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT;
|
||||
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
|
||||
import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
|
||||
import static com.android.server.wm.ActivityInterceptorCallback.COMMUNAL_MODE_ORDERED_ID;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.communal.ICommunalManager;
|
||||
import android.app.compat.CompatChanges;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.SystemService;
|
||||
import com.android.server.wm.ActivityInterceptorCallback;
|
||||
import com.android.server.wm.ActivityTaskManagerInternal;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoSession;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.quality.Strictness;
|
||||
@@ -82,25 +52,9 @@ import org.mockito.quality.Strictness;
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
public class CommunalManagerServiceTest {
|
||||
private static final int TEST_USER_ID = 1;
|
||||
private static final int TEST_REAL_CALLING_UID = 2;
|
||||
private static final int TEST_REAL_CALLING_PID = 3;
|
||||
private static final String TEST_CALLING_PACKAGE = "com.test.caller";
|
||||
private static final String TEST_PACKAGE_NAME = "com.test.package";
|
||||
|
||||
private MockitoSession mMockingSession;
|
||||
private CommunalManagerService mService;
|
||||
|
||||
@Mock
|
||||
private ActivityTaskManagerInternal mAtmInternal;
|
||||
@Mock
|
||||
private KeyguardManager mKeyguardManager;
|
||||
@Mock
|
||||
private DreamManagerInternal mDreamManagerInternal;
|
||||
|
||||
private ActivityInterceptorCallback mActivityInterceptorCallback;
|
||||
private BroadcastReceiver mPackageReceiver;
|
||||
private ActivityInfo mAInfo;
|
||||
private ICommunalManager mBinder;
|
||||
private ContextWrapper mContextSpy;
|
||||
|
||||
@@ -108,19 +62,10 @@ public class CommunalManagerServiceTest {
|
||||
public final void setUp() {
|
||||
mMockingSession = mockitoSession()
|
||||
.initMocks(this)
|
||||
.spyStatic(CommunalManagerService.class)
|
||||
.mockStatic(CompatChanges.class)
|
||||
.strictness(Strictness.WARN)
|
||||
.startMocking();
|
||||
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
MockContentResolver cr = new MockContentResolver(mContextSpy);
|
||||
cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
|
||||
when(mContextSpy.getContentResolver()).thenReturn(cr);
|
||||
|
||||
when(mContextSpy.getSystemService(KeyguardManager.class)).thenReturn(mKeyguardManager);
|
||||
addLocalServiceMock(ActivityTaskManagerInternal.class, mAtmInternal);
|
||||
addLocalServiceMock(DreamManagerInternal.class, mDreamManagerInternal);
|
||||
|
||||
doNothing().when(mContextSpy).enforceCallingPermission(
|
||||
eq(Manifest.permission.WRITE_COMMUNAL_STATE), anyString());
|
||||
@@ -128,83 +73,16 @@ public class CommunalManagerServiceTest {
|
||||
eq(Manifest.permission.READ_COMMUNAL_STATE), anyString());
|
||||
|
||||
mService = new CommunalManagerService(mContextSpy);
|
||||
mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
|
||||
|
||||
ArgumentCaptor<ActivityInterceptorCallback> activityInterceptorCaptor =
|
||||
ArgumentCaptor.forClass(ActivityInterceptorCallback.class);
|
||||
verify(mAtmInternal).registerActivityStartInterceptor(eq(COMMUNAL_MODE_ORDERED_ID),
|
||||
activityInterceptorCaptor.capture());
|
||||
mActivityInterceptorCallback = activityInterceptorCaptor.getValue();
|
||||
|
||||
ArgumentCaptor<BroadcastReceiver> packageReceiverCaptor =
|
||||
ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
verify(mContextSpy).registerReceiverAsUser(packageReceiverCaptor.capture(),
|
||||
eq(UserHandle.SYSTEM), any(), any(), any(), anyInt());
|
||||
mPackageReceiver = packageReceiverCaptor.getValue();
|
||||
|
||||
mBinder = mService.getBinderServiceInstance();
|
||||
|
||||
mAInfo = new ActivityInfo();
|
||||
mAInfo.applicationInfo = new ApplicationInfo();
|
||||
mAInfo.packageName = mAInfo.applicationInfo.packageName = TEST_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
FakeSettingsProvider.clearSettingsProvider();
|
||||
if (mMockingSession != null) {
|
||||
mMockingSession.finishMocking();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mock and registers it to {@link LocalServices}.
|
||||
*/
|
||||
private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
|
||||
LocalServices.removeServiceForTest(clazz);
|
||||
LocalServices.addService(clazz, mock);
|
||||
}
|
||||
|
||||
private ActivityInterceptorCallback.ActivityInterceptorInfo buildActivityInfo(Intent intent) {
|
||||
return new ActivityInterceptorCallback.ActivityInterceptorInfo(
|
||||
TEST_REAL_CALLING_UID,
|
||||
TEST_REAL_CALLING_PID,
|
||||
TEST_USER_ID,
|
||||
TEST_CALLING_PACKAGE,
|
||||
"featureId",
|
||||
intent,
|
||||
null,
|
||||
mAInfo,
|
||||
"resolvedType",
|
||||
TEST_REAL_CALLING_PID,
|
||||
TEST_REAL_CALLING_UID,
|
||||
null);
|
||||
}
|
||||
|
||||
private void allowPackages(String packages) {
|
||||
Settings.Secure.putStringForUser(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.COMMUNAL_MODE_PACKAGES, packages, UserHandle.USER_SYSTEM);
|
||||
}
|
||||
|
||||
private String getAllowedPackages() {
|
||||
return Settings.Secure.getStringForUser(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.COMMUNAL_MODE_PACKAGES, UserHandle.USER_SYSTEM);
|
||||
}
|
||||
|
||||
private void assertDoesIntercept() {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
assertThat(mActivityInterceptorCallback.intercept(buildActivityInfo(intent))).isNotNull();
|
||||
}
|
||||
|
||||
private void assertDoesNotIntercept() {
|
||||
final Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
assertThat(mActivityInterceptorCallback.intercept(buildActivityInfo(intent))).isNull();
|
||||
}
|
||||
|
||||
private Intent createPackageIntent(String packageName, @Nullable String action) {
|
||||
return new Intent(action, Uri.parse("package:" + packageName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsCommunalMode_isTrue() throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
@@ -216,149 +94,4 @@ public class CommunalManagerServiceTest {
|
||||
mBinder.setCommunalViewShowing(false);
|
||||
assertThat(mBinder.isCommunalMode()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_unlocked_communalOff_appNotEnabled_showWhenLockedOff() {
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
|
||||
mAInfo.flags = 0;
|
||||
assertDoesNotIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_unlocked_communalOn_appNotEnabled_showWhenLockedOff()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(false);
|
||||
mAInfo.flags = 0;
|
||||
assertDoesNotIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOff_appNotEnabled_showWhenLockedOff() {
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
mAInfo.flags = 0;
|
||||
assertDoesNotIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_appNotEnabled_showWhenLockedOff_allowlistEnabled()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(CompatChanges.isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, TEST_PACKAGE_NAME,
|
||||
UserHandle.SYSTEM)).thenReturn(true);
|
||||
mAInfo.flags = 0;
|
||||
assertDoesIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_appNotEnabled_showWhenLockedOn_allowlistEnabled()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(CompatChanges.isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, TEST_PACKAGE_NAME,
|
||||
UserHandle.SYSTEM)).thenReturn(true);
|
||||
mAInfo.flags = FLAG_SHOW_WHEN_LOCKED;
|
||||
|
||||
allowPackages("package1,package2");
|
||||
assertDoesIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_appEnabled_showWhenLockedOff_allowlistEnabled()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(CompatChanges.isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, TEST_PACKAGE_NAME,
|
||||
UserHandle.SYSTEM)).thenReturn(true);
|
||||
mAInfo.flags = 0;
|
||||
|
||||
allowPackages(TEST_PACKAGE_NAME);
|
||||
assertDoesIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_appEnabled_showWhenLockedOn_allowlistEnabled()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(CompatChanges.isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, TEST_PACKAGE_NAME,
|
||||
UserHandle.SYSTEM)).thenReturn(true);
|
||||
|
||||
mAInfo.flags = FLAG_SHOW_WHEN_LOCKED;
|
||||
|
||||
allowPackages(TEST_PACKAGE_NAME);
|
||||
assertDoesNotIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_appEnabled_showWhenLockedOn_allowlistDisabled()
|
||||
throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(CompatChanges.isChangeEnabled(ALLOW_COMMUNAL_MODE_WITH_USER_CONSENT, TEST_PACKAGE_NAME,
|
||||
UserHandle.SYSTEM)).thenReturn(false);
|
||||
|
||||
mAInfo.flags = FLAG_SHOW_WHEN_LOCKED;
|
||||
|
||||
allowPackages(TEST_PACKAGE_NAME);
|
||||
assertDoesIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept_locked_communalOn_dream() throws RemoteException {
|
||||
mBinder.setCommunalViewShowing(true);
|
||||
when(mKeyguardManager.isKeyguardLocked()).thenReturn(true);
|
||||
when(mDreamManagerInternal.getActiveDreamComponent(false)).thenReturn(
|
||||
new ComponentName(TEST_PACKAGE_NAME, "SomeClass"));
|
||||
|
||||
allowPackages(TEST_PACKAGE_NAME);
|
||||
assertDoesNotIntercept();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSettings_packageUninstalled() {
|
||||
allowPackages("package1,package2");
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
|
||||
mPackageReceiver.onReceive(mContextSpy,
|
||||
createPackageIntent("package1", ACTION_PACKAGE_REMOVED));
|
||||
|
||||
assertThat(getAllowedPackages()).isEqualTo("package2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSettings_nullAction_doesNothing() {
|
||||
allowPackages("package1,package2");
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
|
||||
mPackageReceiver.onReceive(mContextSpy,
|
||||
createPackageIntent("package1", null));
|
||||
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSettings_invalidPackage_doesNothing() {
|
||||
allowPackages("package1,package2");
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
|
||||
mPackageReceiver.onReceive(mContextSpy,
|
||||
createPackageIntent("package3", ACTION_PACKAGE_REMOVED));
|
||||
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSettings_onBoot() {
|
||||
allowPackages("package1,package2");
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1,package2");
|
||||
|
||||
when(CommunalManagerService.isPackageInstalled(eq("package1"), any())).thenReturn(true);
|
||||
when(CommunalManagerService.isPackageInstalled(eq("package2"), any())).thenReturn(false);
|
||||
|
||||
mService.onBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
|
||||
|
||||
assertThat(getAllowedPackages()).isEqualTo("package1");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user