diff options
author | Nick Moukhine <oni@google.com> | 2021-01-11 09:12:25 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-01-11 09:12:25 +0000 |
commit | 9dcb0d78bafdd20c245000024434f078a292a70f (patch) | |
tree | df4094a622d4f82769ee7827ad7febeb26fdf220 | |
parent | 21538ffb1082a1c236a76dbf124fbb649a39253a (diff) | |
parent | 5b7c195b0d4c18981f1d2c49bf12200cdc0240d6 (diff) |
Merge "Follow-up fixes to MusicRecognitionManagerService"
3 files changed, 94 insertions, 21 deletions
diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java index 353151214823..0cb729d924b4 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java @@ -16,6 +16,7 @@ package com.android.server.musicrecognition; +import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_AUDIO_UNAVAILABLE; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_SERVICE_KILLED; import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION_FAILED_SERVICE_UNAVAILABLE; import static android.media.musicrecognition.MusicRecognitionManager.RecognitionFailureCode; @@ -64,10 +65,6 @@ public final class MusicRecognitionManagerPerUserService extends @GuardedBy("mLock") private RemoteMusicRecognitionService mRemoteService; - private MusicRecognitionServiceCallback mRemoteServiceCallback = - new MusicRecognitionServiceCallback(); - private IMusicRecognitionManagerCallback mCallback; - MusicRecognitionManagerPerUserService( @NonNull MusicRecognitionManagerService primary, @NonNull Object lock, int userId) { @@ -100,7 +97,8 @@ public final class MusicRecognitionManagerPerUserService extends @GuardedBy("mLock") @Nullable - private RemoteMusicRecognitionService ensureRemoteServiceLocked() { + private RemoteMusicRecognitionService ensureRemoteServiceLocked( + IMusicRecognitionManagerCallback clientCallback) { if (mRemoteService == null) { final String serviceName = getComponentNameLocked(); if (serviceName == null) { @@ -113,7 +111,8 @@ public final class MusicRecognitionManagerPerUserService extends mRemoteService = new RemoteMusicRecognitionService(getContext(), serviceComponent, mUserId, this, - mRemoteServiceCallback, mMaster.isBindInstantServiceAllowed(), + new MusicRecognitionServiceCallback(clientCallback), + mMaster.isBindInstantServiceAllowed(), mMaster.verbose); } @@ -130,13 +129,14 @@ public final class MusicRecognitionManagerPerUserService extends @NonNull IBinder callback) { int maxAudioLengthSeconds = Math.min(recognitionRequest.getMaxAudioLengthSeconds(), MAX_STREAMING_SECONDS); - mCallback = IMusicRecognitionManagerCallback.Stub.asInterface(callback); + IMusicRecognitionManagerCallback clientCallback = + IMusicRecognitionManagerCallback.Stub.asInterface(callback); AudioRecord audioRecord = createAudioRecord(recognitionRequest, maxAudioLengthSeconds); - mRemoteService = ensureRemoteServiceLocked(); + mRemoteService = ensureRemoteServiceLocked(clientCallback); if (mRemoteService == null) { try { - mCallback.onRecognitionFailed( + clientCallback.onRecognitionFailed( RECOGNITION_FAILED_SERVICE_UNAVAILABLE); } catch (RemoteException e) { // Ignored. @@ -147,7 +147,8 @@ public final class MusicRecognitionManagerPerUserService extends Pair<ParcelFileDescriptor, ParcelFileDescriptor> clientPipe = createPipe(); if (clientPipe == null) { try { - mCallback.onAudioStreamClosed(); + clientCallback.onRecognitionFailed( + RECOGNITION_FAILED_AUDIO_UNAVAILABLE); } catch (RemoteException ignored) { // Ignored. } @@ -192,11 +193,10 @@ public final class MusicRecognitionManagerPerUserService extends } finally { audioRecord.release(); try { - mCallback.onAudioStreamClosed(); + clientCallback.onAudioStreamClosed(); } catch (RemoteException ignored) { // Ignored. } - } }); // Send the pipe down to the lookup service while we write to it asynchronously. @@ -207,13 +207,20 @@ public final class MusicRecognitionManagerPerUserService extends * Callback invoked by {@link android.service.musicrecognition.MusicRecognitionService} to pass * back the music search result. */ - private final class MusicRecognitionServiceCallback extends + final class MusicRecognitionServiceCallback extends IMusicRecognitionServiceCallback.Stub { + + private final IMusicRecognitionManagerCallback mClientCallback; + + private MusicRecognitionServiceCallback(IMusicRecognitionManagerCallback clientCallback) { + mClientCallback = clientCallback; + } + @Override public void onRecognitionSucceeded(MediaMetadata result, Bundle extras) { try { sanitizeBundle(extras); - mCallback.onRecognitionSucceeded(result, extras); + mClientCallback.onRecognitionSucceeded(result, extras); } catch (RemoteException ignored) { // Ignored. } @@ -223,18 +230,23 @@ public final class MusicRecognitionManagerPerUserService extends @Override public void onRecognitionFailed(@RecognitionFailureCode int failureCode) { try { - mCallback.onRecognitionFailed(failureCode); + mClientCallback.onRecognitionFailed(failureCode); } catch (RemoteException ignored) { // Ignored. } destroyService(); } + + private IMusicRecognitionManagerCallback getClientCallback() { + return mClientCallback; + } } @Override public void onServiceDied(@NonNull RemoteMusicRecognitionService service) { try { - mCallback.onRecognitionFailed(RECOGNITION_FAILED_SERVICE_KILLED); + service.getServerCallback().getClientCallback().onRecognitionFailed( + RECOGNITION_FAILED_SERVICE_KILLED); } catch (RemoteException e) { // Ignored. } diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java index 9123daf0378a..38f43138aee0 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java @@ -22,7 +22,9 @@ import static android.media.musicrecognition.MusicRecognitionManager.RECOGNITION import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.ComponentName; import android.content.Context; +import android.content.pm.PackageManager; import android.media.musicrecognition.IMusicRecognitionManager; import android.media.musicrecognition.IMusicRecognitionManagerCallback; import android.media.musicrecognition.RecognitionRequest; @@ -32,7 +34,9 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; +import android.util.Slog; +import com.android.internal.annotations.GuardedBy; import com.android.server.infra.AbstractMasterSystemService; import com.android.server.infra.FrameworkResourcesServiceNameResolver; @@ -113,9 +117,11 @@ public class MusicRecognitionManagerService extends enforceCaller("beginRecognition"); synchronized (mLock) { + int userId = UserHandle.getCallingUserId(); final MusicRecognitionManagerPerUserService service = getServiceForUserLocked( - UserHandle.getCallingUserId()); - if (service != null) { + userId); + if (service != null && (isDefaultServiceLocked(userId) + || isCalledByServiceAppLocked("beginRecognition"))) { service.beginRecognitionLocked(recognitionRequest, callback); } else { try { @@ -139,5 +145,55 @@ public class MusicRecognitionManagerService extends MusicRecognitionManagerService.this).exec(this, in, out, err, args, callback, resultReceiver); } + + /** True if the currently set handler service is not overridden by the shell. */ + @GuardedBy("mLock") + private boolean isDefaultServiceLocked(int userId) { + final String defaultServiceName = mServiceNameResolver.getDefaultServiceName(userId); + if (defaultServiceName == null) { + return false; + } + + final String currentServiceName = mServiceNameResolver.getServiceName(userId); + return defaultServiceName.equals(currentServiceName); + } + + /** True if the caller of the api is the same app which hosts the default service. */ + @GuardedBy("mLock") + private boolean isCalledByServiceAppLocked(@NonNull String methodName) { + final int userId = UserHandle.getCallingUserId(); + final int callingUid = Binder.getCallingUid(); + final String serviceName = mServiceNameResolver.getServiceName(userId); + if (serviceName == null) { + Slog.e(TAG, methodName + ": called by UID " + callingUid + + ", but there's no service set for user " + userId); + return false; + } + + final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); + if (serviceComponent == null) { + Slog.w(TAG, methodName + ": invalid service name: " + serviceName); + return false; + } + + final String servicePackageName = serviceComponent.getPackageName(); + + final PackageManager pm = getContext().getPackageManager(); + final int serviceUid; + try { + serviceUid = pm.getPackageUidAsUser(servicePackageName, + UserHandle.getCallingUserId()); + } catch (PackageManager.NameNotFoundException e) { + Slog.w(TAG, methodName + ": could not verify UID for " + serviceName); + return false; + } + if (callingUid != serviceUid) { + Slog.e(TAG, methodName + ": called by UID " + callingUid + ", but service UID is " + + serviceUid); + return false; + } + + return true; + } } } diff --git a/services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java b/services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java index 4814a821d525..6c7d673ffe11 100644 --- a/services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java +++ b/services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java @@ -21,13 +21,13 @@ import android.content.ComponentName; import android.content.Context; import android.media.AudioFormat; import android.media.musicrecognition.IMusicRecognitionService; -import android.media.musicrecognition.IMusicRecognitionServiceCallback; import android.media.musicrecognition.MusicRecognitionService; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.text.format.DateUtils; import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService; +import com.android.server.musicrecognition.MusicRecognitionManagerPerUserService.MusicRecognitionServiceCallback; /** Remote connection to an instance of {@link MusicRecognitionService}. */ public class RemoteMusicRecognitionService extends @@ -39,11 +39,12 @@ public class RemoteMusicRecognitionService extends private static final long TIMEOUT_IDLE_BIND_MILLIS = 40 * DateUtils.SECOND_IN_MILLIS; // Allows the remote service to send back a result. - private final IMusicRecognitionServiceCallback mServerCallback; + private final MusicRecognitionServiceCallback + mServerCallback; public RemoteMusicRecognitionService(Context context, ComponentName serviceName, int userId, MusicRecognitionManagerPerUserService perUserService, - IMusicRecognitionServiceCallback callback, + MusicRecognitionServiceCallback callback, boolean bindInstantServiceAllowed, boolean verbose) { super(context, MusicRecognitionService.ACTION_MUSIC_SEARCH_LOOKUP, serviceName, userId, perUserService, @@ -66,6 +67,10 @@ public class RemoteMusicRecognitionService extends return TIMEOUT_IDLE_BIND_MILLIS; } + MusicRecognitionServiceCallback getServerCallback() { + return mServerCallback; + } + /** * Required, but empty since we don't need to notify the callback implementation of the request * results. |