Fix content capture not being usable from hotword detector.

Bug: 194534612
Test: local repro
Change-Id: I58e5c68ea486b4da2f82b9d89440f86a8d507727
This commit is contained in:
Sergey Volnov
2021-07-24 00:38:10 +01:00
parent 6ad35a74d8
commit eacb8c8aee
3 changed files with 52 additions and 6 deletions

View File

@@ -70,6 +70,7 @@ import android.provider.Settings;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.IDataShareReadAdapter;
import android.service.voice.VoiceInteractionManagerInternal;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.Pair;
@@ -302,6 +303,37 @@ public final class ContentCaptureManagerService extends
|| super.isDisabledLocked(userId);
}
@Override
protected void assertCalledByPackageOwner(@NonNull String packageName) {
try {
super.assertCalledByPackageOwner(packageName);
} catch (SecurityException e) {
final int callingUid = Binder.getCallingUid();
VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity
hotwordDetectionServiceIdentity =
LocalServices.getService(VoiceInteractionManagerInternal.class)
.getHotwordDetectionServiceIdentity();
if (callingUid != hotwordDetectionServiceIdentity.getIsolatedUid()) {
super.assertCalledByPackageOwner(packageName);
return;
}
final String[] packages =
getContext()
.getPackageManager()
.getPackagesForUid(hotwordDetectionServiceIdentity.getOwnerUid());
if (packages != null) {
for (String candidate : packages) {
if (packageName.equals(candidate)) return; // Found it
}
}
throw e;
}
}
private boolean isDisabledBySettingsLocked(@UserIdInt int userId) {
return mDisabledBySettings != null && mDisabledBySettings.get(userId);
}

View File

@@ -57,6 +57,7 @@ import android.service.contentcapture.FlushMetrics;
import android.service.contentcapture.IContentCaptureServiceCallback;
import android.service.contentcapture.IDataShareCallback;
import android.service.contentcapture.SnapshotData;
import android.service.voice.VoiceInteractionManagerInternal;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
@@ -415,12 +416,25 @@ final class ContentCapturePerUserService
}
if (callingUid != packageUid && !LocalServices.getService(ActivityManagerInternal.class)
.hasRunningActivity(callingUid, packageName)) {
final String[] packages = pm.getPackagesForUid(callingUid);
final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
+ ") passed package (" + packageName + ") owned by UID " + packageUid);
throw new SecurityException("Invalid package: " + packageName);
VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity
hotwordDetectionServiceIdentity =
LocalServices.getService(VoiceInteractionManagerInternal.class)
.getHotwordDetectionServiceIdentity();
boolean isHotwordDetectionServiceCall =
hotwordDetectionServiceIdentity != null
&& callingUid == hotwordDetectionServiceIdentity.getIsolatedUid()
&& packageUid == hotwordDetectionServiceIdentity.getOwnerUid();
if (!isHotwordDetectionServiceCall) {
final String[] packages = pm.getPackagesForUid(callingUid);
final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
+ ") passed package (" + packageName + ") owned by UID " + packageUid);
throw new SecurityException("Invalid package: " + packageName);
}
}
}

View File

@@ -744,7 +744,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem
*
* @throws SecurityException when it's not...
*/
protected final void assertCalledByPackageOwner(@NonNull String packageName) {
protected void assertCalledByPackageOwner(@NonNull String packageName) {
Objects.requireNonNull(packageName);
final int uid = Binder.getCallingUid();
final String[] packages = getContext().getPackageManager().getPackagesForUid(uid);