diff options
5 files changed, 0 insertions, 253 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 11bc5a851161..88f9aff4a336 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -13507,7 +13507,6 @@ package android.service.voice { method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.HotwordDetector createHotwordDetector(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.HotwordDetector.Callback); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_VOICE_KEYPHRASES) public final android.media.voice.KeyphraseModelManager createKeyphraseModelManager(); method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public final android.service.voice.VisualQueryDetector createVisualQueryDetector(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory, @NonNull java.util.concurrent.Executor, @NonNull android.service.voice.VisualQueryDetector.Callback); - method @FlaggedApi("android.service.voice.flags.allow_training_data_egress_from_hds") @RequiresPermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) public void setShouldReceiveSandboxedTrainingData(boolean); } } diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java index 44bcdbe28cd5..20adc5427495 100644 --- a/core/java/android/service/voice/VoiceInteractionService.java +++ b/core/java/android/service/voice/VoiceInteractionService.java @@ -18,7 +18,6 @@ package android.service.voice; import android.Manifest; import android.annotation.CallbackExecutor; -import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -49,7 +48,6 @@ import android.os.ServiceManager; import android.os.SharedMemory; import android.os.SystemProperties; import android.provider.Settings; -import android.service.voice.flags.Flags; import android.util.ArraySet; import android.util.Log; @@ -1011,36 +1009,6 @@ public class VoiceInteractionService extends Service { } /** - * Allow/disallow receiving training data from trusted process. - * - * <p> This method can be called by a preinstalled assistant to receive/stop receiving - * training data via {@link HotwordDetector.Callback#onTrainingData(HotwordTrainingData)}. - * These training data events are produced during sandboxed detection (in trusted process). - * - * @param allowed whether to allow/disallow receiving training data produced during - * sandboxed detection (from trusted process). - * @throws SecurityException if caller is not a preinstalled assistant or if caller is not the - * active assistant. - * - * @hide - */ - //TODO(b/315053245): Add mitigations to make API no-op once user has modified setting. - @SystemApi - @FlaggedApi(Flags.FLAG_ALLOW_TRAINING_DATA_EGRESS_FROM_HDS) - @RequiresPermission(Manifest.permission.MANAGE_HOTWORD_DETECTION) - public void setShouldReceiveSandboxedTrainingData(boolean allowed) { - Log.i(TAG, "setShouldReceiveSandboxedTrainingData to " + allowed); - if (mSystemService == null) { - throw new IllegalStateException("Not available until onReady() is called"); - } - try { - mSystemService.setShouldReceiveSandboxedTrainingData(allowed); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Creates an {@link KeyphraseModelManager} to use for enrolling voice models outside of the * pre-bundled system voice models. * @hide diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl index 31ccf6d6dc1d..314ed69cb885 100644 --- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl +++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl @@ -382,14 +382,4 @@ interface IVoiceInteractionManagerService { oneway void notifyActivityEventChanged( in IBinder activityToken, int type); - - /** - * Allows/disallows receiving training data from trusted process. - * Caller must be the active assistant and a preinstalled assistant. - * - * @param allowed whether to allow/disallow receiving training data produced during - * sandboxed detection (from trusted process). - */ - @EnforcePermission("MANAGE_HOTWORD_DETECTION") - void setShouldReceiveSandboxedTrainingData(boolean allowed); } diff --git a/services/tests/voiceinteractiontests/src/com/android/server/voiceinteraction/SetSandboxedTrainingDataAllowedTest.java b/services/tests/voiceinteractiontests/src/com/android/server/voiceinteraction/SetSandboxedTrainingDataAllowedTest.java deleted file mode 100644 index 159c760992c6..000000000000 --- a/services/tests/voiceinteractiontests/src/com/android/server/voiceinteraction/SetSandboxedTrainingDataAllowedTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.voiceinteraction; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; - -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assert.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import android.Manifest; -import android.app.ActivityManagerInternal; -import android.app.AppOpsManager; -import android.app.role.RoleManager; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.os.PermissionEnforcer; -import android.os.Process; -import android.os.test.FakePermissionEnforcer; -import android.platform.test.annotations.Presubmit; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.SmallTest; - -import com.android.modules.utils.testing.ExtendedMockitoRule; -import com.android.server.LocalServices; -import com.android.server.pm.UserManagerInternal; -import com.android.server.pm.permission.LegacyPermissionManagerInternal; -import com.android.server.pm.permission.PermissionManagerServiceInternal; -import com.android.server.wm.ActivityTaskManagerInternal; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.quality.Strictness; - -@SmallTest -@Presubmit -@RunWith(AndroidJUnit4.class) -public class SetSandboxedTrainingDataAllowedTest { - - @Captor private ArgumentCaptor<Integer> mOpIdCaptor, mUidCaptor, mOpModeCaptor; - - @Mock - private AppOpsManager mAppOpsManager; - - @Mock - private VoiceInteractionManagerServiceImpl mVoiceInteractionManagerServiceImpl; - - private FakePermissionEnforcer mPermissionEnforcer = new FakePermissionEnforcer(); - - private Context mContext; - - private VoiceInteractionManagerService mVoiceInteractionManagerService; - private VoiceInteractionManagerService.VoiceInteractionManagerServiceStub - mVoiceInteractionManagerServiceStub; - - private ApplicationInfo mApplicationInfo = new ApplicationInfo(); - - @Rule - public final ExtendedMockitoRule mExtendedMockitoRule = - new ExtendedMockitoRule.Builder(this) - .setStrictness(Strictness.WARN) - .mockStatic(LocalServices.class) - .mockStatic(PermissionEnforcer.class) - .build(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = spy(ApplicationProvider.getApplicationContext()); - - doReturn(mPermissionEnforcer).when(() -> PermissionEnforcer.fromContext(any())); - doReturn(mock(PermissionManagerServiceInternal.class)).when( - () -> LocalServices.getService(PermissionManagerServiceInternal.class)); - doReturn(mock(ActivityManagerInternal.class)).when( - () -> LocalServices.getService(ActivityManagerInternal.class)); - doReturn(mock(UserManagerInternal.class)).when( - () -> LocalServices.getService(UserManagerInternal.class)); - doReturn(mock(ActivityTaskManagerInternal.class)).when( - () -> LocalServices.getService(ActivityTaskManagerInternal.class)); - doReturn(mock(LegacyPermissionManagerInternal.class)).when( - () -> LocalServices.getService(LegacyPermissionManagerInternal.class)); - doReturn(mock(RoleManager.class)).when(mContext).getSystemService(RoleManager.class); - doReturn(mAppOpsManager).when(mContext).getSystemService(Context.APP_OPS_SERVICE); - doReturn(mApplicationInfo).when(mVoiceInteractionManagerServiceImpl).getApplicationInfo(); - - mVoiceInteractionManagerService = new VoiceInteractionManagerService(mContext); - mVoiceInteractionManagerServiceStub = - mVoiceInteractionManagerService.new VoiceInteractionManagerServiceStub(); - mVoiceInteractionManagerServiceStub.mImpl = mVoiceInteractionManagerServiceImpl; - mPermissionEnforcer.grant(Manifest.permission.MANAGE_HOTWORD_DETECTION); - } - - @Test - public void setShouldReceiveSandboxedTrainingData_currentAndPreinstalledAssistant_setsOp() { - // Set application info so current app is the current and preinstalled assistant. - mApplicationInfo.uid = Process.myUid(); - mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - - mVoiceInteractionManagerServiceStub.setShouldReceiveSandboxedTrainingData( - /* allowed= */ true); - - verify(mAppOpsManager).setUidMode(mOpIdCaptor.capture(), mUidCaptor.capture(), - mOpModeCaptor.capture()); - assertThat(mOpIdCaptor.getValue()).isEqualTo( - AppOpsManager.OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA); - assertThat(mOpModeCaptor.getValue()).isEqualTo(AppOpsManager.MODE_ALLOWED); - assertThat(mUidCaptor.getValue()).isEqualTo(Process.myUid()); - } - - @Test - public void setShouldReceiveSandboxedTrainingData_missingPermission_doesNotSetOp() { - // Set application info so current app is the current and preinstalled assistant. - mApplicationInfo.uid = Process.myUid(); - mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - - // Simulate missing MANAGE_HOTWORD_DETECTION permission. - mPermissionEnforcer.revoke(Manifest.permission.MANAGE_HOTWORD_DETECTION); - - assertThrows(SecurityException.class, - () -> mVoiceInteractionManagerServiceStub.setShouldReceiveSandboxedTrainingData( - /* allowed= */ true)); - - verify(mAppOpsManager, never()).setUidMode(anyInt(), anyInt(), anyInt()); - } - - @Test - public void setShouldReceiveSandboxedTrainingData_notPreinstalledAssistant_doesNotSetOp() { - // Set application info so current app is not preinstalled assistant. - mApplicationInfo.uid = Process.myUid(); - mApplicationInfo.flags = ApplicationInfo.FLAG_INSTALLED; // Does not contain FLAG_SYSTEM. - - assertThrows(SecurityException.class, - () -> mVoiceInteractionManagerServiceStub.setShouldReceiveSandboxedTrainingData( - /* allowed= */ true)); - - verify(mAppOpsManager, never()).setUidMode(anyInt(), anyInt(), anyInt()); - } - - @Test - public void setShouldReceiveSandboxedTrainingData_notCurrentAssistant_doesNotSetOp() { - // Set application info so current app is not current assistant. - mApplicationInfo.uid = Process.SHELL_UID; // Set current assistant uid to shell UID. - mApplicationInfo.flags = ApplicationInfo.FLAG_SYSTEM; - - assertThrows(SecurityException.class, - () -> mVoiceInteractionManagerServiceStub.setShouldReceiveSandboxedTrainingData( - /* allowed= */ true)); - - verify(mAppOpsManager, never()).setUidMode(anyInt(), anyInt(), anyInt()); - } -} diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index 952a24f20fc0..4cdec705bb6c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -18,14 +18,12 @@ package com.android.server.voiceinteraction; import android.Manifest; import android.annotation.CallbackExecutor; -import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AppGlobals; -import android.app.AppOpsManager; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.content.ComponentName; @@ -1544,34 +1542,6 @@ public class VoiceInteractionManagerService extends SystemService { } } - @Override - @EnforcePermission(android.Manifest.permission.MANAGE_HOTWORD_DETECTION) - public void setShouldReceiveSandboxedTrainingData(boolean allowed) { - super.setShouldReceiveSandboxedTrainingData_enforcePermission(); - - synchronized (this) { - if (mImpl == null) { - throw new IllegalStateException( - "setShouldReceiveSandboxedTrainingData without running voice " - + "interaction service"); - } - - enforceIsCallerPreinstalledAssistant(); - - int callingUid = Binder.getCallingUid(); - final long caller = Binder.clearCallingIdentity(); - try { - AppOpsManager appOpsManager = (AppOpsManager) - mContext.getSystemService(Context.APP_OPS_SERVICE); - appOpsManager.setUidMode( - AppOpsManager.OP_RECEIVE_SANDBOXED_DETECTION_TRAINING_DATA, - callingUid, allowed ? AppOpsManager.MODE_ALLOWED : - AppOpsManager.MODE_ERRORED); - } finally { - Binder.restoreCallingIdentity(caller); - } - } - } //----------------- Model management APIs --------------------------------// |