summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Moukhine <oni@google.com>2020-11-23 14:33:08 +0100
committerNick Moukhine <oni@google.com>2020-12-09 15:33:16 +0100
commite61ddcfc0a479b0383ee085c3650c205852d2869 (patch)
treeeac339aef4ac83b5d8ace6f322c784d6a04b4ae0
parente9cf1f984728f8a1c9f6a7ad0a35cee0c3f9fa61 (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
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/java/android/content/Context.java1
-rw-r--r--services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java19
-rw-r--r--services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java27
-rw-r--r--services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerServiceShellCommand.java80
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("");
+ }
+ }
+}