Loading core/java/android/app/AppOpsManager.java +24 −11 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.database.DatabaseUtils; Loading Loading @@ -7617,7 +7618,7 @@ public class AppOpsManager { // Only collect app-ops when the proxy is trusted && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, myUid) == PackageManager.PERMISSION_GRANTED || isTrustedVoiceServiceProxy(mContext.getOpPackageName(), op))) { || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) { collectNotedOpSync(op, proxiedAttributionTag); } } Loading @@ -7628,31 +7629,43 @@ public class AppOpsManager { } } private boolean isTrustedVoiceServiceProxy(String packageName, int code) { /** * 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( mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceInteractionComponent = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE); context.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceRecognitionServicePackageName = getComponentPackageNameFromString(voiceRecognitionComponent); final String voiceInteractionServicePackageName = getComponentPackageNameFromString(voiceInteractionComponent); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) && (Objects.equals( voiceRecognitionServicePackageName, voiceInteractionServicePackageName) || voiceInteractionServicePackageName == null); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) && isPackagePreInstalled(context, packageName); } private String getComponentPackageNameFromString(String from) { private static String getComponentPackageNameFromString(String from) { ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null; return componentName != null ? componentName.getPackageName() : ""; } private static boolean isPackagePreInstalled(Context context, String packageName) { try { final PackageManager pm = context.getPackageManager(); final ApplicationInfo info = pm.getApplicationInfo(packageName, 0); return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0); } catch (PackageManager.NameNotFoundException e) { return false; } } /** * 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, Loading services/core/java/com/android/server/appop/AppOpsService.java +4 −26 Original line number Diff line number Diff line Loading @@ -94,7 +94,6 @@ import android.app.AsyncNotedAppOp; import android.app.RuntimeAppOpAccessMessage; import android.app.SyncNotedAppOp; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading Loading @@ -3018,29 +3017,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } private boolean isTrustedVoiceServiceProxy(String packageName, int code) { if (code != OP_RECORD_AUDIO) { return false; } final String voiceRecognitionComponent = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceInteractionComponent = Settings.Secure.getString( mContext.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) || voiceInteractionServicePackageName == null); } private String getComponentPackageNameFromString(String from) { ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null; return componentName != null ? componentName.getPackageName() : ""; } @Override public int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName, String proxiedAttributionTag, int proxyUid, String proxyPackageName, Loading @@ -3058,7 +3034,8 @@ public class AppOpsService extends IAppOpsService.Stub { // 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 = isTrustedVoiceServiceProxy(proxyPackageName, code); final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) Loading Loading @@ -3526,7 +3503,8 @@ public class AppOpsService extends IAppOpsService.Stub { // 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 = isTrustedVoiceServiceProxy(proxyPackageName, code); final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) Loading Loading
core/java/android/app/AppOpsManager.java +24 −11 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.database.DatabaseUtils; Loading Loading @@ -7617,7 +7618,7 @@ public class AppOpsManager { // Only collect app-ops when the proxy is trusted && (mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, myUid) == PackageManager.PERMISSION_GRANTED || isTrustedVoiceServiceProxy(mContext.getOpPackageName(), op))) { || isTrustedVoiceServiceProxy(mContext, mContext.getOpPackageName(), op))) { collectNotedOpSync(op, proxiedAttributionTag); } } Loading @@ -7628,31 +7629,43 @@ public class AppOpsManager { } } private boolean isTrustedVoiceServiceProxy(String packageName, int code) { /** * 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( mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceInteractionComponent = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE); context.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceRecognitionServicePackageName = getComponentPackageNameFromString(voiceRecognitionComponent); final String voiceInteractionServicePackageName = getComponentPackageNameFromString(voiceInteractionComponent); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) && (Objects.equals( voiceRecognitionServicePackageName, voiceInteractionServicePackageName) || voiceInteractionServicePackageName == null); return (Objects.equals(packageName, voiceRecognitionServicePackageName)) && isPackagePreInstalled(context, packageName); } private String getComponentPackageNameFromString(String from) { private static String getComponentPackageNameFromString(String from) { ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null; return componentName != null ? componentName.getPackageName() : ""; } private static boolean isPackagePreInstalled(Context context, String packageName) { try { final PackageManager pm = context.getPackageManager(); final ApplicationInfo info = pm.getApplicationInfo(packageName, 0); return ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0); } catch (PackageManager.NameNotFoundException e) { return false; } } /** * 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, Loading
services/core/java/com/android/server/appop/AppOpsService.java +4 −26 Original line number Diff line number Diff line Loading @@ -94,7 +94,6 @@ import android.app.AsyncNotedAppOp; import android.app.RuntimeAppOpAccessMessage; import android.app.SyncNotedAppOp; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading Loading @@ -3018,29 +3017,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } private boolean isTrustedVoiceServiceProxy(String packageName, int code) { if (code != OP_RECORD_AUDIO) { return false; } final String voiceRecognitionComponent = Settings.Secure.getString( mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE); final String voiceInteractionComponent = Settings.Secure.getString( mContext.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) || voiceInteractionServicePackageName == null); } private String getComponentPackageNameFromString(String from) { ComponentName componentName = from != null ? ComponentName.unflattenFromString(from) : null; return componentName != null ? componentName.getPackageName() : ""; } @Override public int noteProxyOperation(int code, int proxiedUid, String proxiedPackageName, String proxiedAttributionTag, int proxyUid, String proxyPackageName, Loading @@ -3058,7 +3034,8 @@ public class AppOpsService extends IAppOpsService.Stub { // 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 = isTrustedVoiceServiceProxy(proxyPackageName, code); final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) Loading Loading @@ -3526,7 +3503,8 @@ public class AppOpsService extends IAppOpsService.Stub { // 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 = isTrustedVoiceServiceProxy(proxyPackageName, code); final boolean isTrustVoiceServiceProxy = AppOpsManager.isTrustedVoiceServiceProxy(mContext, proxyPackageName, code); final boolean isSelfBlame = Binder.getCallingUid() == proxiedUid; final boolean isProxyTrusted = mContext.checkPermission( Manifest.permission.UPDATE_APP_OPS_STATS, -1, proxyUid) Loading