PageRenderTime 40ms CodeModel.GetById 50ms RepoModel.GetById 0ms app.codeStats 1ms

/src/com/android/bluetooth/avrcp/Avrcp.java

https://github.com/CyanogenMod/android_packages_apps_Bluetooth
Java | 6034 lines | 5465 code | 420 blank | 149 comment | 1158 complexity | 5a0703ec4537708987120e87d678f7b9 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2013-2015, The Linux Foundation. All rights reserved.
  3. * Not a Contribution.
  4. *
  5. * Copyright (C) 2012 The Android Open Source Project
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. package com.android.bluetooth.avrcp;
  20. import java.util.Timer;
  21. import java.util.TimerTask;
  22. import android.app.PendingIntent;
  23. import android.bluetooth.BluetoothAdapter;
  24. import android.bluetooth.BluetoothA2dp;
  25. import android.bluetooth.BluetoothAvrcp;
  26. import android.bluetooth.BluetoothDevice;
  27. import android.content.Context;
  28. import android.content.Intent;
  29. import android.content.res.Resources;
  30. import android.content.SharedPreferences;
  31. import android.content.IntentFilter;
  32. import android.graphics.Bitmap;
  33. import android.media.AudioManager;
  34. import android.media.MediaDescription;
  35. import android.media.MediaMetadata;
  36. import android.media.session.MediaController;
  37. import android.media.session.MediaSessionManager;
  38. import android.media.session.PlaybackState;
  39. import android.os.Bundle;
  40. import android.os.Handler;
  41. import android.os.HandlerThread;
  42. import android.os.Looper;
  43. import android.os.Message;
  44. import android.os.ParcelUuid;
  45. import android.os.PowerManager;
  46. import android.os.PowerManager.WakeLock;
  47. import android.os.RemoteException;
  48. import android.os.ServiceManager;
  49. import android.os.SystemClock;
  50. import android.util.Log;
  51. import android.view.KeyEvent;
  52. import com.android.bluetooth.R;
  53. import android.content.BroadcastReceiver;
  54. import com.android.bluetooth.a2dp.A2dpService;
  55. import com.android.bluetooth.btservice.AdapterService;
  56. import com.android.bluetooth.btservice.ProfileService;
  57. import com.android.bluetooth.Utils;
  58. import com.android.internal.util.IState;
  59. import com.android.internal.util.State;
  60. import com.android.internal.util.StateMachine;
  61. import java.lang.ref.WeakReference;
  62. import java.util.ArrayList;
  63. import java.util.HashMap;
  64. import java.util.List;
  65. import java.util.Set;
  66. import java.util.Iterator;
  67. import android.provider.MediaStore;
  68. import android.content.ContentResolver;
  69. import android.database.Cursor;
  70. import android.database.sqlite.SQLiteException;
  71. import android.net.Uri;
  72. import android.app.Notification;
  73. import android.app.NotificationManager;
  74. import com.android.bluetooth.avrcp.AvrcpControllerService;
  75. import android.os.SystemProperties;
  76. /**
  77. * support Bluetooth AVRCP profile.
  78. * support metadata, play status and event notification
  79. */
  80. public final class Avrcp {
  81. private static final boolean DEBUG = false;
  82. private static final String TAG = "Avrcp";
  83. private static final String ABSOLUTE_VOLUME_BLACKLIST = "absolute_volume_blacklist";
  84. private Context mContext;
  85. private final AudioManager mAudioManager;
  86. private A2dpService mA2dpService;
  87. private AvrcpMessageHandler mHandler;
  88. private MediaSessionManager mMediaSessionManager;
  89. private MediaSessionChangeListener mSessionChangeListener;
  90. private MediaController mMediaController;
  91. private MediaControllerListener mMediaControllerCb;
  92. private MediaAttributes mMediaAttributes;
  93. private int mTransportControlFlags;
  94. private PlaybackState mCurrentPlayerState;
  95. private long mLastStateUpdate;
  96. private int mPlayStatusChangedNT;
  97. private int mTrackChangedNT;
  98. private int mPlayPosChangedNT;
  99. private long mSongLengthMs;
  100. private long mPlaybackIntervalMs;
  101. private long mSkipStartTime;
  102. Resources mResources;
  103. private int mVolumeStep;
  104. private final int mAudioStreamMax;
  105. private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
  106. private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
  107. private int mSkipAmount;
  108. private final BluetoothAdapter mAdapter;
  109. private static Uri mMediaUriStatic;
  110. private static long currentTrackPos;
  111. private static boolean updatePlayTime;
  112. private static boolean updateValues;
  113. private int mAddressedPlayerId;
  114. /* BTRC features */
  115. public static final int BTRC_FEAT_METADATA = 0x01;
  116. public static final int BTRC_FEAT_ABSOLUTE_VOLUME = 0x02;
  117. public static final int BTRC_FEAT_BROWSE = 0x04;
  118. public static final int BTRC_FEAT_AVRC_UI_UPDATE = 0x08;
  119. /* AVRC response codes, from avrc_defs */
  120. private static final int AVRC_RSP_NOT_IMPL = 8;
  121. private static final int AVRC_RSP_ACCEPT = 9;
  122. private static final int AVRC_RSP_REJ = 10;
  123. private static final int AVRC_RSP_IN_TRANS = 11;
  124. private static final int AVRC_RSP_IMPL_STBL = 12;
  125. private static final int AVRC_RSP_CHANGED = 13;
  126. private static final int AVRC_RSP_INTERIM = 15;
  127. private static final int MESSAGE_GET_RC_FEATURES = 1;
  128. private static final int MESSAGE_GET_PLAY_STATUS = 2;
  129. private static final int MESSAGE_GET_ELEM_ATTRS = 3;
  130. private static final int MESSAGE_REGISTER_NOTIFICATION = 4;
  131. private static final int MESSAGE_PLAY_INTERVAL_TIMEOUT = 5;
  132. private static final int MESSAGE_VOLUME_CHANGED = 6;
  133. private static final int MESSAGE_ADJUST_VOLUME = 7;
  134. private static final int MESSAGE_SET_ABSOLUTE_VOLUME = 8;
  135. private static final int MESSAGE_ABS_VOL_TIMEOUT = 9;
  136. private static final int MESSAGE_FAST_FORWARD = 10;
  137. private static final int MESSAGE_REWIND = 11;
  138. private static final int MESSAGE_CHANGE_PLAY_POS = 12;
  139. private static final int MESSAGE_SET_A2DP_AUDIO_STATE = 13;
  140. private static final int MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT = 14;
  141. private static final int AVRCP_BR_RSP_TIMEOUT = 2000;
  142. private static final int MESSAGE_SEND_PASS_THROUGH_CMD = 2001;
  143. private static final int MESSAGE_SET_ADDR_PLAYER = 2002;
  144. private static final int MESSAGE_GET_FOLDER_ITEMS = 2003;
  145. private static final int MESSAGE_SET_BROWSED_PLAYER = 2004;
  146. private static final int MESSAGE_CHANGE_PATH = 2005;
  147. private static final int MESSAGE_PLAY_ITEM = 2006;
  148. private static final int MESSAGE_GET_ITEM_ATTRS = 2007;
  149. private static final int MESSAGE_GET_TOTAL_NUMBER_OF_ITEMS = 2008;
  150. private CachedRequest mCachedRequest = null;
  151. private static final int MSG_UPDATE_AVAILABLE_PLAYERS = 201;
  152. private static final int MSG_UPDATE_ADDRESSED_PLAYER = 202;
  153. private static final int MSG_UPDATE_RCC_CHANGE = 203;
  154. private static final int MSG_UPDATE_BROWSED_PLAYER_FOLDER = 204;
  155. private static final int MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED = 205;
  156. private static final int MSG_PLAY_ITEM_RESPONSE = 206;
  157. private static final int MSG_NOW_PLAYING_ENTRIES_RECEIVED = 207;
  158. private MediaPlayerInfo mediaPlayerInfo1;
  159. private MediaPlayerInfo mediaPlayerInfo2;
  160. private static final int BUTTON_TIMEOUT_TIME = 2000;
  161. private static final int BASE_SKIP_AMOUNT = 2000;
  162. private static final int KEY_STATE_PRESS = 1;
  163. private static final int KEY_STATE_RELEASE = 0;
  164. private static final int SKIP_PERIOD = 400;
  165. private static final int SKIP_DOUBLE_INTERVAL = 3000;
  166. private static final long MAX_MULTIPLIER_VALUE = 128L;
  167. private static final int CMD_TIMEOUT_DELAY = 2000;
  168. private static final int MAX_ERROR_RETRY_TIMES = 6;
  169. private static final int AVRCP_MAX_VOL = 127;
  170. private static final int AVRCP_BASE_VOLUME_STEP = 1;
  171. private final static int MESSAGE_PLAYERSETTINGS_TIMEOUT = 602;
  172. private static final int AVRCP_CONNECTED = 1;
  173. public static final int KEY_STATE_PRESSED = 0;
  174. public static final int KEY_STATE_RELEASED = 1;
  175. public static final int AVRC_ID_VOL_UP = 0x41;
  176. public static final int AVRC_ID_VOL_DOWN = 0x42;
  177. private boolean pts_test = false;
  178. private final static int TYPE_MEDIA_PLAYER_ITEM = 0x01;
  179. private final static int TYPE_FOLDER_ITEM = 0x02;
  180. private final static int TYPE_MEDIA_ELEMENT_ITEM = 0x03;
  181. private final static int FOLDER_UP = 0x00;
  182. private final static int FOLDER_DOWN = 0x01;
  183. private static final String PATH_INVALID = "invalid";
  184. private static final String PATH_ROOT = "root";
  185. private static final String PATH_TITLES = "titles";
  186. private static final String PATH_ALBUMS = "albums";
  187. private static final String PATH_ARTISTS = "artists";
  188. private static final String PATH_PLAYLISTS = "playlists";
  189. private final static long UID_TITLES = 0x01;
  190. private final static long UID_ALBUM = 0x02;
  191. private final static long UID_ARTIST = 0x03;
  192. private final static long UID_PLAYLIST = 0x04;
  193. private final static int NUM_ROOT_ELEMENTS = 0x04;
  194. private static final int INTERNAL_ERROR = 0x03;
  195. private static final int OPERATION_SUCCESSFUL = 0x04;
  196. private static final int INVALID_DIRECTION = 0x07;
  197. private static final int NOT_A_DIRECTORY = 0x08;
  198. private static final int DOES_NOT_EXIST = 0x09;
  199. private static final int INVALID_SCOPE = 0x0a;
  200. private static final int RANGE_OUT_OF_BOUNDS = 0x0b;
  201. private static final int UID_A_DIRECTORY = 0x0c;
  202. private static final int MEDIA_IN_USE = 0x0d;
  203. private static final int INVALID_PLAYER_ID = 0x11;
  204. private static final int PLAYER_NOT_BROWSABLE = 0x12;
  205. private static final int PLAYER_NOT_ADDRESSED = 0x13;
  206. private static final int FOLDER_TYPE_MIXED = 0x00;
  207. private static final int FOLDER_TYPE_TITLES = 0x01;
  208. private static final int FOLDER_TYPE_ALBUMS = 0x02;
  209. private static final int FOLDER_TYPE_ARTISTS = 0x03;
  210. private static final int FOLDER_TYPE_GENRES = 0x04;
  211. private static final int FOLDER_TYPE_PLAYLISTS = 0x05;
  212. private static final int MEDIA_TYPE_AUDIO = 0X00;
  213. private static final int MEDIA_TYPE_VIDEO = 0X01;
  214. private static final int MAX_BROWSE_ITEM_TO_SEND = 10;
  215. private static final int MAX_ATTRIB_COUNT = 0x08;
  216. private final static int ALBUMS_ITEM_INDEX = 0;
  217. private final static int ARTISTS_ITEM_INDEX = 1;
  218. private final static int PLAYLISTS_ITEM_INDEX = 2;
  219. private final static int TITLES_ITEM_INDEX = 3;
  220. //Intents for PlayerApplication Settings
  221. private static final String PLAYERSETTINGS_REQUEST =
  222. "org.codeaurora.music.playersettingsrequest";
  223. private static final String PLAYERSETTINGS_RESPONSE =
  224. "org.codeaurora.music.playersettingsresponse";
  225. // Max number of Avrcp connections at any time
  226. private int maxAvrcpConnections = 1;
  227. BluetoothDevice mBrowserDevice = null;
  228. private static final int INVALID_DEVICE_INDEX = 0xFF;
  229. // codes for reset of of notifications
  230. private static final int PLAY_POSITION_CHANGE_NOTIFICATION = 101;
  231. private static final int PLAY_STATUS_CHANGE_NOTIFICATION = 102;
  232. private static final int TRACK_CHANGE_NOTIFICATION = 103;
  233. private static final int NOW_PALYING_CONTENT_CHANGED_NOTIFICATION = 104;
  234. private static final int PLAYER_STATUS_CHANGED_NOTIFICATION = 105;
  235. private static final int INVALID_ADDRESSED_PLAYER_ID = -1;
  236. // Device dependent registered Notification & Variables
  237. private class DeviceDependentFeature {
  238. private BluetoothDevice mCurrentDevice;
  239. private PlaybackState mCurrentPlayState;
  240. private int mPlayStatusChangedNT;
  241. private int mPlayerStatusChangeNT;
  242. private int mTrackChangedNT;
  243. private long mNextPosMs;
  244. private long mPrevPosMs;
  245. private long mPlaybackIntervalMs;
  246. private long mLastReportedPosition;
  247. private int mPlayPosChangedNT;
  248. private int mFeatures;
  249. private int mAbsoluteVolume;
  250. private int mLastSetVolume;
  251. private int mLastDirection;
  252. private boolean mVolCmdSetInProgress;
  253. private boolean mVolCmdAdjustInProgress;
  254. private int mAbsVolRetryTimes;
  255. private int keyPressState;
  256. private int mAddressedPlayerChangedNT;
  257. private int mAvailablePlayersChangedNT;
  258. private int mNowPlayingContentChangedNT;
  259. private String mRequestedAddressedPlayerPackageName;
  260. private String mCurrentPath;
  261. private String mCurrentPathUid;
  262. private Uri mMediaUri;
  263. private boolean isMusicAppResponsePending;
  264. private boolean isBrowsingSupported;
  265. private boolean isAbsoluteVolumeSupportingDevice;
  266. private boolean isActiveDevice;
  267. private int mRemoteVolume;
  268. private int mLastRemoteVolume;
  269. private int mInitialRemoteVolume;
  270. /* Local volume in audio index 0-15 */
  271. private int mLocalVolume;
  272. private int mLastLocalVolume;
  273. private int mAbsVolThreshold;
  274. private HashMap<Integer, Integer> mVolumeMapping;
  275. public DeviceDependentFeature() {
  276. mCurrentDevice = null;
  277. mCurrentPlayState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build();;
  278. mPlayStatusChangedNT = NOTIFICATION_TYPE_CHANGED;
  279. mPlayerStatusChangeNT = NOTIFICATION_TYPE_CHANGED;
  280. mTrackChangedNT = NOTIFICATION_TYPE_CHANGED;
  281. mNextPosMs = -1;
  282. mPrevPosMs = -1;
  283. mPlaybackIntervalMs = 0L;
  284. mLastReportedPosition = -1;
  285. mPlayPosChangedNT = NOTIFICATION_TYPE_CHANGED;
  286. mFeatures = 0;
  287. mAbsoluteVolume = -1;
  288. mLastSetVolume = -1;
  289. mLastDirection = 0;
  290. mVolCmdAdjustInProgress = false;
  291. mVolCmdSetInProgress = false;
  292. mAbsVolRetryTimes = 0;
  293. keyPressState = KEY_STATE_RELEASE; //Key release state
  294. mAddressedPlayerChangedNT = NOTIFICATION_TYPE_CHANGED;
  295. mAvailablePlayersChangedNT = NOTIFICATION_TYPE_CHANGED;
  296. mNowPlayingContentChangedNT = NOTIFICATION_TYPE_CHANGED;
  297. mRequestedAddressedPlayerPackageName = null;
  298. mCurrentPath = PATH_INVALID;
  299. mCurrentPathUid = null;
  300. mMediaUri = Uri.EMPTY;
  301. isMusicAppResponsePending = false;
  302. isBrowsingSupported = false;
  303. isAbsoluteVolumeSupportingDevice = false;
  304. isActiveDevice = false;
  305. mRemoteVolume = -1;
  306. mInitialRemoteVolume = -1;
  307. mLastRemoteVolume = -1;
  308. mLocalVolume = -1;
  309. mLastLocalVolume = -1;
  310. mAbsVolThreshold = 0;
  311. mVolumeMapping = new HashMap<Integer, Integer>();
  312. if (mResources != null) {
  313. mAbsVolThreshold = mResources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold);
  314. }
  315. }
  316. };
  317. private class PlayerSettings {
  318. public byte attr;
  319. public byte [] attrIds;
  320. public String path;
  321. };
  322. private PlayerSettings mPlayerSettings = new PlayerSettings();
  323. private class localPlayerSettings {
  324. public byte eq_value = 0x01;
  325. public byte repeat_value = 0x01;
  326. public byte shuffle_value = 0x01;
  327. public byte scan_value = 0x01;
  328. };
  329. private localPlayerSettings settingValues = new localPlayerSettings();
  330. private static final String COMMAND = "command";
  331. private static final String CMDGET = "get";
  332. private static final String CMDSET = "set";
  333. private static final String EXTRA_GET_COMMAND = "commandExtra";
  334. private static final String EXTRA_GET_RESPONSE = "Response";
  335. private static final int GET_ATTRIBUTE_IDS = 0;
  336. private static final int GET_VALUE_IDS = 1;
  337. private static final int GET_ATTRIBUTE_TEXT = 2;
  338. private static final int GET_VALUE_TEXT = 3;
  339. private static final int GET_ATTRIBUTE_VALUES = 4;
  340. private static final int NOTIFY_ATTRIBUTE_VALUES = 5;
  341. private static final int SET_ATTRIBUTE_VALUES = 6;
  342. private static final int GET_INVALID = 0xff;
  343. private static final String EXTRA_ATTRIBUTE_ID = "Attribute";
  344. private static final String EXTRA_VALUE_STRING_ARRAY = "ValueStrings";
  345. private static final String EXTRA_ATTRIB_VALUE_PAIRS = "AttribValuePairs";
  346. private static final String EXTRA_ATTRIBUTE_STRING_ARRAY = "AttributeStrings";
  347. private static final String EXTRA_VALUE_ID_ARRAY = "Values";
  348. private static final String EXTRA_ATTIBUTE_ID_ARRAY = "Attributes";
  349. public static final int VALUE_SHUFFLEMODE_OFF = 1;
  350. public static final int VALUE_SHUFFLEMODE_ALL = 2;
  351. public static final int VALUE_REPEATMODE_OFF = 1;
  352. public static final int VALUE_REPEATMODE_SINGLE = 2;
  353. public static final int VALUE_REPEATMODE_ALL = 3;
  354. public static final int VALUE_INVALID = 0;
  355. public static final int ATTRIBUTE_NOTSUPPORTED = -1;
  356. public static final int ATTRIBUTE_EQUALIZER = 1;
  357. public static final int ATTRIBUTE_REPEATMODE = 2;
  358. public static final int ATTRIBUTE_SHUFFLEMODE = 3;
  359. public static final int ATTRIBUTE_SCANMODE = 4;
  360. public static final int NUMPLAYER_ATTRIBUTE = 2;
  361. private static AvrcpBipRsp mAvrcpBipRsp;
  362. private byte [] def_attrib = new byte [] {ATTRIBUTE_REPEATMODE, ATTRIBUTE_SHUFFLEMODE};
  363. private byte [] value_repmode = new byte [] { VALUE_REPEATMODE_OFF,
  364. VALUE_REPEATMODE_SINGLE,
  365. VALUE_REPEATMODE_ALL };
  366. private byte [] value_shufmode = new byte [] { VALUE_SHUFFLEMODE_OFF,
  367. VALUE_SHUFFLEMODE_ALL };
  368. private byte [] value_default = new byte [] {0};
  369. private final String UPDATE_ATTRIBUTES = "UpdateSupportedAttributes";
  370. private final String UPDATE_VALUES = "UpdateSupportedValues";
  371. private final String UPDATE_ATTRIB_VALUE = "UpdateCurrentValues";
  372. private final String UPDATE_ATTRIB_TEXT = "UpdateAttributesText";
  373. private final String UPDATE_VALUE_TEXT = "UpdateValuesText";
  374. private ArrayList <Integer> mPendingCmds;
  375. private ArrayList <Integer> mPendingSetAttributes;
  376. DeviceDependentFeature[] deviceFeatures;
  377. static {
  378. classInitNative();
  379. }
  380. private Avrcp(Context context, A2dpService svc, int maxConnections ) {
  381. if (DEBUG)
  382. Log.v(TAG, "Avrcp");
  383. mAdapter = BluetoothAdapter.getDefaultAdapter();
  384. mMediaAttributes = new MediaAttributes(null);
  385. mCurrentPlayerState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build();
  386. mLastStateUpdate = -1L;
  387. mSongLengthMs = 0L;
  388. mA2dpService = svc;
  389. maxAvrcpConnections = maxConnections;
  390. deviceFeatures = new DeviceDependentFeature[maxAvrcpConnections];
  391. mAddressedPlayerId = INVALID_ADDRESSED_PLAYER_ID;
  392. for(int i = 0; i < maxAvrcpConnections; i++) {
  393. deviceFeatures[i] = new DeviceDependentFeature();
  394. }
  395. mContext = context;
  396. initNative(maxConnections);
  397. mMediaSessionManager = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
  398. mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
  399. mResources = context.getResources();
  400. mAudioStreamMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  401. mVolumeStep = Math.max(AVRCP_BASE_VOLUME_STEP, AVRCP_MAX_VOL/mAudioStreamMax);
  402. mAvrcpBipRsp = new AvrcpBipRsp(mContext);
  403. pts_test = SystemProperties.getBoolean("bt.avrcpct-passthrough.pts", false);
  404. }
  405. private void start() {
  406. if (DEBUG)
  407. Log.v(TAG, "start");
  408. HandlerThread thread = new HandlerThread("BluetoothAvrcpHandler");
  409. thread.start();
  410. Looper looper = thread.getLooper();
  411. mHandler = new AvrcpMessageHandler(looper);
  412. registerMediaPlayers();
  413. mSessionChangeListener = new MediaSessionChangeListener();
  414. mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionChangeListener, null, mHandler);
  415. List<MediaController> sessions = mMediaSessionManager.getActiveSessions(null);
  416. mMediaControllerCb = new MediaControllerListener();
  417. if (sessions.size() > 0) {
  418. final Iterator<MediaController> mcIterator = sessions.iterator();
  419. while (mcIterator.hasNext()) {
  420. final MediaController player = mcIterator.next();
  421. if (mHandler != null) {
  422. Log.v(TAG, "Availability change for player: " + player.getPackageName());
  423. mHandler.obtainMessage(MSG_UPDATE_RCC_CHANGE, 0, 1,
  424. player.getPackageName()).sendToTarget();
  425. }
  426. }
  427. updateCurrentMediaController(sessions.get(0));
  428. }
  429. mPendingCmds = new ArrayList<Integer>();
  430. mPendingSetAttributes = new ArrayList<Integer>();
  431. // clear path for all devices
  432. for (int i = 0; i < maxAvrcpConnections; i++) {
  433. deviceFeatures[i].mCurrentPath = PATH_INVALID;
  434. deviceFeatures[i].mCurrentPathUid = null;
  435. deviceFeatures[i].mMediaUri = Uri.EMPTY;
  436. }
  437. IntentFilter intentFilter = new IntentFilter();
  438. intentFilter.addAction(AudioManager.RCC_CHANGED_ACTION);
  439. intentFilter.addAction(PLAYERSETTINGS_RESPONSE);
  440. try {
  441. mContext.registerReceiver(mIntentReceiver, intentFilter);
  442. }catch (Exception e) {
  443. Log.e(TAG,"Unable to register Avrcp receiver", e);
  444. }
  445. mAvrcpBipRsp.start();
  446. }
  447. //Listen to intents from MediaPlayer and Audio Manager and update data structures
  448. private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
  449. @Override
  450. public void onReceive(Context context, Intent intent) {
  451. Log.d(TAG, "Enter onReceive()" +intent);
  452. String action = intent.getAction();
  453. if (action.equals(AudioManager.RCC_CHANGED_ACTION)) {
  454. Log.v(TAG, "received RCC_CHANGED_ACTION");
  455. int isRCCFocussed = 0;
  456. int isRCCAvailable = 0;
  457. String callingPackageName =
  458. intent.getStringExtra(AudioManager.EXTRA_CALLING_PACKAGE_NAME);
  459. boolean isFocussed =
  460. intent.getBooleanExtra(AudioManager.EXTRA_FOCUS_CHANGED_VALUE,
  461. false);
  462. boolean isAvailable =
  463. intent.getBooleanExtra(AudioManager.EXTRA_AVAILABLITY_CHANGED_VALUE,
  464. false);
  465. if (isFocussed)
  466. isRCCFocussed = 1;
  467. if (isAvailable)
  468. isRCCAvailable = 1;
  469. Log.v(TAG, "focus: " + isFocussed + " , availability: " + isAvailable);
  470. if (mHandler != null) {
  471. mHandler.obtainMessage(MSG_UPDATE_RCC_CHANGE, isRCCFocussed,
  472. isRCCAvailable, callingPackageName).sendToTarget();
  473. }
  474. } else if (action.equals(PLAYERSETTINGS_RESPONSE)) {
  475. int getResponse = intent.getIntExtra(EXTRA_GET_RESPONSE,
  476. GET_INVALID);
  477. byte [] data;
  478. String [] text;
  479. boolean isSetAttrValRsp = false;
  480. BluetoothDevice device = null;
  481. synchronized (mPendingCmds) {
  482. Integer val = new Integer(getResponse);
  483. if (mPendingCmds.contains(val)) {
  484. if (getResponse == SET_ATTRIBUTE_VALUES) {
  485. isSetAttrValRsp = true;
  486. if (DEBUG) Log.v(TAG,"Response received for SET_ATTRIBUTE_VALUES");
  487. }
  488. mHandler.removeMessages(MESSAGE_PLAYERSETTINGS_TIMEOUT);
  489. mPendingCmds.remove(val);
  490. }
  491. }
  492. for (int i = 0; i < maxAvrcpConnections; i++) {
  493. if (deviceFeatures[i].isMusicAppResponsePending ==
  494. true) {
  495. device = deviceFeatures[i].mCurrentDevice;
  496. deviceFeatures[i].isMusicAppResponsePending = false;
  497. break;
  498. }
  499. }
  500. if (DEBUG)
  501. Log.v(TAG,"getResponse" + getResponse);
  502. switch (getResponse) {
  503. case GET_ATTRIBUTE_IDS:
  504. if (device == null) {
  505. Log.e(TAG,"ERROR!!! device is null");
  506. return;
  507. }
  508. data = intent.getByteArrayExtra(EXTRA_ATTIBUTE_ID_ARRAY);
  509. byte numAttr = (byte) data.length;
  510. if (DEBUG)
  511. Log.v(TAG,"GET_ATTRIBUTE_IDS");
  512. getListPlayerappAttrRspNative(numAttr ,
  513. data ,getByteAddress(device));
  514. break;
  515. case GET_VALUE_IDS:
  516. if (device == null) {
  517. Log.e(TAG,"ERROR!!! device is null");
  518. return;
  519. }
  520. data = intent.getByteArrayExtra(EXTRA_VALUE_ID_ARRAY);
  521. numAttr = (byte) data.length;
  522. if (DEBUG)
  523. Log.v(TAG,"GET_VALUE_IDS" + numAttr);
  524. getPlayerAppValueRspNative(numAttr, data,
  525. getByteAddress(device));
  526. break;
  527. case GET_ATTRIBUTE_VALUES:
  528. if (device == null) {
  529. Log.e(TAG,"ERROR!!! device is null");
  530. return;
  531. }
  532. data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS);
  533. updateLocalPlayerSettings(data);
  534. numAttr = (byte) data.length;
  535. if (DEBUG)
  536. Log.v(TAG,"GET_ATTRIBUTE_VALUES" + numAttr);
  537. SendCurrentPlayerValueRspNative(numAttr ,
  538. data, getByteAddress(device));
  539. break;
  540. case SET_ATTRIBUTE_VALUES:
  541. data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS);
  542. updateLocalPlayerSettings(data);
  543. if (isSetAttrValRsp) {
  544. isSetAttrValRsp = false;
  545. for (int i = 0; i < maxAvrcpConnections; i++) {
  546. if (deviceFeatures[i].mCurrentDevice != null) {
  547. Log.v(TAG,"Respond to SET_ATTRIBUTE_VALUES request");
  548. if (checkPlayerAttributeResponse(data)) {
  549. SendSetPlayerAppRspNative(OPERATION_SUCCESSFUL,
  550. getByteAddress(deviceFeatures[i].mCurrentDevice));
  551. } else {
  552. SendSetPlayerAppRspNative(INTERNAL_ERROR,
  553. getByteAddress(deviceFeatures[i].mCurrentDevice));
  554. }
  555. }
  556. }
  557. mPendingSetAttributes.clear();
  558. }
  559. for (int i = 0; i < maxAvrcpConnections; i++) {
  560. if (deviceFeatures[i].mPlayerStatusChangeNT ==
  561. NOTIFICATION_TYPE_INTERIM) {
  562. Log.v(TAG,"device has registered for"+
  563. "mPlayerStatusChangeNT");
  564. deviceFeatures[i].mPlayerStatusChangeNT =
  565. NOTIFICATION_TYPE_CHANGED;
  566. sendPlayerAppChangedRsp(deviceFeatures[i].mPlayerStatusChangeNT,
  567. deviceFeatures[i].mCurrentDevice);
  568. } else {
  569. Log.v(TAG,"Drop Set Attr Val update from media player");
  570. }
  571. }
  572. break;
  573. case GET_ATTRIBUTE_TEXT:
  574. text = intent.getStringArrayExtra(EXTRA_ATTRIBUTE_STRING_ARRAY);
  575. if (device == null) {
  576. Log.e(TAG,"ERROR!!! device is null");
  577. return;
  578. }
  579. sendSettingsTextRspNative(mPlayerSettings.attrIds.length ,
  580. mPlayerSettings.attrIds ,text.length,
  581. text, getByteAddress(device));
  582. if (DEBUG)
  583. Log.v(TAG,"mPlayerSettings.attrIds"
  584. + mPlayerSettings.attrIds.length);
  585. break;
  586. case GET_VALUE_TEXT:
  587. text = intent.getStringArrayExtra(EXTRA_VALUE_STRING_ARRAY);
  588. if (device == null) {
  589. Log.e(TAG,"ERROR!!! device is null");
  590. return;
  591. }
  592. sendValueTextRspNative(mPlayerSettings.attrIds.length ,
  593. mPlayerSettings.attrIds,
  594. text.length, text,
  595. getByteAddress(device));
  596. break;
  597. }
  598. }
  599. }
  600. };
  601. /* This method is used for create entries of existing media players on RCD start
  602. * Later when media players become avaialable corresponding entries
  603. * are marked accordingly and similarly when media players changes focus
  604. * the corresponding fields are modified */
  605. private void registerMediaPlayers () {
  606. if (DEBUG)
  607. Log.v(TAG, "registerMediaPlayers");
  608. int[] featureMasks = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  609. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  610. int[] featureMasks2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  611. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  612. byte[] playerName1 = {0x4d, 0x75, 0x73, 0x69, 0x63}/*Music*/;
  613. byte[] playerName2 = {0x4d, 0x75, 0x73, 0x69, 0x63, 0x32}/*Music2*/;
  614. featureMasks[FEATURE_MASK_PLAY_OFFSET] =
  615. featureMasks[FEATURE_MASK_PLAY_OFFSET] | FEATURE_MASK_PLAY_MASK;
  616. featureMasks[FEATURE_MASK_PAUSE_OFFSET] =
  617. featureMasks[FEATURE_MASK_PAUSE_OFFSET] | FEATURE_MASK_PAUSE_MASK;
  618. featureMasks[FEATURE_MASK_STOP_OFFSET] =
  619. featureMasks[FEATURE_MASK_STOP_OFFSET] | FEATURE_MASK_STOP_MASK;
  620. featureMasks[FEATURE_MASK_PAGE_UP_OFFSET] =
  621. featureMasks[FEATURE_MASK_PAGE_UP_OFFSET] | FEATURE_MASK_PAGE_UP_MASK;
  622. featureMasks[FEATURE_MASK_PAGE_DOWN_OFFSET] =
  623. featureMasks[FEATURE_MASK_PAGE_DOWN_OFFSET] | FEATURE_MASK_PAGE_DOWN_MASK;
  624. featureMasks[FEATURE_MASK_REWIND_OFFSET] =
  625. featureMasks[FEATURE_MASK_REWIND_OFFSET] | FEATURE_MASK_REWIND_MASK;
  626. featureMasks[FEATURE_MASK_FAST_FWD_OFFSET] =
  627. featureMasks[FEATURE_MASK_FAST_FWD_OFFSET] | FEATURE_MASK_FAST_FWD_MASK;
  628. featureMasks[FEATURE_MASK_VENDOR_OFFSET] =
  629. featureMasks[FEATURE_MASK_VENDOR_OFFSET] | FEATURE_MASK_VENDOR_MASK;
  630. featureMasks[FEATURE_MASK_ADV_CTRL_OFFSET] =
  631. featureMasks[FEATURE_MASK_ADV_CTRL_OFFSET] | FEATURE_MASK_ADV_CTRL_MASK;
  632. featureMasks[FEATURE_MASK_BROWSE_OFFSET] =
  633. featureMasks[FEATURE_MASK_BROWSE_OFFSET] | FEATURE_MASK_BROWSE_MASK;
  634. featureMasks[FEATURE_MASK_NOW_PLAY_OFFSET] =
  635. featureMasks[FEATURE_MASK_NOW_PLAY_OFFSET] | FEATURE_MASK_NOW_PLAY_MASK;
  636. featureMasks[FEATURE_MASK_BR_WH_ADDR_OFFSET] =
  637. featureMasks[FEATURE_MASK_BR_WH_ADDR_OFFSET] | FEATURE_MASK_BR_WH_ADDR_MASK;
  638. featureMasks[FEATURE_MASK_NUM_ITEMS_OFFSET] =
  639. featureMasks[FEATURE_MASK_NUM_ITEMS_OFFSET] | FEATURE_MASK_NUM_ITEMS_MASK;
  640. featureMasks[FEATURE_MASK_COVER_ART_OFFSET] =
  641. featureMasks[FEATURE_MASK_COVER_ART_OFFSET] | FEATURE_MASK_COVER_ART_MASK;
  642. /*Player2 does not support browsing and now playing,
  643. hence updated the masks properly*/
  644. featureMasks2[FEATURE_MASK_PLAY_OFFSET] =
  645. featureMasks2[FEATURE_MASK_PLAY_OFFSET] | FEATURE_MASK_PLAY_MASK;
  646. featureMasks2[FEATURE_MASK_PAUSE_OFFSET] =
  647. featureMasks2[FEATURE_MASK_PAUSE_OFFSET] | FEATURE_MASK_PAUSE_MASK;
  648. featureMasks2[FEATURE_MASK_STOP_OFFSET] =
  649. featureMasks2[FEATURE_MASK_STOP_OFFSET] | FEATURE_MASK_STOP_MASK;
  650. featureMasks2[FEATURE_MASK_PAGE_UP_OFFSET] =
  651. featureMasks2[FEATURE_MASK_PAGE_UP_OFFSET] | FEATURE_MASK_PAGE_UP_MASK;
  652. featureMasks2[FEATURE_MASK_PAGE_DOWN_OFFSET] =
  653. featureMasks2[FEATURE_MASK_PAGE_DOWN_OFFSET] | FEATURE_MASK_PAGE_DOWN_MASK;
  654. featureMasks2[FEATURE_MASK_REWIND_OFFSET] =
  655. featureMasks2[FEATURE_MASK_REWIND_OFFSET] | FEATURE_MASK_REWIND_MASK;
  656. featureMasks2[FEATURE_MASK_FAST_FWD_OFFSET] =
  657. featureMasks2[FEATURE_MASK_FAST_FWD_OFFSET] | FEATURE_MASK_FAST_FWD_MASK;
  658. mediaPlayerInfo1 = new MediaPlayerInfo ((short)0x0001,
  659. MAJOR_TYPE_AUDIO,
  660. SUB_TYPE_NONE,
  661. (byte)PlaybackState.STATE_PAUSED,
  662. CHAR_SET_UTF8,
  663. (short)0x05,
  664. playerName1,
  665. "com.android.music",
  666. true,
  667. featureMasks);
  668. mediaPlayerInfo2 = new MediaPlayerInfo ((short)0x0000,
  669. MAJOR_TYPE_AUDIO,
  670. SUB_TYPE_NONE,
  671. (byte)PlaybackState.STATE_PAUSED,
  672. CHAR_SET_UTF8,
  673. (short)0x06,
  674. playerName2,
  675. "com.google.android.music",
  676. true,
  677. featureMasks2);
  678. mMediaPlayers.add(mediaPlayerInfo1);
  679. mMediaPlayers.add(mediaPlayerInfo2);
  680. Log.d(TAG, "Exit registerMediaPlayers()");
  681. }
  682. public static Avrcp make(Context context, A2dpService svc,
  683. int maxConnections) {
  684. if (DEBUG)
  685. Log.v(TAG, "make");
  686. Avrcp ar = new Avrcp(context, svc, maxConnections);
  687. ar.start();
  688. return ar;
  689. }
  690. public void doQuit() {
  691. if (DEBUG)
  692. Log.v(TAG, "doQuit");
  693. mHandler.removeCallbacksAndMessages(null);
  694. Looper looper = mHandler.getLooper();
  695. if (looper != null) {
  696. looper.quit();
  697. }
  698. mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionChangeListener);
  699. clearDeviceDependentFeature();
  700. for (int i = 0; i < maxAvrcpConnections; i++) {
  701. cleanupDeviceFeaturesIndex(i);
  702. }
  703. mAvrcpBipRsp.stop();
  704. try {
  705. mContext.unregisterReceiver(mIntentReceiver);
  706. } catch (Exception e) {
  707. Log.e(TAG,"Unable to unregister Avrcp receiver", e);
  708. }
  709. mMediaPlayers.clear();
  710. if (mHandler.hasMessages(MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT)) {
  711. mHandler.removeMessages(MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT);
  712. if (DEBUG)
  713. Log.v(TAG, "Addressed player message cleanup as part of doQuit");
  714. }
  715. }
  716. public void clearDeviceDependentFeature() {
  717. Log.d(TAG, "Enter clearDeviceDependentFeature()");
  718. for (int i = 0; i < maxAvrcpConnections; i++) {
  719. deviceFeatures[i].keyPressState = KEY_STATE_RELEASE; //Key release state
  720. deviceFeatures[i].mCurrentPath = PATH_INVALID;
  721. deviceFeatures[i].mMediaUri = Uri.EMPTY;
  722. deviceFeatures[i].mCurrentPathUid = null;
  723. deviceFeatures[i].mRequestedAddressedPlayerPackageName = null;
  724. if (deviceFeatures[i].mVolumeMapping != null)
  725. deviceFeatures[i].mVolumeMapping.clear();
  726. }
  727. Log.d(TAG, "Exit clearDeviceDependentFeature()");
  728. }
  729. public void cleanup() {
  730. if (DEBUG)
  731. Log.v(TAG, "cleanup");
  732. cleanupNative();
  733. Log.d(TAG, "Exit cleanup()");
  734. }
  735. private class MediaControllerListener extends MediaController.Callback {
  736. @Override
  737. public void onMetadataChanged(MediaMetadata metadata) {
  738. Log.v(TAG, "MediaController metadata changed");
  739. updateMetadata(metadata);
  740. Log.d(TAG, "Exit onMetadataChanged()");
  741. }
  742. @Override
  743. public void onPlaybackStateChanged(PlaybackState state) {
  744. Log.v(TAG, "MediaController playback changed: " + state.toString());
  745. updatePlaybackState(state, null);
  746. Log.d(TAG, "Exit onPlaybackStateChanged()");
  747. }
  748. @Override
  749. public void onSessionDestroyed() {
  750. Log.v(TAG, "MediaController session destroyed");
  751. }
  752. @Override
  753. public void onUpdateFolderInfoBrowsedPlayer(String stringUri) {
  754. Log.v(TAG, "onClientFolderInfoBrowsedPlayer: stringUri: " + stringUri);
  755. if (stringUri != null) {
  756. String[] ExternalPath = stringUri.split("/");
  757. if (ExternalPath.length < 4) {
  758. Log.d(TAG, "Wrong entries.");
  759. mHandler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, 0, INTERNAL_ERROR,
  760. null).sendToTarget();
  761. return;
  762. }
  763. Uri uri = Uri.parse(stringUri);
  764. Log.v(TAG, "URI received: " + uri);
  765. String[] SplitPath = new String[ExternalPath.length - 3];
  766. for (int count = 2; count < (ExternalPath.length - 1); count++) {
  767. SplitPath[count - 2] = ExternalPath[count];
  768. Log.d(TAG, "SplitPath[" + (count - 2) + "] = " + SplitPath[count - 2]);
  769. }
  770. Log.v(TAG, "folderDepth: " + SplitPath.length);
  771. for (int count = 0; count < SplitPath.length; count++) {
  772. Log.v(TAG, "folderName: " + SplitPath[count]);
  773. }
  774. mMediaUriStatic = uri;
  775. if (mHandler != null) {
  776. // Don't send the complete path to CK as few gets confused by that
  777. // Send only the name of the root folder
  778. mHandler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, NUM_ROOT_ELEMENTS,
  779. OPERATION_SUCCESSFUL, SplitPath).sendToTarget();
  780. }
  781. } else {
  782. mHandler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, 0, INTERNAL_ERROR,
  783. null).sendToTarget();
  784. }
  785. Log.d(TAG, "Exit onUpdateFolderInfoBrowsedPlayer()");
  786. }
  787. @Override
  788. public void onUpdateNowPlayingEntries(long[] playList) {
  789. Log.v(TAG, "onClientUpdateNowPlayingEntries");
  790. if (mHandler != null) {
  791. mHandler.obtainMessage(MSG_NOW_PLAYING_ENTRIES_RECEIVED, 0, 0,
  792. playList).sendToTarget();
  793. }
  794. Log.d(TAG, "Exit onUpdateNowPlayingEntries()");
  795. }
  796. @Override
  797. public void onUpdateNowPlayingContentChange() {
  798. Log.v(TAG, "onClientNowPlayingContentChange");
  799. if (mHandler != null) {
  800. mHandler.obtainMessage(MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED).sendToTarget();
  801. }
  802. Log.d(TAG, "Exit onUpdateNowPlayingContentChange()");
  803. }
  804. @Override
  805. public void onPlayItemResponse(boolean success) {
  806. Log.v(TAG, "onClientPlayItemResponse");
  807. if (mHandler != null) {
  808. mHandler.obtainMessage(MSG_PLAY_ITEM_RESPONSE, 0, 0, new Boolean(success))
  809. .sendToTarget();
  810. }
  811. Log.d(TAG, "Exit onPlayItemResponse()");
  812. }
  813. }
  814. private class MediaSessionChangeListener implements MediaSessionManager.OnActiveSessionsChangedListener {
  815. public MediaSessionChangeListener() {
  816. }
  817. @Override
  818. public void onActiveSessionsChanged(List<MediaController> controllers) {
  819. Log.v(TAG, "Active sessions changed, " + controllers.size() + " sessions");
  820. if (controllers.size() > 0) {
  821. updateCurrentMediaController(controllers.get(0));
  822. }
  823. Log.d(TAG, "Exit onActiveSessionsChanged()");
  824. }
  825. }
  826. private void updateCurrentMediaController(MediaController controller) {
  827. Log.v(TAG, "Updating media controller to " + controller);
  828. if (mMediaController != null) {
  829. mMediaController.unregisterCallback(mMediaControllerCb);
  830. }
  831. mMediaController = controller;
  832. if (mMediaController == null) {
  833. updateMetadata(null);
  834. return;
  835. }
  836. mMediaController.registerCallback(mMediaControllerCb, mHandler);
  837. updateMetadata(mMediaController.getMetadata());
  838. if (mHandler != null) {
  839. Log.v(TAG, "Focus gained for player: " + mMediaController.getPackageName());
  840. mHandler.obtainMessage(MSG_UPDATE_RCC_CHANGE, 1, 1,
  841. mMediaController.getPackageName()).sendToTarget();
  842. }
  843. Log.d(TAG, "Exit updateCurrentMediaController()");
  844. }
  845. /** Handles Avrcp messages. */
  846. private final class AvrcpMessageHandler extends Handler {
  847. private AvrcpMessageHandler(Looper looper) {
  848. super(looper);
  849. }
  850. @Override
  851. public void handleMessage(Message msg) {
  852. int deviceIndex = INVALID_DEVICE_INDEX;
  853. switch (msg.what) {
  854. case MESSAGE_PLAYERSETTINGS_TIMEOUT:
  855. Log.e(TAG, "**MESSAGE_PLAYSTATUS_TIMEOUT: Addr: " +
  856. (String)msg.obj + " Msg: " + msg.arg1);
  857. synchronized (mPendingCmds) {
  858. Integer val = new Integer(msg.arg1);
  859. if (!mPendingCmds.contains(val)) {
  860. break;
  861. }
  862. mPendingCmds.remove(val);
  863. }
  864. switch (msg.arg1) {
  865. case GET_ATTRIBUTE_IDS:
  866. getListPlayerappAttrRspNative((byte)def_attrib.length ,
  867. def_attrib, getByteAddress(
  868. mAdapter.getRemoteDevice((String) msg.obj)));
  869. break;
  870. case GET_VALUE_IDS:
  871. switch (mPlayerSettings.attr) {
  872. case ATTRIBUTE_REPEATMODE:
  873. getPlayerAppValueRspNative((byte)value_repmode.length,
  874. value_repmode,
  875. getByteAddress(mAdapter.getRemoteDevice(
  876. (String) msg.obj)));
  877. break;
  878. case ATTRIBUTE_SHUFFLEMODE:
  879. getPlayerAppValueRspNative((byte)value_shufmode.length,
  880. value_shufmode,
  881. getByteAddress(mAdapter.getRemoteDevice(
  882. (String) msg.obj)));
  883. break;
  884. default:
  885. getPlayerAppValueRspNative((byte)value_default.length,
  886. value_default,
  887. getByteAddress(mAdapter.getRemoteDevice(
  888. (String) msg.obj)));
  889. break;
  890. }
  891. break;
  892. case GET_ATTRIBUTE_VALUES:
  893. int j = 0;
  894. byte [] retVal = new byte [mPlayerSettings.attrIds.length*2];
  895. for (int i = 0; i < mPlayerSettings.attrIds.length; i++) {
  896. retVal[j++] = mPlayerSettings.attrIds[i];
  897. if (mPlayerSettings.attrIds[i] == ATTRIBUTE_REPEATMODE) {
  898. retVal[j++] = settingValues.repeat_value;
  899. } else if (mPlayerSettings.attrIds[i] == ATTRIBUTE_SHUFFLEMODE) {
  900. retVal[j++] = settingValues.shuffle_value;
  901. } else {
  902. retVal[j++] = 0x0;
  903. }
  904. }
  905. SendCurrentPlayerValueRspNative((byte)retVal.length ,
  906. retVal, getByteAddress(mAdapter.getRemoteDevice(
  907. (String) msg.obj)));
  908. break;
  909. case SET_ATTRIBUTE_VALUES :
  910. SendSetPlayerAppRspNative(INTERNAL_ERROR, getByteAddress(
  911. mAdapter.getRemoteDevice((String) msg.obj)));
  912. break;
  913. case GET_ATTRIBUTE_TEXT:
  914. String [] attribText = new String [mPlayerSettings.attrIds.length];
  915. for (int i = 0; i < mPlayerSettings.attrIds.length; i++) {
  916. attribText[i] = "";
  917. }
  918. sendSettingsTextRspNative(mPlayerSettings.attrIds.length ,
  919. mPlayerSettings.attrIds, attribText.length,
  920. attribText, getByteAddress(mAdapter.getRemoteDevice(
  921. (String) msg.obj)));
  922. break;
  923. case GET_VALUE_TEXT:
  924. String [] valueText = new String [mPlayerSettings.attrIds.length];
  925. for (int i = 0; i < mPlayerSettings.attrIds.length; i++) {
  926. valueText[i] = "";
  927. }
  928. sendValueTextRspNative(mPlayerSettings.attrIds.length ,
  929. mPlayerSettings.attrIds, valueText.length,
  930. valueText,getByteAddress(mAdapter.getRemoteDevice(
  931. (String) msg.obj)));
  932. break;
  933. default :
  934. Log.e(TAG,"in default case");
  935. break;
  936. }
  937. break;
  938. case MSG_UPDATE_AVAILABLE_PLAYERS:
  939. updateAvailableMediaPlayers();
  940. break;
  941. case MSG_UPDATE_ADDRESSED_PLAYER:
  942. updateAddressedMediaPlayer(msg.arg1);
  943. break;
  944. case MSG_UPDATE_BROWSED_PLAYER_FOLDER:
  945. Log.v(TAG, "MSG_UPDATE_BROWSED_PLAYER_FOLDER");
  946. updateBrowsedPlayerFolder(msg.arg1, msg.arg2, (String [])msg.obj);
  947. break;
  948. case MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED:
  949. Log.v(TAG, "MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED");
  950. updateNowPlayingContentChanged();
  951. break;
  952. case MSG_PLAY_ITEM_RESPONSE:
  953. Log.v(TAG, "MSG_PLAY_ITEM_RESPONSE");
  954. boolean success = ((Boolean)msg.obj).booleanValue();
  955. Log.v(TAG, "success: " + success);
  956. updatePlayItemResponse(success);
  957. break;
  958. case MSG_NOW_PLAYING_ENTRIES_RECEIVED:
  959. Log.v(TAG, "MSG_NOW_PLAYING_ENTRIES_RECEIVED");
  960. updateNowPlayingEntriesReceived((long [])msg.obj);
  961. break;
  962. case MESSAGE_GET_RC_FEATURES:
  963. {
  964. String address = (String) msg.obj;
  965. if (DEBUG)
  966. Log.v(TAG, "MESSAGE_GET_RC_FEATURES: address="+address+
  967. ", features="+msg.arg1);
  968. BluetoothDevice device = mAdapter.getRemoteDevice(address);
  969. deviceIndex = getIndexForDevice(device);
  970. if (deviceIndex == INVALID_DEVICE_INDEX) {
  971. Log.v(TAG,"device entry not present, bailing out");
  972. return;
  973. }
  974. deviceFeatures[deviceIndex].mFeatures = msg.arg1;
  975. deviceFeatures[deviceIndex].mFeatures =
  976. modifyRcFeatureFromBlacklist(deviceFeatures[deviceIndex].mFeatures,
  977. address);
  978. Log.d(TAG, "avrcpct-passthrough pts_test = " + pts_test);
  979. if (pts_test) {
  980. Log.v(TAG,"fake BTRC_FEAT_ABSOLUTE_VOLUME remote feat support for pts test");
  981. deviceFeatures[deviceIndex].mFeatures =
  982. deviceFeatures[deviceIndex].mFeatures | BTRC_FEAT_ABSOLUTE_VOLUME;
  983. }
  984. deviceFeatures[deviceIndex].isAbsoluteVolumeSupportingDevice =
  985. ((deviceFeatures[deviceIndex].mFeatures &
  986. BTRC_FEAT_ABSOLUTE_VOLUME) != 0);
  987. mAudioManager.avrcpSupportsAbsoluteVolume(device.getAddress(),
  988. isAbsoluteVolumeSupported());
  989. Log.v(TAG," update audio manager for abs vol state = "
  990. + isAbsoluteVolumeSupported());
  991. deviceFeatures[deviceIndex].mLastLocalVolume = -1;
  992. deviceFeatures[deviceIndex].mRemoteVolume = -1;
  993. deviceFeatures[deviceIndex].mLocalVolume = -1;
  994. devic

Large files files are truncated, but you can click here to view the full file