summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/safetycenter/SafetyCenterConfigReader.java12
-rw-r--r--service/java/com/android/safetycenter/SafetyCenterService.java5
-rw-r--r--service/java/com/android/safetycenter/data/SafetyCenterDataManager.java25
-rw-r--r--service/java/com/android/safetycenter/data/SafetySourceDataValidator.java26
-rw-r--r--tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt14
5 files changed, 68 insertions, 14 deletions
diff --git a/service/java/com/android/safetycenter/SafetyCenterConfigReader.java b/service/java/com/android/safetycenter/SafetyCenterConfigReader.java
index e3e39cc9a..c473ad916 100644
--- a/service/java/com/android/safetycenter/SafetyCenterConfigReader.java
+++ b/service/java/com/android/safetycenter/SafetyCenterConfigReader.java
@@ -175,16 +175,20 @@ public final class SafetyCenterConfigReader {
* source is expected to interact with Safety Center, but is currently being silenced / no-ops
* while an override for tests is in place.
*
- * <p>The {@code callingPackageName} is used to differentiate a real source being overridden. It
- * could be that a test is overriding a real source and as such the real source should not be
- * able to provide data while its override is in place.
+ * <p>The {@code callingPackageName} can be used to differentiate a real source being
+ * overridden. It could be that a test is overriding a real source and as such the real source
+ * should not be able to provide data while its override is in place.
*/
- public boolean isExternalSafetySourceActive(String safetySourceId, String callingPackageName) {
+ public boolean isExternalSafetySourceActive(
+ String safetySourceId, @Nullable String callingPackageName) {
ExternalSafetySource externalSafetySourceInCurrentConfig =
getCurrentConfigInternal().getExternalSafetySources().get(safetySourceId);
if (externalSafetySourceInCurrentConfig == null) {
return false;
}
+ if (callingPackageName == null) {
+ return true;
+ }
return Objects.equals(
externalSafetySourceInCurrentConfig.getSafetySource().getPackageName(),
callingPackageName);
diff --git a/service/java/com/android/safetycenter/SafetyCenterService.java b/service/java/com/android/safetycenter/SafetyCenterService.java
index 578997355..98e97a26c 100644
--- a/service/java/com/android/safetycenter/SafetyCenterService.java
+++ b/service/java/com/android/safetycenter/SafetyCenterService.java
@@ -342,9 +342,8 @@ public final class SafetyCenterService extends SystemService {
String safetySourceId, String packageName, @UserIdInt int userId) {
requireNonNull(safetySourceId);
requireNonNull(packageName);
- getContext()
- .enforceCallingOrSelfPermission(
- SEND_SAFETY_CENTER_UPDATE, "getSafetySourceData");
+ enforceAnyCallingOrSelfPermissions(
+ "getSafetySourceData", SEND_SAFETY_CENTER_UPDATE, MANAGE_SAFETY_CENTER);
if (!enforceCrossUserPermission("getSafetySourceData", userId)
|| !enforcePackage(Binder.getCallingUid(), packageName, userId)
|| !checkApiEnabled("getSafetySourceData")) {
diff --git a/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java b/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java
index 018fedf41..dff7c4339 100644
--- a/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java
+++ b/service/java/com/android/safetycenter/data/SafetyCenterDataManager.java
@@ -16,6 +16,9 @@
package com.android.safetycenter.data;
+import static android.Manifest.permission.MANAGE_SAFETY_CENTER;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
import static com.android.safetycenter.logging.SafetyCenterStatsdLogger.toSystemEventResult;
import android.annotation.UserIdInt;
@@ -63,6 +66,7 @@ public final class SafetyCenterDataManager {
private static final String TAG = "SafetyCenterDataManager";
+ private final Context mContext;
private final SafetyCenterRefreshTracker mSafetyCenterRefreshTracker;
private final SafetySourceDataRepository mSafetySourceDataRepository;
private final SafetyCenterIssueDismissalRepository mSafetyCenterIssueDismissalRepository;
@@ -78,6 +82,7 @@ public final class SafetyCenterDataManager {
SafetyCenterConfigReader safetyCenterConfigReader,
SafetyCenterRefreshTracker safetyCenterRefreshTracker,
ApiLock apiLock) {
+ mContext = context;
mSafetyCenterRefreshTracker = safetyCenterRefreshTracker;
mSafetyCenterInFlightIssueActionRepository =
new SafetyCenterInFlightIssueActionRepository(context);
@@ -130,7 +135,11 @@ public final class SafetyCenterDataManager {
String packageName,
@UserIdInt int userId) {
if (!mSafetySourceDataValidator.validateRequest(
- safetySourceData, safetySourceId, packageName, userId)) {
+ safetySourceData,
+ /* callerCanAccessAnySource= */ false,
+ safetySourceId,
+ packageName,
+ userId)) {
return false;
}
SafetySourceKey safetySourceKey = SafetySourceKey.of(safetySourceId, userId);
@@ -204,7 +213,11 @@ public final class SafetyCenterDataManager {
String packageName,
@UserIdInt int userId) {
if (!mSafetySourceDataValidator.validateRequest(
- /* safetySourceData= */ null, safetySourceId, packageName, userId)) {
+ /* safetySourceData= */ null,
+ /* callerCanAccessAnySource= */ false,
+ safetySourceId,
+ packageName,
+ userId)) {
return false;
}
SafetyEvent safetyEvent = safetySourceErrorDetails.getSafetyEvent();
@@ -425,8 +438,14 @@ public final class SafetyCenterDataManager {
@Nullable
public SafetySourceData getSafetySourceData(
String safetySourceId, String packageName, @UserIdInt int userId) {
+ boolean callerCanAccessAnySource =
+ mContext.checkCallingOrSelfPermission(MANAGE_SAFETY_CENTER) == PERMISSION_GRANTED;
if (!mSafetySourceDataValidator.validateRequest(
- /* safetySourceData= */ null, safetySourceId, packageName, userId)) {
+ /* safetySourceData= */ null,
+ callerCanAccessAnySource,
+ safetySourceId,
+ packageName,
+ userId)) {
return null;
}
return mSafetySourceDataRepository.getSafetySourceData(
diff --git a/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java b/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java
index 8a3151c9f..7355035b0 100644
--- a/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java
+++ b/service/java/com/android/safetycenter/data/SafetySourceDataValidator.java
@@ -70,9 +70,12 @@ final class SafetySourceDataValidator {
*
* @param safetySourceData being set, or {@code null} if retrieving or clearing data, or
* reporting an error
+ * @param callerCanAccessAnySource whether we should allow the caller to access any source, or
+ * restrict them to their own {@code packageName}
*/
boolean validateRequest(
@Nullable SafetySourceData safetySourceData,
+ boolean callerCanAccessAnySource,
String safetySourceId,
String packageName,
@UserIdInt int userId) {
@@ -83,7 +86,9 @@ final class SafetySourceDataValidator {
}
SafetySource safetySource = externalSafetySource.getSafetySource();
- validateCallingPackage(safetySource, packageName, safetySourceId);
+ if (!callerCanAccessAnySource) {
+ validateCallingPackage(safetySource, packageName, safetySourceId);
+ }
if (UserUtils.isManagedProfile(userId, mContext)
&& !SafetySources.supportsManagedProfiles(safetySource)) {
@@ -93,8 +98,8 @@ final class SafetySourceDataValidator {
boolean retrievingOrClearingData = safetySourceData == null;
if (retrievingOrClearingData) {
- return mSafetyCenterConfigReader.isExternalSafetySourceActive(
- safetySourceId, packageName);
+ return isExternalSafetySourceActive(
+ callerCanAccessAnySource, safetySourceId, packageName);
}
SafetySourceStatus safetySourceStatus = safetySourceData.getStatus();
@@ -160,7 +165,20 @@ final class SafetySourceDataValidator {
}
}
- return mSafetyCenterConfigReader.isExternalSafetySourceActive(safetySourceId, packageName);
+ return isExternalSafetySourceActive(callerCanAccessAnySource, safetySourceId, packageName);
+ }
+
+ private boolean isExternalSafetySourceActive(
+ boolean callerCanAccessAnySource, String safetySourceId, String callerPackageName) {
+ boolean isActive =
+ mSafetyCenterConfigReader.isExternalSafetySourceActive(
+ safetySourceId, callerCanAccessAnySource ? null : callerPackageName);
+ if (!isActive) {
+ Log.i(
+ TAG,
+ "Call ignored as safety source " + safetySourceId + " is not currently active");
+ }
+ return isActive;
}
private void validateCallingPackage(
diff --git a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
index 298d7643c..6193efb71 100644
--- a/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
+++ b/tests/cts/safetycenter/src/android/safetycenter/cts/SafetyCenterManagerTest.kt
@@ -16,6 +16,7 @@
package android.safetycenter.cts
+import android.Manifest.permission.MANAGE_SAFETY_CENTER
import android.content.Context
import android.os.Build.VERSION_CODES.TIRAMISU
import android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE
@@ -88,6 +89,7 @@ import com.android.safetycenter.testing.SafetySourceTestData.Companion.CRITICAL_
import com.android.safetycenter.testing.SafetySourceTestData.Companion.CRITICAL_ISSUE_ID
import com.android.safetycenter.testing.SafetySourceTestData.Companion.EVENT_SOURCE_STATE_CHANGED
import com.android.safetycenter.testing.SafetySourceTestData.Companion.RECOMMENDATION_ISSUE_ID
+import com.android.safetycenter.testing.ShellPermissions.callWithShellPermissionIdentity
import com.android.safetycenter.testing.SupportsSafetyCenterRule
import com.google.common.base.Preconditions.checkState
import com.google.common.truth.Truth.assertThat
@@ -659,6 +661,18 @@ class SafetyCenterManagerTest {
}
@Test
+ fun getSafetySourceData_differentPackageWithManageSafetyCenterPermission_returnsData() {
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexConfig)
+
+ val data =
+ callWithShellPermissionIdentity(MANAGE_SAFETY_CENTER) {
+ safetyCenterManager.getSafetySourceData(DYNAMIC_OTHER_PACKAGE_ID)
+ }
+
+ assertThat(data).isNull()
+ }
+
+ @Test
fun getSafetySourceData_differentPackage_throwsIllegalArgumentException() {
safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.complexConfig)