diff options
10 files changed, 331 insertions, 26 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 16299c7aff7b..4ebc0ad9267d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -78,6 +78,7 @@ import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.ViewController; @@ -365,6 +366,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } }; + private final DeviceProvisionedController mDeviceProvisionedController; + @Inject public KeyguardSecurityContainerController(KeyguardSecurityContainer view, AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, @@ -386,7 +389,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard FalsingA11yDelegate falsingA11yDelegate, TelephonyManager telephonyManager, ViewMediatorCallback viewMediatorCallback, - AudioManager audioManager + AudioManager audioManager, + DeviceProvisionedController deviceProvisionedController ) { super(view); mLockPatternUtils = lockPatternUtils; @@ -411,6 +415,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard mTelephonyManager = telephonyManager; mViewMediatorCallback = viewMediatorCallback; mAudioManager = audioManager; + mDeviceProvisionedController = deviceProvisionedController; } @Override @@ -752,8 +757,11 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard case SimPuk: // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); - if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( - KeyguardUpdateMonitor.getCurrentUser())) { + boolean isLockscreenDisabled = mLockPatternUtils.isLockScreenDisabled( + KeyguardUpdateMonitor.getCurrentUser()) + || !mDeviceProvisionedController.isUserSetup(targetUserId); + + if (securityMode == SecurityMode.None && isLockscreenDisabled) { finish = true; eventSubtype = BOUNCER_DISMISS_SIM; uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM; diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java index 6b859763eb6f..c6c08585640f 100644 --- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java @@ -51,6 +51,7 @@ import com.android.systemui.util.time.SystemClock; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; import javax.inject.Inject; @@ -144,6 +145,10 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon protected void setListening(boolean listening) { mListening = listening; if (listening) { + // System UI could be restarted while ops are active, so fetch the currently active ops + // once System UI starts listening again. + fetchCurrentActiveOps(); + mAppOps.startWatchingActive(OPS, this); mAppOps.startWatchingNoted(OPS, this); mAudioManager.registerAudioRecordingCallback(mAudioRecordingCallback, mBGHandler); @@ -176,6 +181,29 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } } + private void fetchCurrentActiveOps() { + List<AppOpsManager.PackageOps> packageOps = mAppOps.getPackagesForOps(OPS); + for (AppOpsManager.PackageOps op : packageOps) { + for (AppOpsManager.OpEntry entry : op.getOps()) { + for (Map.Entry<String, AppOpsManager.AttributedOpEntry> attributedOpEntry : + entry.getAttributedOpEntries().entrySet()) { + if (attributedOpEntry.getValue().isRunning()) { + onOpActiveChanged( + entry.getOpStr(), + op.getUid(), + op.getPackageName(), + /* attributionTag= */ attributedOpEntry.getKey(), + /* active= */ true, + // AppOpsManager doesn't have a way to fetch attribution flags or + // chain ID given an op entry, so default them to none. + AppOpsManager.ATTRIBUTION_FLAGS_NONE, + AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE); + } + } + } + } + } + /** * Adds a callback that will get notifified when an AppOp of the type the controller tracks * changes diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt index f7a4feafee25..997020155cdc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImpl.kt @@ -128,8 +128,9 @@ constructor( override fun onStatusEvent(event: StatusEvent) { Assert.isMainThread() - // Ignore any updates until the system is up and running - if (isTooEarly() || !isImmersiveIndicatorEnabled()) { + // Ignore any updates until the system is up and running. However, for important events that + // request to be force visible (like privacy), ignore whether it's too early. + if ((isTooEarly() && !event.forceVisible) || !isImmersiveIndicatorEnabled()) { return } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt index 5fa83ef5d454..6b5a548b0afe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerLegacyImpl.kt @@ -93,8 +93,9 @@ constructor( @SystemAnimationState override fun getAnimationState() = animationState override fun onStatusEvent(event: StatusEvent) { - // Ignore any updates until the system is up and running - if (isTooEarly() || !isImmersiveIndicatorEnabled()) { + // Ignore any updates until the system is up and running. However, for important events that + // request to be force visible (like privacy), ignore whether it's too early. + if ((isTooEarly() && !event.forceVisible) || !isImmersiveIndicatorEnabled()) { return } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index 3b3df239b8ea..73ef12f35a1f 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -71,6 +71,7 @@ import com.android.systemui.log.SessionTracker; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.statusbar.policy.UserSwitcherController; import com.android.systemui.util.settings.GlobalSettings; @@ -208,7 +209,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { mConfigurationController, mFalsingCollector, mFalsingManager, mUserSwitcherController, mFeatureFlags, mGlobalSettings, mSessionTracker, Optional.of(mSideFpsController), mFalsingA11yDelegate, - mTelephonyManager, mViewMediatorCallback, mAudioManager); + mTelephonyManager, mViewMediatorCallback, mAudioManager, + mock(DeviceProvisionedController.class)); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java index 61a651234e0c..e6c36c18342c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java @@ -19,6 +19,8 @@ package com.android.systemui.appops; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; +import static com.google.common.truth.Truth.assertThat; + import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; @@ -66,6 +68,7 @@ import org.mockito.MockitoAnnotations; import java.util.Collections; import java.util.List; +import java.util.Map; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -158,6 +161,204 @@ public class AppOpsControllerTest extends SysuiTestCase { } @Test + public void startListening_fetchesCurrentActive_none() { + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of()); + + mController.setListening(true); + + assertThat(mController.getActiveAppOps()).isEmpty(); + } + + /** Regression test for b/294104969. */ + @Test + public void startListening_fetchesCurrentActive_oneActive() { + AppOpsManager.PackageOps packageOps = createPackageOp( + "package.test", + /* packageUid= */ 2, + AppOpsManager.OPSTR_FINE_LOCATION, + /* isRunning= */ true); + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of(packageOps)); + + // WHEN we start listening + mController.setListening(true); + + // THEN the active list has the op + List<AppOpItem> list = mController.getActiveAppOps(); + assertEquals(1, list.size()); + AppOpItem first = list.get(0); + assertThat(first.getPackageName()).isEqualTo("package.test"); + assertThat(first.getUid()).isEqualTo(2); + assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION); + } + + @Test + public void startListening_fetchesCurrentActive_multiplePackages() { + AppOpsManager.PackageOps packageOps1 = createPackageOp( + "package.one", + /* packageUid= */ 1, + AppOpsManager.OPSTR_FINE_LOCATION, + /* isRunning= */ true); + AppOpsManager.PackageOps packageOps2 = createPackageOp( + "package.two", + /* packageUid= */ 2, + AppOpsManager.OPSTR_FINE_LOCATION, + /* isRunning= */ false); + AppOpsManager.PackageOps packageOps3 = createPackageOp( + "package.three", + /* packageUid= */ 3, + AppOpsManager.OPSTR_FINE_LOCATION, + /* isRunning= */ true); + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of(packageOps1, packageOps2, packageOps3)); + + // WHEN we start listening + mController.setListening(true); + + // THEN the active list has the ops + List<AppOpItem> list = mController.getActiveAppOps(); + assertEquals(2, list.size()); + + AppOpItem item0 = list.get(0); + assertThat(item0.getPackageName()).isEqualTo("package.one"); + assertThat(item0.getUid()).isEqualTo(1); + assertThat(item0.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION); + + AppOpItem item1 = list.get(1); + assertThat(item1.getPackageName()).isEqualTo("package.three"); + assertThat(item1.getUid()).isEqualTo(3); + assertThat(item1.getCode()).isEqualTo(AppOpsManager.OP_FINE_LOCATION); + } + + @Test + public void startListening_fetchesCurrentActive_multipleEntries() { + AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class); + when(packageOps.getUid()).thenReturn(1); + when(packageOps.getPackageName()).thenReturn("package.one"); + + // Entry 1 + AppOpsManager.OpEntry entry1 = mock(AppOpsManager.OpEntry.class); + when(entry1.getOpStr()).thenReturn(AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE); + AppOpsManager.AttributedOpEntry attributed1 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed1.isRunning()).thenReturn(true); + when(entry1.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed1)); + // Entry 2 + AppOpsManager.OpEntry entry2 = mock(AppOpsManager.OpEntry.class); + when(entry2.getOpStr()).thenReturn(AppOpsManager.OPSTR_CAMERA); + AppOpsManager.AttributedOpEntry attributed2 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed2.isRunning()).thenReturn(true); + when(entry2.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed2)); + // Entry 3 + AppOpsManager.OpEntry entry3 = mock(AppOpsManager.OpEntry.class); + when(entry3.getOpStr()).thenReturn(AppOpsManager.OPSTR_FINE_LOCATION); + AppOpsManager.AttributedOpEntry attributed3 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed3.isRunning()).thenReturn(false); + when(entry3.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed3)); + + when(packageOps.getOps()).thenReturn(List.of(entry1, entry2, entry3)); + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of(packageOps)); + + // WHEN we start listening + mController.setListening(true); + + // THEN the active list has the ops + List<AppOpItem> list = mController.getActiveAppOps(); + assertEquals(2, list.size()); + + AppOpItem first = list.get(0); + assertThat(first.getPackageName()).isEqualTo("package.one"); + assertThat(first.getUid()).isEqualTo(1); + assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_PHONE_CALL_MICROPHONE); + + AppOpItem second = list.get(1); + assertThat(second.getPackageName()).isEqualTo("package.one"); + assertThat(second.getUid()).isEqualTo(1); + assertThat(second.getCode()).isEqualTo(AppOpsManager.OP_CAMERA); + } + + @Test + public void startListening_fetchesCurrentActive_multipleAttributes() { + AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class); + when(packageOps.getUid()).thenReturn(1); + when(packageOps.getPackageName()).thenReturn("package.one"); + AppOpsManager.OpEntry entry = mock(AppOpsManager.OpEntry.class); + when(entry.getOpStr()).thenReturn(AppOpsManager.OPSTR_RECORD_AUDIO); + + AppOpsManager.AttributedOpEntry attributed1 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed1.isRunning()).thenReturn(false); + AppOpsManager.AttributedOpEntry attributed2 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed2.isRunning()).thenReturn(true); + AppOpsManager.AttributedOpEntry attributed3 = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed3.isRunning()).thenReturn(true); + when(entry.getAttributedOpEntries()).thenReturn( + Map.of("attr1", attributed1, "attr2", attributed2, "attr3", attributed3)); + + when(packageOps.getOps()).thenReturn(List.of(entry)); + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of(packageOps)); + + // WHEN we start listening + mController.setListening(true); + + // THEN the active list has the ops + List<AppOpItem> list = mController.getActiveAppOps(); + // Multiple attributes get merged into one entry in the active ops + assertEquals(1, list.size()); + + AppOpItem first = list.get(0); + assertThat(first.getPackageName()).isEqualTo("package.one"); + assertThat(first.getUid()).isEqualTo(1); + assertThat(first.getCode()).isEqualTo(AppOpsManager.OP_RECORD_AUDIO); + } + + /** Regression test for b/294104969. */ + @Test + public void addCallback_existingCallbacksNotifiedOfCurrentActive() { + AppOpsManager.PackageOps packageOps1 = createPackageOp( + "package.one", + /* packageUid= */ 1, + AppOpsManager.OPSTR_FINE_LOCATION, + /* isRunning= */ true); + AppOpsManager.PackageOps packageOps2 = createPackageOp( + "package.two", + /* packageUid= */ 2, + AppOpsManager.OPSTR_RECORD_AUDIO, + /* isRunning= */ true); + AppOpsManager.PackageOps packageOps3 = createPackageOp( + "package.three", + /* packageUid= */ 3, + AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, + /* isRunning= */ true); + when(mAppOpsManager.getPackagesForOps(AppOpsControllerImpl.OPS)) + .thenReturn(List.of(packageOps1, packageOps2, packageOps3)); + + // WHEN we start listening + mController.addCallback( + new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION}, + mCallback); + mTestableLooper.processAllMessages(); + + // THEN the callback is notified of the current active ops it cares about + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_FINE_LOCATION, + /* uid= */ 1, + "package.one", + true); + verify(mCallback).onActiveStateChanged( + AppOpsManager.OP_RECORD_AUDIO, + /* uid= */ 2, + "package.two", + true); + verify(mCallback, never()).onActiveStateChanged( + AppOpsManager.OP_PHONE_CALL_MICROPHONE, + /* uid= */ 3, + "package.three", + true); + } + + @Test public void addCallback_includedCode() { mController.addCallback( new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_FINE_LOCATION}, @@ -673,6 +874,22 @@ public class AppOpsControllerTest extends SysuiTestCase { assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(cameraIdx).getCode()); } + private AppOpsManager.PackageOps createPackageOp( + String packageName, int packageUid, String opStr, boolean isRunning) { + AppOpsManager.PackageOps packageOps = mock(AppOpsManager.PackageOps.class); + when(packageOps.getPackageName()).thenReturn(packageName); + when(packageOps.getUid()).thenReturn(packageUid); + AppOpsManager.OpEntry entry = mock(AppOpsManager.OpEntry.class); + when(entry.getOpStr()).thenReturn(opStr); + AppOpsManager.AttributedOpEntry attributed = mock(AppOpsManager.AttributedOpEntry.class); + when(attributed.isRunning()).thenReturn(isRunning); + + when(packageOps.getOps()).thenReturn(Collections.singletonList(entry)); + when(entry.getAttributedOpEntries()).thenReturn(Map.of("tag", attributed)); + + return packageOps; + } + private class TestHandler extends AppOpsControllerImpl.H { TestHandler(Looper looper) { mController.super(looper); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt index 7b59cc284181..f0de14eaf2bc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/events/SystemStatusAnimationSchedulerImplTest.kt @@ -87,9 +87,6 @@ class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() { fakeFeatureFlags ) - // ensure that isTooEarly() check in SystemStatusAnimationScheduler does not return true - systemClock.advanceTime(Process.getStartUptimeMillis() + MIN_UPTIME) - // StatusBarContentInsetProvider is mocked. Ensure that it returns some mocked values. whenever(statusBarContentInsetProvider.getStatusBarContentInsetsForCurrentRotation()) .thenReturn(android.util.Pair(10, 10)) @@ -150,6 +147,21 @@ class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() { assertEquals(0f, batteryChip.view.alpha) } + /** Regression test for b/294104969. */ + @Test + fun testPrivacyStatusEvent_beforeSystemUptime_stillDisplayed() = runTest { + initializeSystemStatusAnimationScheduler(testScope = this, advancePastMinUptime = false) + + // WHEN the uptime hasn't quite passed the minimum required uptime... + systemClock.setUptimeMillis(Process.getStartUptimeMillis() + MIN_UPTIME / 2) + + // BUT the event is a privacy event + createAndScheduleFakePrivacyEvent() + + // THEN the privacy event still happens + assertEquals(ANIMATION_QUEUED, systemStatusAnimationScheduler.getAnimationState()) + } + @Test fun testPrivacyStatusEvent_standardAnimationLifecycle() = runTest { // Instantiate class under test with TestScope from runTest @@ -454,7 +466,10 @@ class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() { return batteryChip } - private fun initializeSystemStatusAnimationScheduler(testScope: TestScope) { + private fun initializeSystemStatusAnimationScheduler( + testScope: TestScope, + advancePastMinUptime: Boolean = true, + ) { systemStatusAnimationScheduler = SystemStatusAnimationSchedulerImpl( systemEventCoordinator, @@ -466,5 +481,10 @@ class SystemStatusAnimationSchedulerImplTest : SysuiTestCase() { ) // add a mock listener systemStatusAnimationScheduler.addCallback(listener) + + if (advancePastMinUptime) { + // ensure that isTooEarly() check in SystemStatusAnimationScheduler does not return true + systemClock.advanceTime(Process.getStartUptimeMillis() + MIN_UPTIME) + } } } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index a94e4b9b492d..41546d2bdc38 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -132,6 +132,7 @@ public class CompanionDeviceManagerService extends SystemService { "debug.cdm.cdmservice.removal_time_window"; private static final long ASSOCIATION_REMOVAL_TIME_WINDOW_DEFAULT = DAYS.toMillis(90); + private static final int MAX_CN_LENGTH = 500; private final ActivityManager mActivityManager; private final OnPackageVisibilityChangeListener mOnPackageVisibilityChangeListener; @@ -619,8 +620,10 @@ public class CompanionDeviceManagerService extends SystemService { public PendingIntent requestNotificationAccess(ComponentName component, int userId) throws RemoteException { String callingPackage = component.getPackageName(); - checkCanCallNotificationApi(callingPackage); - // TODO: check userId. + checkCanCallNotificationApi(callingPackage, userId); + if (component.flattenToString().length() > MAX_CN_LENGTH) { + throw new IllegalArgumentException("Component name is too long."); + } final long identity = Binder.clearCallingIdentity(); try { return PendingIntent.getActivityAsUser(getContext(), @@ -643,7 +646,7 @@ public class CompanionDeviceManagerService extends SystemService { @Deprecated @Override public boolean hasNotificationAccess(ComponentName component) throws RemoteException { - checkCanCallNotificationApi(component.getPackageName()); + checkCanCallNotificationApi(component.getPackageName(), getCallingUserId()); NotificationManager nm = getContext().getSystemService(NotificationManager.class); return nm.isNotificationListenerAccessGranted(component); } @@ -800,8 +803,7 @@ public class CompanionDeviceManagerService extends SystemService { legacyCreateAssociation(userId, macAddress, packageName, null); } - private void checkCanCallNotificationApi(String callingPackage) { - final int userId = getCallingUserId(); + private void checkCanCallNotificationApi(String callingPackage, int userId) { enforceCallerIsSystemOr(userId, callingPackage); if (getCallingUid() == SYSTEM_UID) return; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 46f62b83d669..70bef605b567 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5434,7 +5434,20 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { - target.send(code, intent, resolvedType, allowlistToken, null, + if (allowlistToken != null) { + final int callingUid = Binder.getCallingUid(); + final String packageName; + final long token = Binder.clearCallingIdentity(); + try { + packageName = AppGlobals.getPackageManager().getNameForUid(callingUid); + } finally { + Binder.restoreCallingIdentity(token); + } + Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target." + + " Calling package: " + packageName + "; intent: " + intent + + "; options: " + options); + } + target.send(code, intent, resolvedType, null, null, requiredPermission, options); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 88aeb17dc2b4..edc3923b2998 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -258,6 +258,8 @@ public class UserManagerService extends IUserManager.Stub { private static final int USER_VERSION = 9; + private static final int MAX_USER_STRING_LENGTH = 500; + private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms static final int WRITE_USER_MSG = 1; @@ -3514,15 +3516,17 @@ public class UserManagerService extends IUserManager.Stub { // Write seed data if (userData.persistSeedData) { if (userData.seedAccountName != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, userData.seedAccountName); + serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, + truncateString(userData.seedAccountName)); } if (userData.seedAccountType != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, userData.seedAccountType); + serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, + truncateString(userData.seedAccountType)); } } if (userInfo.name != null) { serializer.startTag(null, TAG_NAME); - serializer.text(userInfo.name); + serializer.text(truncateString(userInfo.name)); serializer.endTag(null, TAG_NAME); } synchronized (mRestrictionsLock) { @@ -3562,6 +3566,13 @@ public class UserManagerService extends IUserManager.Stub { serializer.endDocument(); } + private String truncateString(String original) { + if (original == null || original.length() <= MAX_USER_STRING_LENGTH) { + return original; + } + return original.substring(0, MAX_USER_STRING_LENGTH); + } + /* * Writes the user list file in this format: * @@ -3967,6 +3978,8 @@ public class UserManagerService extends IUserManager.Stub { boolean preCreate, @Nullable String[] disallowedPackages, @NonNull TimingsTraceAndSlog t, @Nullable Object token) throws UserManager.CheckedUserOperationException { + + String truncatedName = truncateString(name); final UserTypeDetails userTypeDetails = mUserTypes.get(userType); if (userTypeDetails == null) { Slog.e(LOG_TAG, "Cannot create user of invalid user type: " + userType); @@ -3998,8 +4011,8 @@ public class UserManagerService extends IUserManager.Stub { // Try to use a pre-created user (if available). if (!preCreate && parentId < 0 && isUserTypeEligibleForPreCreation(userTypeDetails)) { - final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, name, - token); + final UserInfo preCreatedUser = convertPreCreatedUserIfPossible(userType, flags, + truncatedName, token); if (preCreatedUser != null) { return preCreatedUser; } @@ -4099,7 +4112,7 @@ public class UserManagerService extends IUserManager.Stub { flags |= UserInfo.FLAG_EPHEMERAL_ON_CREATE; } - userInfo = new UserInfo(userId, name, null, flags, userType); + userInfo = new UserInfo(userId, truncatedName, null, flags, userType); userInfo.serialNumber = mNextSerialNumber++; userInfo.creationTime = getCreationTime(); userInfo.partial = true; @@ -5531,8 +5544,8 @@ public class UserManagerService extends IUserManager.Stub { Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); return; } - userData.seedAccountName = accountName; - userData.seedAccountType = accountType; + userData.seedAccountName = truncateString(accountName); + userData.seedAccountType = truncateString(accountType); userData.seedAccountOptions = accountOptions; userData.persistSeedData = persist; } |