summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-10 18:31:07 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-10 18:31:07 +0000
commitdb0e3c4a9ca475c4ca9b5513768b1982d3d03317 (patch)
tree393872ec994215bd3c9ece1aa924c653fde16bc5
parentcb74878e9347fdcf8bbc32f8b379a55ba1c35c64 (diff)
parent7e50754a7c91415bbd8ea5e0519fb815b6418305 (diff)
downloadbase-db0e3c4a9ca475c4ca9b5513768b1982d3d03317.tar.gz
Merge cherrypicks of ['googleplex-android-review.googlesource.com/22621774', 'googleplex-android-review.googlesource.com/24413226', 'googleplex-android-review.googlesource.com/24993589', 'googleplex-android-review.googlesource.com/24867202', 'googleplex-android-review.googlesource.com/24665127', 'googleplex-android-review.googlesource.com/25175743', 'googleplex-android-review.googlesource.com/25238611', 'googleplex-android-review.googlesource.com/25119905', 'googleplex-android-review.googlesource.com/25208516'] into security-aosp-sc-release.android-security-12.0.0_r55
Change-Id: Ifa325f9272a44b76f8a9cabd92836309e49e9176
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java12
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java217
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java47
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java29
10 files changed, 333 insertions, 35 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index ab7b54d98285..beadd821957b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -351,7 +351,17 @@ public class DreamBackend {
if (cn != null && cn.indexOf('/') < 0) {
cn = resolveInfo.serviceInfo.packageName + "/" + cn;
}
- return cn == null ? null : ComponentName.unflattenFromString(cn);
+ // Ensure that the component is from the same package as the dream service. If not,
+ // treat the component as invalid and return null instead.
+ final ComponentName result = cn != null ? ComponentName.unflattenFromString(cn) : null;
+ if (result != null
+ && !result.getPackageName().equals(resolveInfo.serviceInfo.packageName)) {
+ Log.w(TAG,
+ "Inconsistent package name in component: " + result.getPackageName()
+ + ", should be: " + resolveInfo.serviceInfo.packageName);
+ return null;
+ }
+ return result;
}
private static void logd(String msg, Object... args) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index fc9c5dddbee5..b2aec6bae864 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -51,6 +51,7 @@ import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Gefingerpoken;
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.util.ViewController;
@@ -196,6 +197,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mSecurityViewFlipperController.reloadColors();
}
};
+ private final DeviceProvisionedController mDeviceProvisionedController;
private KeyguardSecurityContainerController(KeyguardSecurityContainer view,
AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory,
@@ -207,7 +209,9 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
KeyguardStateController keyguardStateController,
SecurityCallback securityCallback,
KeyguardSecurityViewFlipperController securityViewFlipperController,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ DeviceProvisionedController deviceProvisionedController
+ ) {
super(view);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = keyguardUpdateMonitor;
@@ -221,6 +225,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mKeyguardSecurityCallback);
mConfigurationController = configurationController;
mLastOrientation = getResources().getConfiguration().orientation;
+ mDeviceProvisionedController = deviceProvisionedController;
}
@Override
@@ -391,8 +396,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;
@@ -552,6 +560,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
private final KeyguardStateController mKeyguardStateController;
private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController;
private final ConfigurationController mConfigurationController;
+ private final DeviceProvisionedController mDeviceProvisionedController;
@Inject
Factory(KeyguardSecurityContainer view,
@@ -564,7 +573,8 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
UiEventLogger uiEventLogger,
KeyguardStateController keyguardStateController,
KeyguardSecurityViewFlipperController securityViewFlipperController,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ DeviceProvisionedController deviceProvisionedController) {
mView = view;
mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory;
mLockPatternUtils = lockPatternUtils;
@@ -575,6 +585,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mKeyguardStateController = keyguardStateController;
mSecurityViewFlipperController = securityViewFlipperController;
mConfigurationController = configurationController;
+ mDeviceProvisionedController = deviceProvisionedController;
}
public KeyguardSecurityContainerController create(
@@ -583,7 +594,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
mKeyguardStateController, securityCallback, mSecurityViewFlipperController,
- mConfigurationController);
+ mConfigurationController, mDeviceProvisionedController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index 9676a57b2df9..bcf3de1c0b97 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -52,6 +52,7 @@ import java.io.FileDescriptor;
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/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 70af5b647362..fba7ac037ee8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -574,7 +574,7 @@ class MediaDataManager(
// Song name
var song: CharSequence? = metadata?.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE)
if (song.isNullOrBlank()) {
- song = metadata.getString(MediaMetadata.METADATA_KEY_TITLE)
+ song = metadata?.getString(MediaMetadata.METADATA_KEY_TITLE)
}
if (song.isNullOrBlank()) {
song = HybridGroupManager.resolveTitle(notif)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index dcf8e739a76e..37a7ba58422d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -93,8 +93,9 @@ class SystemStatusAnimationScheduler @Inject constructor(
}
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 917a6f38df0a..70825ef77765 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -47,6 +47,7 @@ import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -135,7 +136,7 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
mKeyguardStateController, mKeyguardSecurityViewFlipperController,
- mConfigurationController)
+ mConfigurationController, mock(DeviceProvisionedController.class))
.create(mSecurityCallback);
}
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/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 595218207713..eccfe2ecb0b2 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -172,6 +172,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
private static final int ASSOCIATE_WITHOUT_PROMPT_MAX_PER_TIME_WINDOW = 5;
private static final long ASSOCIATE_WITHOUT_PROMPT_WINDOW_MS = 60 * 60 * 1000; // 60 min;
+ private static final int MAX_CN_LENGTH = 500;
private static final String XML_TAG_ASSOCIATIONS = "associations";
private static final String XML_TAG_ASSOCIATION = "association";
@@ -552,6 +553,9 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
String callingPackage = component.getPackageName();
checkCanCallNotificationApi(callingPackage);
int userId = getCallingUserId();
+ 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(),
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 123bb6c856f3..43423e25376a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3663,6 +3663,22 @@ public class ActivityManagerService extends IActivityManager.Stub
throw new SecurityException(msg);
}
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+
+ ProcessRecord proc;
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(callingPid);
+ }
+ if (callingUid >= FIRST_APPLICATION_UID
+ && (proc == null || !proc.info.isSystemApp())) {
+ final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
+ + callingPid + ", uid=" + callingUid + " is not allowed";
+ Slog.w(TAG, msg);
+ // Silently return to avoid existing apps from crashing.
+ return;
+ }
+
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (this) {
@@ -3703,22 +3719,6 @@ public class ActivityManagerService extends IActivityManager.Stub
throw new SecurityException(msg);
}
- final int callingUid = Binder.getCallingUid();
- final int callingPid = Binder.getCallingPid();
-
- ProcessRecord proc;
- synchronized (mPidsSelfLocked) {
- proc = mPidsSelfLocked.get(callingPid);
- }
- if (callingUid >= FIRST_APPLICATION_UID
- && (proc == null || !proc.info.isSystemApp())) {
- final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
- + callingPid + ", uid=" + callingUid + " is not allowed";
- Slog.w(TAG, msg);
- // Silently return to avoid existing apps from crashing.
- return;
- }
-
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (this) {
@@ -5006,7 +5006,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 d441b76406c2..4179559d778d 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -247,6 +247,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;
@@ -3156,15 +3158,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) {
@@ -3204,6 +3208,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:
*
@@ -3564,6 +3575,7 @@ 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);
@@ -3589,8 +3601,9 @@ 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;
}
@@ -3683,7 +3696,7 @@ public class UserManagerService extends IUserManager.Stub {
flags &= ~UserInfo.FLAG_EPHEMERAL;
}
- 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;
@@ -4976,8 +4989,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;
}