1702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal/* 2702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * Copyright (C) 2015 The Android Open Source Project 3702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * 4702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * Licensed under the Apache License, Version 2.0 (the "License"); 5702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * you may not use this file except in compliance with the License. 6702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * You may obtain a copy of the License at 7702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * 8702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * http://www.apache.org/licenses/LICENSE-2.0 9702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * 10702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * Unless required by applicable law or agreed to in writing, software 11702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * distributed under the License is distributed on an "AS IS" BASIS, 12702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * See the License for the specific language governing permissions and 14702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal * limitations under the License. 15702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal */ 16702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 1792870384369a8a5345bfe868b97d2d384f433103Sanket Agarwalpackage com.android.bluetooth.a2dpsink.mbs; 18702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 19702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.bluetooth.BluetoothAdapter; 20702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.bluetooth.BluetoothAvrcpController; 21702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.bluetooth.BluetoothDevice; 22702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.bluetooth.BluetoothProfile; 23702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.content.BroadcastReceiver; 24702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.content.Context; 25702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.content.Intent; 26702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.content.IntentFilter; 27702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.media.MediaMetadata; 28702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.media.browse.MediaBrowser.MediaItem; 2926469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwalimport android.media.session.MediaController; 30702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.media.session.MediaSession; 31702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.media.session.PlaybackState; 32702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.os.Bundle; 33702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.os.Handler; 34702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.os.Looper; 35702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.os.Message; 36702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.os.ResultReceiver; 37702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.service.media.MediaBrowserService; 38702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.util.Pair; 39702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport android.util.Log; 40702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 4192870384369a8a5345bfe868b97d2d384f433103Sanket Agarwalimport com.android.bluetooth.R; 4292870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal 43702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport java.lang.ref.WeakReference; 44702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport java.util.ArrayList; 45702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalimport java.util.List; 46702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 47702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwalpublic class A2dpMediaBrowserService extends MediaBrowserService { 48702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final String TAG = "A2dpMediaBrowserService"; 49702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final String MEDIA_ID_ROOT = "__ROOT__"; 50702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final String UNKNOWN_BT_AUDIO = "__UNKNOWN_BT_AUDIO__"; 51702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final float PLAYBACK_SPEED = 1.0f; 52702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 53702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Message sent when A2DP device is disconnected. 54702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_DEVICE_DISCONNECT = 0; 55702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Message snet when the AVRCP profile is disconnected = 1; 56702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_PROFILE_DISCONNECT = 1; 57702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Message sent when A2DP device is connected. 58702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_DEVICE_CONNECT = 2; 59702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Message sent when AVRCP profile is connected (note AVRCP profile may be connected before or 60702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // after A2DP device is connected). 61702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_PROFILE_CONNECT = 3; 62702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Message sent when we recieve a TRACK update from AVRCP profile over a connected A2DP device. 63702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_TRACK = 4; 64702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Internal message sent to trigger a AVRCP action. 65702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final int MSG_AVRCP_PASSTHRU = 5; 66702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 67702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private MediaSession mSession; 68702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private MediaMetadata mA2dpMetadata; 69702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 70702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private BluetoothAdapter mAdapter; 71702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private BluetoothAvrcpController mAvrcpProfile; 72702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private BluetoothDevice mA2dpDevice = null; 73702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private Handler mAvrcpCommandQueue; 74702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 75702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private long mTransportControlFlags = PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY 76702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal | PlaybackState.ACTION_SKIP_TO_NEXT | PlaybackState.ACTION_SKIP_TO_PREVIOUS; 77702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 78702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private static final class AvrcpCommandQueueHandler extends Handler { 79702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal WeakReference<A2dpMediaBrowserService> mInst; 80702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 81702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal AvrcpCommandQueueHandler(Looper looper, A2dpMediaBrowserService sink) { 82702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal super(looper); 83702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mInst = new WeakReference<A2dpMediaBrowserService>(sink); 84702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 85702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 86702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 87702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void handleMessage(Message msg) { 88702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal A2dpMediaBrowserService inst = mInst.get(); 89702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (inst == null) { 90702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.e(TAG, "Parent class has died; aborting."); 91702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 92702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 93702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 94702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal switch (msg.what) { 95702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_DEVICE_CONNECT: 96702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgDeviceConnect((BluetoothDevice) msg.obj); 97702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 98702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_PROFILE_CONNECT: 99702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgProfileConnect((BluetoothProfile) msg.obj); 100702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 101702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_DEVICE_DISCONNECT: 102702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgDeviceDisconnect((BluetoothDevice) msg.obj); 103702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 104702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_PROFILE_DISCONNECT: 105702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgProfileDisconnect(); 106702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 107702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_TRACK: 108702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Pair<PlaybackState, MediaMetadata> pair = 109702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal (Pair<PlaybackState, MediaMetadata>) (msg.obj); 110702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgTrack(pair.first, pair.second); 111702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 112702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal case MSG_AVRCP_PASSTHRU: 113702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal inst.msgPassThru((int) msg.obj); 114702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal break; 115702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 116702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 117702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 118702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 119702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 120702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onCreate() { 121702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onCreate"); 122702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal super.onCreate(); 123702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession = new MediaSession(this, TAG); 124702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal setSessionToken(mSession.getSessionToken()); 125702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setCallback(mSessionCallbacks); 126702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | 127702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); 128702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue = new AvrcpCommandQueueHandler(Looper.getMainLooper(), this); 129702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 130702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAdapter = BluetoothAdapter.getDefaultAdapter(); 131702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAdapter.getProfileProxy(this, mServiceListener, BluetoothProfile.AVRCP_CONTROLLER); 132702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 133702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal IntentFilter filter = new IntentFilter(); 134f3db7dcf88a585d133f73b8579012f8217965728Sanket Agarwal filter.addAction(BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED); 135702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal filter.addAction(BluetoothAvrcpController.ACTION_TRACK_EVENT); 136702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal registerReceiver(mBtReceiver, filter); 137702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 138702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 139702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 140702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onDestroy() { 141702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onDestroy"); 142702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.release(); 143702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal unregisterReceiver(mBtReceiver); 144702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal super.onDestroy(); 145702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 146702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 147702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 148702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) { 149702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return new BrowserRoot(MEDIA_ID_ROOT, null); 150702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 151702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 152702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 153702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) { 154702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onLoadChildren parentMediaId=" + parentMediaId); 155702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal List<MediaItem> items = new ArrayList<MediaItem>(); 156702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal result.sendResult(items); 157702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 158702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 159702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal BluetoothProfile.ServiceListener mServiceListener = new BluetoothProfile.ServiceListener() { 160702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onServiceConnected(int profile, BluetoothProfile proxy) { 161702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onServiceConnected"); 162702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (profile == BluetoothProfile.AVRCP_CONTROLLER) { 163702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage(MSG_PROFILE_CONNECT, proxy).sendToTarget(); 164702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal List<BluetoothDevice> devices = proxy.getConnectedDevices(); 165702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (devices != null && devices.size() > 0) { 166702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal BluetoothDevice device = devices.get(0); 167702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "got AVRCP device " + device); 168702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 169702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 170702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 171702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 172702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onServiceDisconnected(int profile) { 173702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onServiceDisconnected " + profile); 174702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (profile == BluetoothProfile.AVRCP_CONTROLLER) { 175702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpProfile = null; 176702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage(MSG_PROFILE_DISCONNECT).sendToTarget(); 177702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 178702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 179702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal }; 180702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 181702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Media Session Stuff. 182702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private MediaSession.Callback mSessionCallbacks = new MediaSession.Callback() { 183702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 184702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onPlay() { 185702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onPlay"); 186702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage( 187702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_PLAY).sendToTarget(); 188702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // TRACK_EVENT should be fired eventually and the UI should be hence updated. 189702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 190702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 191702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 192702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onPause() { 193702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onPause"); 194702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage( 195702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_PAUSE).sendToTarget(); 196702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // TRACK_EVENT should be fired eventually and the UI should be hence updated. 197702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 198702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 199702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 200702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onSkipToNext() { 201702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onSkipToNext"); 202702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage( 203702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_FORWARD) 204702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .sendToTarget(); 205702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // TRACK_EVENT should be fired eventually and the UI should be hence updated. 206702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 207702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 208702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 209702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onSkipToPrevious() { 210702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onSkipToPrevious"); 211702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 212702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage( 213702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MSG_AVRCP_PASSTHRU, BluetoothAvrcpController.PASS_THRU_CMD_ID_BACKWARD) 214702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .sendToTarget(); 215702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // TRACK_EVENT should be fired eventually and the UI should be hence updated. 216702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 217702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 218702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // These are not yet supported. 219702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 220702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onStop() { 221702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onStop"); 222702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 223702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 224702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 225702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onCustomAction(String action, Bundle extras) { 226702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onCustomAction action=" + action + " extras=" + extras); 227702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 228702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 229702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 230702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onPlayFromSearch(String query, Bundle extras) { 231702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "playFromSearch not supported in AVRCP"); 232702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 233702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 234702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 235702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onCommand(String command, Bundle args, ResultReceiver cb) { 236702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onCommand command=" + command + " args=" + args); 237702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 238702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 239702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 240702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onSkipToQueueItem(long queueId) { 241702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onSkipToQueueItem"); 242702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 243702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 244702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 245702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onPlayFromMediaId(String mediaId, Bundle extras) { 246702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onPlayFromMediaId mediaId=" + mediaId + " extras=" + extras); 247702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 248702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 249702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal }; 250702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 251702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private BroadcastReceiver mBtReceiver = new BroadcastReceiver() { 252702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal @Override 253702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal public void onReceive(Context context, Intent intent) { 254702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "onReceive intent=" + intent); 255702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal String action = intent.getAction(); 256702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal BluetoothDevice btDev = 257702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 258702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1); 259702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 260f3db7dcf88a585d133f73b8579012f8217965728Sanket Agarwal if (BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED.equals(action)) { 261702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "handleConnectionStateChange: newState=" 262702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal + state + " btDev=" + btDev); 263702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 264702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Connected state will be handled when AVRCP BluetoothProfile gets connected. 265702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (state == BluetoothProfile.STATE_CONNECTED) { 266702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage(MSG_DEVICE_CONNECT, btDev).sendToTarget(); 267702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } else if (state == BluetoothProfile.STATE_DISCONNECTED) { 268702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Set the playback state to unconnected. 269702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage(MSG_DEVICE_DISCONNECT, btDev).sendToTarget(); 270702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 271702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } else if (BluetoothAvrcpController.ACTION_TRACK_EVENT.equals(action)) { 272702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState pbb = 273702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal intent.getParcelableExtra(BluetoothAvrcpController.EXTRA_PLAYBACK); 274702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MediaMetadata mmd = 275702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal intent.getParcelableExtra(BluetoothAvrcpController.EXTRA_METADATA); 276702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpCommandQueue.obtainMessage( 277702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MSG_TRACK, new Pair<PlaybackState, MediaMetadata>(pbb, mmd)).sendToTarget(); 278702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 279702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 280702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal }; 281702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 282702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgDeviceConnect(BluetoothDevice device) { 283702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgDeviceConnect"); 284702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // We are connected to a new device via A2DP now. 285702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mA2dpDevice = device; 28692870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal refreshInitialPlayingState(); 287702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 288702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 289702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgProfileConnect(BluetoothProfile profile) { 290702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgProfileConnect"); 291702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (profile != null) { 292702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpProfile = (BluetoothAvrcpController) profile; 293702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 29492870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal refreshInitialPlayingState(); 29592870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal } 29692870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal 29792870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal // Refresh the UI if we have a connected device and AVRCP is initialized. 29892870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal private void refreshInitialPlayingState() { 29992870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal if (mAvrcpProfile == null || mA2dpDevice == null) { 30092870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal Log.d(TAG, "AVRCP Profile " + mAvrcpProfile + " device " + mA2dpDevice); 30192870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal return; 30292870384369a8a5345bfe868b97d2d384f433103Sanket Agarwal } 303702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 304702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal List<BluetoothDevice> devices = mAvrcpProfile.getConnectedDevices(); 305702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (devices.size() == 0) { 306702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.w(TAG, "No devices connected yet"); 307702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 308702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 309702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 310702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (mA2dpDevice != null && !mA2dpDevice.equals(devices.get(0))) { 311702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.e(TAG, "A2dp device : " + mA2dpDevice + " avrcp device " + devices.get(0)); 312702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 313702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mA2dpDevice = devices.get(0); 314702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 315702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState playbackState = mAvrcpProfile.getPlaybackState(mA2dpDevice); 316702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Add actions required for playback and rebuild the object. 317702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState.Builder pbb = new PlaybackState.Builder(playbackState); 318702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal playbackState = pbb.setActions(mTransportControlFlags).build(); 319702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 320702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal MediaMetadata mediaMetadata = mAvrcpProfile.getMetadata(mA2dpDevice); 321702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "Media metadata " + mediaMetadata + " playback state " + playbackState); 322702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setMetadata(mAvrcpProfile.getMetadata(mA2dpDevice)); 323702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setPlaybackState(playbackState); 324702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 325702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 326702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgDeviceDisconnect(BluetoothDevice device) { 327702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgDeviceDisconnect"); 328702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (mA2dpDevice == null) { 329702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.w(TAG, "Already disconnected - nothing to do here."); 330702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 331702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } else if (!mA2dpDevice.equals(device)) { 332702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.e(TAG, "Not the right device to disconnect current " + 333702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mA2dpDevice + " dc " + device); 334702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 335702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 336702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 337702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Unset the session. 338702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState.Builder pbb = new PlaybackState.Builder(); 339702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal pbb = pbb.setState(PlaybackState.STATE_ERROR, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 340702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PLAYBACK_SPEED) 341702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .setActions(mTransportControlFlags) 342702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .setErrorMessage(getString(R.string.bluetooth_disconnected)); 343702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setPlaybackState(pbb.build()); 344702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 345702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 346702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgProfileDisconnect() { 347702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgProfileDisconnect"); 348702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // The profile is disconnected - even if the device is still connected we cannot really have 349702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // a functioning UI so reset the session. 350702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpProfile = null; 351702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 352702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Unset the session. 353702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState.Builder pbb = new PlaybackState.Builder(); 354702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal pbb = pbb.setState(PlaybackState.STATE_ERROR, PlaybackState.PLAYBACK_POSITION_UNKNOWN, 355702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PLAYBACK_SPEED) 356702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .setActions(mTransportControlFlags) 357702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal .setErrorMessage(getString(R.string.bluetooth_disconnected)); 358702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setPlaybackState(pbb.build()); 359702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 360702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 361702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgTrack(PlaybackState pb, MediaMetadata mmd) { 362702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgTrack: playback: " + pb + " mmd: " + mmd); 36326469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal // Log the current track position/content. 36426469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal MediaController controller = mSession.getController(); 36526469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal PlaybackState prevPS = controller.getPlaybackState(); 36626469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal MediaMetadata prevMM = controller.getMetadata(); 36726469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal 36826469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal if (prevPS != null) { 36926469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal Log.d(TAG, "prevPS " + prevPS); 37026469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal } 37126469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal 37226469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal if (prevMM != null) { 37326469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal String title = prevMM.getString(MediaMetadata.METADATA_KEY_TITLE); 37426469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal long trackLen = prevMM.getLong(MediaMetadata.METADATA_KEY_DURATION); 37526469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal Log.d(TAG, "prev MM title " + title + " track len " + trackLen); 37626469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal } 37726469ff3f9f4ab96ad288e0934220023a0c159f1Sanket Agarwal 378702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (mmd != null) { 379702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgTrack() mmd " + mmd.getDescription()); 380702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setMetadata(mmd); 381702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 382702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 383702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (pb != null) { 384702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgTrack() playbackstate " + pb); 385702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal PlaybackState.Builder pbb = new PlaybackState.Builder(pb); 386702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal pb = pbb.setActions(mTransportControlFlags).build(); 387702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mSession.setPlaybackState(pb); 388702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 389702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 390702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 391702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal private void msgPassThru(int cmd) { 392702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.d(TAG, "msgPassThru " + cmd); 393702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (mA2dpDevice == null) { 394702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // We should have already disconnected - ignore this message. 395702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.e(TAG, "Already disconnected ignoring."); 396702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 397702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 398702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 399702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal if (mAvrcpProfile == null) { 400702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // We may be disconnected with the profile but there is not much we can do for now but 401702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // to wait for the profile to come back up. 402702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal Log.e(TAG, "Profile disconnected; ignoring."); 403702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal return; 404702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 405702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal 406702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal // Send the pass through. 407702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpProfile.sendPassThroughCmd( 408702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mA2dpDevice, cmd, BluetoothAvrcpController.KEY_STATE_PRESSED); 409702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mAvrcpProfile.sendPassThroughCmd( 410702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal mA2dpDevice, cmd, BluetoothAvrcpController.KEY_STATE_RELEASED); 411702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal } 412702c59f80ab9c21d6b4d673d50380e18c477f88cSanket Agarwal} 413