PageRenderTime 3691ms CodeModel.GetById 3ms RepoModel.GetById 1ms app.codeStats 1ms

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

https://gitlab.com/math4youbyusgroupillinois/android_packages_apps_Bluetooth
Java | 4153 lines | 3703 code | 359 blank | 91 comment | 812 complexity | 3cea9832f96bd230ecea89255570e06f MD5 | raw file

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

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

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