Merge "Re-add partial hotword indicator exemption" into udc-qpr-dev am: 47c5b71a46

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

Change-Id: Id886f13f05204857bf39f0aa32810fabf1163890
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Felix Oghina
2023-07-24 17:02:28 +00:00
committed by Automerger Merge Worker
3 changed files with 56 additions and 19 deletions

View File

@@ -27,6 +27,7 @@ import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPH
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH; import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__SERVICE_CRASH;
import android.app.AppOpsManager;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.compat.annotation.ChangeId; import android.compat.annotation.ChangeId;
@@ -548,13 +549,15 @@ final class HotwordDetectionConnection {
static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub { static final class SoundTriggerCallback extends IRecognitionStatusCallback.Stub {
private final HotwordDetectionConnection mHotwordDetectionConnection; private final HotwordDetectionConnection mHotwordDetectionConnection;
private final IHotwordRecognitionStatusCallback mExternalCallback; private final IHotwordRecognitionStatusCallback mExternalCallback;
private final int mVoiceInteractionServiceUid; private final Identity mVoiceInteractorIdentity;
private final Context mContext;
SoundTriggerCallback(IHotwordRecognitionStatusCallback callback, SoundTriggerCallback(Context context, IHotwordRecognitionStatusCallback callback,
HotwordDetectionConnection connection, int uid) { HotwordDetectionConnection connection, Identity voiceInteractorIdentity) {
mContext = context;
mHotwordDetectionConnection = connection; mHotwordDetectionConnection = connection;
mExternalCallback = callback; mExternalCallback = callback;
mVoiceInteractionServiceUid = uid; mVoiceInteractorIdentity = voiceInteractorIdentity;
} }
@Override @Override
@@ -568,17 +571,32 @@ final class HotwordDetectionConnection {
HotwordMetricsLogger.writeKeyphraseTriggerEvent( HotwordMetricsLogger.writeKeyphraseTriggerEvent(
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__TRUSTED_DETECTOR_DSP,
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER,
mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid);
mHotwordDetectionConnection.detectFromDspSource( mHotwordDetectionConnection.detectFromDspSource(
recognitionEvent, mExternalCallback); recognitionEvent, mExternalCallback);
} else {
// We have to attribute ops here, since we configure all st clients as trusted to
// enable a partial exemption.
// TODO (b/292012931) remove once trusted uniformly required.
int result = mContext.getSystemService(AppOpsManager.class)
.noteOpNoThrow(AppOpsManager.OP_RECORD_AUDIO_HOTWORD,
mVoiceInteractorIdentity.uid, mVoiceInteractorIdentity.packageName,
mVoiceInteractorIdentity.attributionTag,
"Non-HDS keyphrase recognition to VoiceInteractionService");
if (result != AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "onKeyphraseDetected suppressed, permission check returned: "
+ result);
mExternalCallback.onRecognitionPaused();
} else { } else {
HotwordMetricsLogger.writeKeyphraseTriggerEvent( HotwordMetricsLogger.writeKeyphraseTriggerEvent(
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__DETECTOR_TYPE__NORMAL_DETECTOR,
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER, HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__KEYPHRASE_TRIGGER,
mVoiceInteractionServiceUid); mVoiceInteractorIdentity.uid);
mExternalCallback.onKeyphraseDetected(recognitionEvent, null); mExternalCallback.onKeyphraseDetected(recognitionEvent, null);
} }
} }
}
@Override @Override
public void onGenericSoundTriggerDetected( public void onGenericSoundTriggerDetected(

View File

@@ -104,6 +104,7 @@ import com.android.server.SystemService;
import com.android.server.UiThread; import com.android.server.UiThread;
import com.android.server.pm.UserManagerInternal; import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.LegacyPermissionManagerInternal; import com.android.server.pm.permission.LegacyPermissionManagerInternal;
import com.android.server.policy.AppOpsPolicy;
import com.android.server.utils.Slogf; import com.android.server.utils.Slogf;
import com.android.server.utils.TimingsTraceAndSlog; import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.ActivityTaskManagerInternal; import com.android.server.wm.ActivityTaskManagerInternal;
@@ -336,6 +337,9 @@ public class VoiceInteractionManagerService extends SystemService {
/** The start value of showSessionId */ /** The start value of showSessionId */
private static final int SHOW_SESSION_START_ID = 0; private static final int SHOW_SESSION_START_ID = 0;
private final boolean IS_HDS_REQUIRED = AppOpsPolicy.isHotwordDetectionServiceRequired(
mContext.getPackageManager());
@GuardedBy("this") @GuardedBy("this")
private int mShowSessionId = SHOW_SESSION_START_ID; private int mShowSessionId = SHOW_SESSION_START_ID;
@@ -393,8 +397,14 @@ public class VoiceInteractionManagerService extends SystemService {
} }
try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect( try (SafeCloseable ignored = PermissionUtil.establishIdentityDirect(
originatorIdentity)) { originatorIdentity)) {
if (!IS_HDS_REQUIRED) {
// For devices which still have hotword exemption, any client (not just HDS
// clients) are trusted.
// TODO (b/292012931) remove once trusted uniformly required.
forHotwordDetectionService = true;
}
return new SoundTriggerSession(mSoundTriggerInternal.attach(client, return new SoundTriggerSession(mSoundTriggerInternal.attach(client,
moduleProperties, forHotwordDetectionService)); moduleProperties, forHotwordDetectionService), originatorIdentity);
} }
} }
@@ -1674,10 +1684,13 @@ public class VoiceInteractionManagerService extends SystemService {
final SoundTriggerInternal.Session mSession; final SoundTriggerInternal.Session mSession;
private IHotwordRecognitionStatusCallback mSessionExternalCallback; private IHotwordRecognitionStatusCallback mSessionExternalCallback;
private IRecognitionStatusCallback mSessionInternalCallback; private IRecognitionStatusCallback mSessionInternalCallback;
private final Identity mVoiceInteractorIdentity;
SoundTriggerSession( SoundTriggerSession(
SoundTriggerInternal.Session session) { SoundTriggerInternal.Session session,
Identity voiceInteractorIdentity) {
mSession = session; mSession = session;
mVoiceInteractorIdentity = voiceInteractorIdentity;
} }
@Override @Override
@@ -1731,7 +1744,8 @@ public class VoiceInteractionManagerService extends SystemService {
if (mSessionExternalCallback == null if (mSessionExternalCallback == null
|| mSessionInternalCallback == null || mSessionInternalCallback == null
|| callback.asBinder() != mSessionExternalCallback.asBinder()) { || callback.asBinder() != mSessionExternalCallback.asBinder()) {
mSessionInternalCallback = createSoundTriggerCallbackLocked(callback); mSessionInternalCallback = createSoundTriggerCallbackLocked(callback,
mVoiceInteractorIdentity);
mSessionExternalCallback = callback; mSessionExternalCallback = callback;
} }
} }
@@ -1752,7 +1766,8 @@ public class VoiceInteractionManagerService extends SystemService {
if (mSessionExternalCallback == null if (mSessionExternalCallback == null
|| mSessionInternalCallback == null || mSessionInternalCallback == null
|| callback.asBinder() != mSessionExternalCallback.asBinder()) { || callback.asBinder() != mSessionExternalCallback.asBinder()) {
soundTriggerCallback = createSoundTriggerCallbackLocked(callback); soundTriggerCallback = createSoundTriggerCallbackLocked(callback,
mVoiceInteractorIdentity);
Slog.w(TAG, "stopRecognition() called with a different callback than" Slog.w(TAG, "stopRecognition() called with a different callback than"
+ "startRecognition()"); + "startRecognition()");
} else { } else {
@@ -2090,6 +2105,7 @@ public class VoiceInteractionManagerService extends SystemService {
pw.println(" mTemporarilyDisabled: " + mTemporarilyDisabled); pw.println(" mTemporarilyDisabled: " + mTemporarilyDisabled);
pw.println(" mCurUser: " + mCurUser); pw.println(" mCurUser: " + mCurUser);
pw.println(" mCurUserSupported: " + mCurUserSupported); pw.println(" mCurUserSupported: " + mCurUserSupported);
pw.println(" mIsHdsRequired: " + IS_HDS_REQUIRED);
dumpSupportedUsers(pw, " "); dumpSupportedUsers(pw, " ");
mDbHelper.dump(pw); mDbHelper.dump(pw);
if (mImpl == null) { if (mImpl == null) {
@@ -2165,11 +2181,13 @@ public class VoiceInteractionManagerService extends SystemService {
} }
private IRecognitionStatusCallback createSoundTriggerCallbackLocked( private IRecognitionStatusCallback createSoundTriggerCallbackLocked(
IHotwordRecognitionStatusCallback callback) { IHotwordRecognitionStatusCallback callback,
Identity voiceInteractorIdentity) {
if (mImpl == null) { if (mImpl == null) {
return null; return null;
} }
return mImpl.createSoundTriggerCallbackLocked(callback); return mImpl.createSoundTriggerCallbackLocked(mContext, callback,
voiceInteractorIdentity);
} }
class RoleObserver implements OnRoleHoldersChangedListener { class RoleObserver implements OnRoleHoldersChangedListener {

View File

@@ -877,12 +877,13 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
} }
public IRecognitionStatusCallback createSoundTriggerCallbackLocked( public IRecognitionStatusCallback createSoundTriggerCallbackLocked(
IHotwordRecognitionStatusCallback callback) { Context context, IHotwordRecognitionStatusCallback callback,
Identity voiceInteractorIdentity) {
if (DEBUG) { if (DEBUG) {
Slog.d(TAG, "createSoundTriggerCallbackLocked"); Slog.d(TAG, "createSoundTriggerCallbackLocked");
} }
return new HotwordDetectionConnection.SoundTriggerCallback(callback, return new HotwordDetectionConnection.SoundTriggerCallback(context, callback,
mHotwordDetectionConnection, mInfo.getServiceInfo().applicationInfo.uid); mHotwordDetectionConnection, voiceInteractorIdentity);
} }
private static ServiceInfo getServiceInfoLocked(@NonNull ComponentName componentName, private static ServiceInfo getServiceInfoLocked(@NonNull ComponentName componentName,