Merge "Exempt autofill service to record sensitive content" into main
diff --git a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
index 253fe35..ac19d8b 100644
--- a/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
+++ b/services/core/java/com/android/server/SensitiveContentProtectionManagerService.java
@@ -161,20 +161,20 @@
}
if (DEBUG) Log.d(TAG, "onBootPhase - PHASE_BOOT_COMPLETED");
-
- mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
init(getContext().getSystemService(MediaProjectionManager.class),
LocalServices.getService(WindowManagerInternal.class),
- getExemptedPackages());
+ LocalServices.getService(PackageManagerInternal.class),
+ getExemptedPackages()
+ );
if (sensitiveContentAppProtection()) {
publishBinderService(Context.SENSITIVE_CONTENT_PROTECTION_SERVICE,
- new SensitiveContentProtectionManagerServiceBinder(mPackageManagerInternal));
+ new SensitiveContentProtectionManagerServiceBinder());
}
}
@VisibleForTesting
void init(MediaProjectionManager projectionManager, WindowManagerInternal windowManager,
- ArraySet<String> exemptedPackages) {
+ PackageManagerInternal packageManagerInternal, ArraySet<String> exemptedPackages) {
if (DEBUG) Log.d(TAG, "init");
Objects.requireNonNull(projectionManager);
@@ -182,6 +182,7 @@
mProjectionManager = projectionManager;
mWindowManager = windowManager;
+ mPackageManagerInternal = packageManagerInternal;
mExemptedPackages = exemptedPackages;
// TODO(b/317250444): use MediaProjectionManagerService directly, reduces unnecessary
@@ -231,14 +232,16 @@
}
private void onProjectionStart(MediaProjectionInfo projectionInfo) {
- int uid = mPackageManagerInternal.getPackageUid(projectionInfo.getPackageName(), 0,
- projectionInfo.getUserHandle().getIdentifier());
boolean isPackageExempted = (mExemptedPackages != null && mExemptedPackages.contains(
projectionInfo.getPackageName()))
- || canRecordSensitiveContent(projectionInfo.getPackageName());
+ || canRecordSensitiveContent(projectionInfo.getPackageName())
+ || isAutofillServiceRecorderPackage(projectionInfo.getUserHandle().getIdentifier(),
+ projectionInfo.getPackageName());
// TODO(b/324447419): move GlobalSettings lookup to background thread
boolean isFeatureDisabled = Settings.Global.getInt(getContext().getContentResolver(),
DISABLE_SCREEN_SHARE_PROTECTIONS_FOR_APPS_AND_NOTIFICATIONS, 0) != 0;
+ int uid = mPackageManagerInternal.getPackageUid(projectionInfo.getPackageName(), 0,
+ projectionInfo.getUserHandle().getIdentifier());
mMediaProjectionSession = new MediaProjectionSession(
uid, isPackageExempted || isFeatureDisabled, new Random().nextLong());
@@ -295,8 +298,9 @@
// notify windowmanager of any currently posted sensitive content notifications
ArraySet<PackageInfo> packageInfos =
getSensitivePackagesFromNotifications(notifications, rankingMap);
-
- mWindowManager.addBlockScreenCaptureForApps(packageInfos);
+ if (packageInfos.size() > 0) {
+ mWindowManager.addBlockScreenCaptureForApps(packageInfos);
+ }
}
private ArraySet<PackageInfo> getSensitivePackagesFromNotifications(
@@ -422,6 +426,7 @@
if (!mProjectionActive) {
return;
}
+
if (DEBUG) {
Log.d(TAG, "setSensitiveContentProtection - current package=" + packageInfo
+ ", isShowingSensitiveContent=" + isShowingSensitiveContent
@@ -452,15 +457,29 @@
}
}
- private final class SensitiveContentProtectionManagerServiceBinder
- extends ISensitiveContentProtectionManager.Stub {
- private final PackageManagerInternal mPackageManagerInternal;
-
- SensitiveContentProtectionManagerServiceBinder(
- PackageManagerInternal packageManagerInternal) {
- mPackageManagerInternal = packageManagerInternal;
+ // TODO: b/328251279 - Autofill service exemption is temporary and will be removed in future.
+ private boolean isAutofillServiceRecorderPackage(int userId, String projectionPackage) {
+ String autofillServiceName = Settings.Secure.getStringForUser(
+ getContext().getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, userId);
+ if (DEBUG) {
+ Log.d(TAG, "autofill service for user " + userId + " is " + autofillServiceName);
}
+ if (autofillServiceName == null) {
+ return false;
+ }
+ ComponentName serviceComponent = ComponentName.unflattenFromString(autofillServiceName);
+ if (serviceComponent == null) {
+ return false;
+ }
+ String autofillServicePackage = serviceComponent.getPackageName();
+
+ return autofillServicePackage != null
+ && autofillServicePackage.equals(projectionPackage);
+ }
+
+ private final class SensitiveContentProtectionManagerServiceBinder
+ extends ISensitiveContentProtectionManager.Stub {
public void setSensitiveContentProtection(IBinder windowToken, String packageName,
boolean isShowingSensitiveContent) {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER,
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
index 2366f56..7aafa8e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceContentTest.java
@@ -24,9 +24,11 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.os.Binder;
@@ -72,6 +74,7 @@
@Mock private WindowManagerInternal mWindowManager;
@Mock private MediaProjectionManager mProjectionManager;
+ @Mock private PackageManagerInternal mPackageManagerInternal;
private MediaProjectionInfo mMediaProjectionInfo;
@Captor
@@ -91,7 +94,7 @@
mSensitiveContentProtectionManagerService =
new SensitiveContentProtectionManagerService(mContext);
mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
- new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
+ mPackageManagerInternal, new ArraySet<>(Set.of(mExemptedScreenRecorderPackage)));
verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());
mMediaPorjectionCallback = mMediaProjectionCallbackCaptor.getValue();
mMediaProjectionInfo =
@@ -146,6 +149,20 @@
}
@Test
+ public void testAutofillServicePackageExemption() {
+ String testAutofillService = mScreenRecorderPackage + "/com.example.SampleAutofillService";
+ int userId = Process.myUserHandle().getIdentifier();
+ Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.AUTOFILL_SERVICE, testAutofillService , userId);
+
+ mMediaPorjectionCallback.onStart(mMediaProjectionInfo);
+ mSensitiveContentProtectionManagerService.setSensitiveContentProtection(
+ mPackageInfo.getWindowToken(), mPackageInfo.getPkg(), mPackageInfo.getUid(), true);
+ verify(mWindowManager, never())
+ .addBlockScreenCaptureForApps(mPackageInfoCaptor.capture());
+ }
+
+ @Test
public void testDeveloperOptionDisableFeature() {
mockDisabledViaDeveloperOption();
mMediaProjectionCallbackCaptor.getValue().onStart(mMediaProjectionInfo);
diff --git a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
index e74fe29..5065144 100644
--- a/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/SensitiveContentProtectionManagerServiceNotificationTest.java
@@ -31,6 +31,7 @@
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import android.content.pm.PackageManagerInternal;
import android.media.projection.MediaProjectionInfo;
import android.media.projection.MediaProjectionManager;
import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -104,6 +105,9 @@
private WindowManagerInternal mWindowManager;
@Mock
+ private PackageManagerInternal mPackageManagerInternal;
+
+ @Mock
private StatusBarNotification mNotification1;
@Mock
@@ -141,7 +145,7 @@
setupSensitiveNotification();
mSensitiveContentProtectionManagerService.init(mProjectionManager, mWindowManager,
- new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));
+ mPackageManagerInternal, new ArraySet<>(Set.of(EXEMPTED_SCREEN_RECORDER_PACKAGE)));
// Obtain useful mMediaProjectionCallback
verify(mProjectionManager).addCallback(mMediaProjectionCallbackCaptor.capture(), any());