Loading services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java +28 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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); } Loading @@ -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. Loading @@ -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. } Loading Loading @@ -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. Loading @@ -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. } Loading @@ -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. } Loading services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java +58 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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; } } } services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java +8 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, Loading @@ -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. Loading Loading
services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerPerUserService.java +28 −16 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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); } Loading @@ -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. Loading @@ -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. } Loading Loading @@ -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. Loading @@ -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. } Loading @@ -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. } Loading
services/musicrecognition/java/com/android/server/musicrecognition/MusicRecognitionManagerService.java +58 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 { Loading @@ -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; } } }
services/musicrecognition/java/com/android/server/musicrecognition/RemoteMusicRecognitionService.java +8 −3 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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, Loading @@ -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. Loading