Merge "Allow voice recognition service to blame other apps access." into rvc-qpr-dev am: 5a9a2bc30d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13026536

Change-Id: Ibe30e7c3a8c7d21c17d16c71ca43f2a9a59f9cae
This commit is contained in:
Joanne Chung
2020-11-11 06:44:56 +00:00
committed by Automerger Merge Worker
2 changed files with 42 additions and 3 deletions

View File

@@ -31,6 +31,7 @@ import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -52,6 +53,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongSparseArray;
@@ -7610,8 +7612,9 @@ public class AppOpsManager {
collectNotedOpForSelf(op, proxiedAttributionTag);
} else if (collectionMode == COLLECT_SYNC
// Only collect app-ops when the proxy is trusted
&& mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
myUid) == PackageManager.PERMISSION_GRANTED) {
&& (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
myUid) == PackageManager.PERMISSION_GRANTED
|| isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) {
collectNotedOpSync(op, proxiedAttributionTag);
}
}
@@ -7622,6 +7625,38 @@ public class AppOpsManager {
}
}
/**
* Checks if the voice recognition service is a trust proxy.
*
* @return {@code true} if the package is a trust voice recognition service proxy
* @hide
*/
public static boolean isTrustedVoiceServiceProxy(Context context, String packageName,
int code) {
// This is a workaround for R QPR, new API change is not allowed. We only allow the current
// voice recognizer is also the voice interactor to noteproxy op.
if (code != OP_RECORD_AUDIO) {
return false;
}
final String voiceRecognitionComponent = Settings.Secure.getString(
context.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
final String voiceInteractionComponent = Settings.Secure.getString(
context.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
final String voiceRecognitionServicePackageName =
getComponentPackagenameFromString(voiceRecognitionComponent);
final String voiceInteractionServicePackageName =
getComponentPackagenameFromString(voiceInteractionComponent);
return Objects.equals(packageName, voiceRecognitionServicePackageName) && Objects.equals(
voiceRecognitionServicePackageName, voiceInteractionServicePackageName);
}
private static String getComponentPackagenameFromString(String from) {
ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null;
return componentName != null ? componentName.getPackageName() : "";
}
/**
* Do a quick check for whether an application might be able to perform an operation.
* This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,

View File

@@ -2989,9 +2989,13 @@ public class AppOpsService extends IAppOpsService.Stub {
return AppOpsManager.MODE_IGNORED;
}
// This is a workaround for R QPR, new API change is not allowed. We only allow the current
// voice recognizer is also the voice interactor to noteproxy op.
final boolean isTrustVoiceServiceProxy =
AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code);
final boolean isProxyTrusted = mContext.checkPermission(
Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid)
== PackageManager.PERMISSION_GRANTED;
== PackageManager.PERMISSION_GRANTED || isTrustVoiceServiceProxy;
final int proxyFlags = isProxyTrusted ? AppOpsManager.OP_FLAG_TRUSTED_PROXY
: AppOpsManager.OP_FLAG_UNTRUSTED_PROXY;