diff options
author | Nick Moukhine <oni@google.com> | 2020-11-23 14:33:08 +0100 |
---|---|---|
committer | Nick Moukhine <oni@google.com> | 2020-12-09 15:33:16 +0100 |
commit | e61ddcfc0a479b0383ee085c3650c205852d2869 (patch) | |
tree | eac339aef4ac83b5d8ace6f322c784d6a04b4ae0 | |
parent | e9cf1f984728f8a1c9f6a7ad0a35cee0c3f9fa61 (diff) |
Add shell commands MusicRecognitionService
The shell command allows a temporary override of the recognition service so I can substitute a stub in cts tests. Also add permission for the shell to be able to invoke the recognition api for the sake of cts tests.
Bug: 164439465
Test: new test in topic
Change-Id: I4a8de616a70f0d6504b2eaf486d5641cb7872607
5 files changed, 126 insertions, 2 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 71dbca0ac828..cc9d957be200 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -1771,6 +1771,7 @@ package android.content { field public static final String EUICC_CARD_SERVICE = "euicc_card"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String MEDIA_TRANSCODING_SERVICE = "media_transcoding"; + field public static final String MUSIC_RECOGNITION_SERVICE = "music_recognition"; field public static final String NETD_SERVICE = "netd"; field public static final String NETWORK_SCORE_SERVICE = "network_score"; field public static final String OEM_LOCK_SERVICE = "oem_lock"; diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 37e0a44bdd95..d56ebb3b6e46 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4536,6 +4536,7 @@ public abstract class Context { * @hide * @see #getSystemService(String) */ + @SystemApi public static final String MUSIC_RECOGNITION_SERVICE = "music_recognition"; /** diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java index e258ef009fb0..353151214823 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java @@ -113,7 +113,8 @@ public final class MusicRecognitionManagerPerUserService extends mRemoteService = new RemoteMusicRecognitionService(getContext(), serviceComponent, mUserId, this, - mRemoteServiceCallback, mMaster.isBindInstantServiceAllowed(), mMaster.verbose); + mRemoteServiceCallback, mMaster.isBindInstantServiceAllowed(), + mMaster.verbose); } return mRemoteService; @@ -167,7 +168,8 @@ public final class MusicRecognitionManagerPerUserService extends recognitionRequest.getIgnoreBeginningFrames() * BYTES_PER_SAMPLE; audioRecord.startRecording(); while (bytesRead >= 0 && totalBytesRead - < audioRecord.getBufferSizeInFrames() * BYTES_PER_SAMPLE) { + < audioRecord.getBufferSizeInFrames() * BYTES_PER_SAMPLE + && mRemoteService != null) { bytesRead = audioRecord.read(byteBuffer, 0, byteBuffer.length); if (bytesRead > 0) { totalBytesRead += bytesRead; @@ -215,6 +217,7 @@ public final class MusicRecognitionManagerPerUserService extends } catch (RemoteException ignored) { // Ignored. } + destroyService(); } @Override @@ -224,6 +227,7 @@ public final class MusicRecognitionManagerPerUserService extends } catch (RemoteException ignored) { // Ignored. } + destroyService(); } } @@ -235,6 +239,17 @@ public final class MusicRecognitionManagerPerUserService extends // Ignored. } Slog.w(TAG, "remote service died: " + service); + destroyService(); + } + + @GuardedBy("mLock") + private void destroyService() { + synchronized (mLock) { + if (mRemoteService != null) { + mRemoteService.destroy(); + mRemoteService = null; + } + } } /** Establishes an audio stream from the DSP audio source. */ diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java index b4cb33795878..9123daf0378a 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java @@ -16,6 +16,7 @@ package com.android.server.musicrecognition; +import static android.Manifest.permission.MANAGE_MUSIC_RECOGNITION; import static android.content.PermissionChecker.PERMISSION_GRANTED; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_SERVICE_UNAVAILABLE; @@ -28,11 +29,14 @@ import android.media.musicrecognition.RecognitionRequest; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; +import android.os.ResultReceiver; +import android.os.ShellCallback; import android.os.UserHandle; import com.android.server.infra.AbstractMasterSystemService; import com.android.server.infra.FrameworkResourcesServiceNameResolver; +import java.io.FileDescriptor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -45,6 +49,7 @@ public class MusicRecognitionManagerService extends MusicRecognitionManagerPerUserService> { private static final String TAG = MusicRecognitionManagerService.class.getSimpleName(); + private static final int MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS = 60_000; private MusicRecognitionManagerStub mMusicRecognitionManagerStub; final ExecutorService mExecutorService = Executors.newCachedThreadPool(); @@ -90,6 +95,16 @@ public class MusicRecognitionManagerService extends throw new SecurityException(msg); } + @Override + protected void enforceCallingPermissionForManagement() { + getContext().enforceCallingPermission(MANAGE_MUSIC_RECOGNITION, TAG); + } + + @Override + protected int getMaximumTemporaryServiceDurationMs() { + return MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS; + } + final class MusicRecognitionManagerStub extends IMusicRecognitionManager.Stub { @Override public void beginRecognition( @@ -112,5 +127,17 @@ public class MusicRecognitionManagerService extends } } } + + @Override + public void onShellCommand(@Nullable FileDescriptor in, + @Nullable FileDescriptor out, + @Nullable FileDescriptor err, + @NonNull String[] args, + @Nullable ShellCallback callback, + @NonNull ResultReceiver resultReceiver) throws RemoteException { + new MusicRecognitionManagerServiceShellCommand( + MusicRecognitionManagerService.this).exec(this, in, out, err, args, callback, + resultReceiver); + } } } diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerServiceShellCommand.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerServiceShellCommand.java new file mode 100644 index 000000000000..b020a243e454 --- /dev/null +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerServiceShellCommand.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 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.musicrecognition; + +import android.os.ShellCommand; + +import java.io.PrintWriter; + +/** Handles adb shell commands send to MusicRecognitionManagerService. */ +class MusicRecognitionManagerServiceShellCommand extends ShellCommand { + + private final MusicRecognitionManagerService mService; + + MusicRecognitionManagerServiceShellCommand(MusicRecognitionManagerService service) { + mService = service; + } + + @Override + public int onCommand(String cmd) { + if (cmd == null) { + return handleDefaultCommands(cmd); + } + final PrintWriter pw = getOutPrintWriter(); + if ("set".equals(cmd)) { + return requestSet(pw); + } + return handleDefaultCommands(cmd); + } + + private int requestSet(PrintWriter pw) { + final String what = getNextArgRequired(); + if ("temporary-service".equals(what)) { + return setTemporaryService(pw); + } + pw.println("Invalid set: " + what); + return -1; + } + + private int setTemporaryService(PrintWriter pw) { + final int userId = Integer.parseInt(getNextArgRequired()); + final String serviceName = getNextArg(); + if (serviceName == null) { + mService.resetTemporaryService(userId); + return 0; + } + final int duration = Integer.parseInt(getNextArgRequired()); + mService.setTemporaryService(userId, serviceName, duration); + pw.println("MusicRecognitionService temporarily set to " + serviceName + " for " + + duration + "ms"); + return 0; + } + + @Override + public void onHelp() { + try (PrintWriter pw = getOutPrintWriter();) { + pw.println("MusicRecognition Service (music_recognition) commands:"); + pw.println(" help"); + pw.println(" Prints this help text."); + pw.println(""); + pw.println(" set temporary-service USER_ID [COMPONENT_NAME DURATION]"); + pw.println(" Temporarily (for DURATION ms) changes the service implementation."); + pw.println(" To reset, call with just the USER_ID argument."); + pw.println(""); + } + } +} |