blob: 99b4482114923365564bfa960858fce40ef691d7 [file] [log] [blame]
/*
* 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.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.media.AudioFormat;
import android.media.musicrecognition.IMusicRecognitionAttributionTagCallback;
import android.media.musicrecognition.IMusicRecognitionService;
import android.media.musicrecognition.MusicRecognitionService;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.text.format.DateUtils;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
import com.android.server.musicrecognition.MusicRecognitionManagerPerUserService.MusicRecognitionServiceCallback;
import java.util.concurrent.CompletableFuture;
/** Remote connection to an instance of {@link MusicRecognitionService}. */
public class RemoteMusicRecognitionService extends
AbstractMultiplePendingRequestsRemoteService<RemoteMusicRecognitionService,
IMusicRecognitionService> {
// Maximum time allotted for the remote service to return a result. Up to 24s of audio plus
// time to fingerprint and make rpcs.
private static final long TIMEOUT_IDLE_BIND_MILLIS = 40 * DateUtils.SECOND_IN_MILLIS;
// Allows the remote service to send back a result.
private final MusicRecognitionServiceCallback
mServerCallback;
public RemoteMusicRecognitionService(Context context, ComponentName serviceName,
int userId, MusicRecognitionManagerPerUserService perUserService,
MusicRecognitionServiceCallback callback,
boolean bindInstantServiceAllowed, boolean verbose) {
super(context, MusicRecognitionService.ACTION_MUSIC_SEARCH_LOOKUP, serviceName, userId,
perUserService,
context.getMainThreadHandler(),
// Prevents the service from having its permissions stripped while in background.
Context.BIND_INCLUDE_CAPABILITIES | (bindInstantServiceAllowed
? Context.BIND_ALLOW_INSTANT : 0), verbose,
/* initialCapacity= */ 1);
mServerCallback = callback;
}
@NonNull
@Override
protected IMusicRecognitionService getServiceInterface(@NonNull IBinder service) {
return IMusicRecognitionService.Stub.asInterface(service);
}
@Override
protected long getTimeoutIdleBindMillis() {
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.
*/
interface Callbacks extends VultureCallback<RemoteMusicRecognitionService> {}
/**
* Sends the given descriptor to the app's {@link MusicRecognitionService} to read the
* audio.
*/
public void onAudioStreamStarted(@NonNull ParcelFileDescriptor fd,
@NonNull AudioFormat audioFormat) {
scheduleAsyncRequest(
binder -> binder.onAudioStreamStarted(fd, audioFormat, mServerCallback));
}
/**
* Returns the name of the <attribution> tag defined in the remote service's manifest.
*/
public CompletableFuture<String> getAttributionTag() {
CompletableFuture<String> attributionTagFuture = new CompletableFuture<String>();
scheduleAsyncRequest(
binder -> binder.getAttributionTag(
new IMusicRecognitionAttributionTagCallback.Stub() {
@Override
public void onAttributionTag(String tag) throws RemoteException {
attributionTagFuture.complete(tag);
}
}));
return attributionTagFuture;
}
}