blob: a4e8b662ed5e078c6d76a8dc27d53f8f804ab896 [file] [log] [blame]
/*
* Copyright 2018 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.bluetooth.avrcp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.util.Log;
import java.util.List;
/**
* Native Interface to communicate with the JNI layer. This class should never be passed null
* data.
*/
public class AvrcpNativeInterface {
private static final String TAG = "AvrcpNativeInterface";
private static final boolean DEBUG = true;
private static AvrcpNativeInterface sInstance;
private AvrcpTargetService mAvrcpService;
static {
classInitNative();
}
static AvrcpNativeInterface getInterface() {
if (sInstance == null) {
sInstance = new AvrcpNativeInterface();
}
return sInstance;
}
void init(AvrcpTargetService service) {
d("Init AvrcpNativeInterface");
mAvrcpService = service;
initNative();
}
void cleanup() {
d("Cleanup AvrcpNativeInterface");
mAvrcpService = null;
cleanupNative();
}
Metadata getCurrentSongInfo() {
d("getCurrentSongInfo");
if (mAvrcpService == null) {
Log.w(TAG, "getCurrentSongInfo(): AvrcpTargetService is null");
return null;
}
return mAvrcpService.getCurrentSongInfo();
}
PlayStatus getPlayStatus() {
d("getPlayStatus");
if (mAvrcpService == null) {
Log.w(TAG, "getPlayStatus(): AvrcpTargetService is null");
return null;
}
return mAvrcpService.getPlayState();
}
void sendMediaKeyEvent(int keyEvent, boolean pushed) {
d("sendMediaKeyEvent: keyEvent=" + keyEvent + " pushed=" + pushed);
if (mAvrcpService == null) {
Log.w(TAG, "sendMediaKeyEvent(): AvrcpTargetService is null");
return;
}
mAvrcpService.sendMediaKeyEvent(keyEvent, pushed);
}
String getCurrentMediaId() {
d("getCurrentMediaId");
if (mAvrcpService == null) {
Log.w(TAG, "getMediaPlayerList(): AvrcpTargetService is null");
return "";
}
return mAvrcpService.getCurrentMediaId();
}
List<Metadata> getNowPlayingList() {
d("getNowPlayingList");
if (mAvrcpService == null) {
Log.w(TAG, "getMediaPlayerList(): AvrcpTargetService is null");
return null;
}
return mAvrcpService.getNowPlayingList();
}
int getCurrentPlayerId() {
d("getCurrentPlayerId");
if (mAvrcpService == null) {
Log.w(TAG, "getMediaPlayerList(): AvrcpTargetService is null");
return -1;
}
return mAvrcpService.getCurrentPlayerId();
}
List<PlayerInfo> getMediaPlayerList() {
d("getMediaPlayerList");
if (mAvrcpService == null) {
Log.w(TAG, "getMediaPlayerList(): AvrcpTargetService is null");
return null;
}
return mAvrcpService.getMediaPlayerList();
}
// TODO(apanicke): This shouldn't be named setBrowsedPlayer as it doesn't actually connect
// anything internally. It just returns the number of items in the root folder.
void setBrowsedPlayer(int playerId) {
d("setBrowsedPlayer: playerId=" + playerId);
mAvrcpService.getPlayerRoot(playerId, (a, b, c, d) ->
setBrowsedPlayerResponse(a, b, c, d));
}
void setBrowsedPlayerResponse(int playerId, boolean success, String rootId, int numItems) {
d("setBrowsedPlayerResponse: playerId=" + playerId
+ " success=" + success
+ " rootId=" + rootId
+ " numItems=" + numItems);
setBrowsedPlayerResponseNative(playerId, success, rootId, numItems);
}
void getFolderItemsRequest(int playerId, String mediaId) {
d("getFolderItemsRequest: playerId=" + playerId + " mediaId=" + mediaId);
mAvrcpService.getFolderItems(playerId, mediaId, (a, b) -> getFolderItemsResponse(a, b));
}
void getFolderItemsResponse(String parentId, List<ListItem> items) {
d("getFolderItemsResponse: parentId=" + parentId + " items.size=" + items.size());
getFolderItemsResponseNative(parentId, items);
}
void sendMediaUpdate(boolean metadata, boolean playStatus, boolean queue) {
d("sendMediaUpdate: metadata=" + metadata
+ " playStatus=" + playStatus
+ " queue=" + queue);
sendMediaUpdateNative(metadata, playStatus, queue);
}
void sendFolderUpdate(boolean availablePlayers, boolean addressedPlayers, boolean uids) {
d("sendFolderUpdate: availablePlayers=" + availablePlayers
+ " addressedPlayers=" + addressedPlayers
+ " uids=" + uids);
sendFolderUpdateNative(availablePlayers, addressedPlayers, uids);
}
void playItem(int playerId, boolean nowPlaying, String mediaId) {
d("playItem: playerId=" + playerId + " nowPlaying=" + nowPlaying + " mediaId" + mediaId);
if (mAvrcpService == null) {
Log.d(TAG, "playItem: AvrcpTargetService is null");
return;
}
mAvrcpService.playItem(playerId, nowPlaying, mediaId);
}
boolean connectDevice(String bdaddr) {
d("connectDevice: bdaddr=" + bdaddr);
return connectDeviceNative(bdaddr);
}
boolean disconnectDevice(String bdaddr) {
d("disconnectDevice: bdaddr=" + bdaddr);
return disconnectDeviceNative(bdaddr);
}
void setActiveDevice(String bdaddr) {
BluetoothDevice device =
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(bdaddr.toUpperCase());
d("setActiveDevice: device=" + device);
mAvrcpService.setActiveDevice(device);
}
void deviceConnected(String bdaddr, boolean absoluteVolume) {
BluetoothDevice device =
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(bdaddr.toUpperCase());
d("deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume);
if (mAvrcpService == null) {
Log.w(TAG, "deviceConnected: AvrcpTargetService is null");
return;
}
mAvrcpService.deviceConnected(device, absoluteVolume);
}
void deviceDisconnected(String bdaddr) {
BluetoothDevice device =
BluetoothAdapter.getDefaultAdapter().getRemoteDevice(bdaddr.toUpperCase());
d("deviceDisconnected: device=" + device);
if (mAvrcpService == null) {
Log.w(TAG, "deviceDisconnected: AvrcpTargetService is null");
return;
}
mAvrcpService.deviceDisconnected(device);
}
void sendVolumeChanged(int volume) {
d("sendVolumeChanged: volume=" + volume);
sendVolumeChangedNative(volume);
}
void setVolume(int volume) {
d("setVolume: volume=" + volume);
if (mAvrcpService == null) {
Log.w(TAG, "setVolume: AvrcpTargetService is null");
return;
}
mAvrcpService.setVolume(volume);
}
private static native void classInitNative();
private native void initNative();
private native void sendMediaUpdateNative(
boolean trackChanged, boolean playState, boolean playPos);
private native void sendFolderUpdateNative(
boolean availablePlayers, boolean addressedPlayers, boolean uids);
private native void setBrowsedPlayerResponseNative(
int playerId, boolean success, String rootId, int numItems);
private native void getFolderItemsResponseNative(String parentId, List<ListItem> list);
private native void cleanupNative();
private native boolean connectDeviceNative(String bdaddr);
private native boolean disconnectDeviceNative(String bdaddr);
private native void sendVolumeChangedNative(int volume);
private static void d(String msg) {
if (DEBUG) {
Log.d(TAG, msg);
}
}
}