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