/src/com/android/bluetooth/avrcp/Avrcp.java
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
- /*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.android.bluetooth.avrcp;
- import java.util.Timer;
- import java.util.TimerTask;
- import android.app.PendingIntent;
- import android.bluetooth.BluetoothA2dp;
- import android.bluetooth.BluetoothAvrcp;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.graphics.Bitmap;
- import android.media.AudioManager;
- import android.media.IRemoteControlDisplay;
- import android.media.MediaMetadataRetriever;
- import android.media.RemoteControlClient;
- import android.media.RemoteController;
- import android.media.RemoteController.MetadataEditor;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.os.ParcelUuid;
- import android.os.PowerManager;
- import android.os.PowerManager.WakeLock;
- import android.os.RemoteException;
- import android.os.ServiceManager;
- import android.os.SystemClock;
- import android.util.Log;
- import android.view.KeyEvent;
- import android.content.BroadcastReceiver;
- import com.android.bluetooth.btservice.AdapterService;
- import com.android.bluetooth.btservice.ProfileService;
- import com.android.bluetooth.Utils;
- import com.android.internal.util.IState;
- import com.android.internal.util.State;
- import com.android.internal.util.StateMachine;
- import java.lang.ref.WeakReference;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Set;
- import java.util.Iterator;
- import android.provider.MediaStore;
- import android.content.ContentResolver;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteException;
- import android.net.Uri;
- /**
- * support Bluetooth AVRCP profile.
- * support metadata, play status and event notification
- */
- public final class Avrcp {
- private static final boolean DEBUG = true;
- private static final String TAG = "Avrcp";
- private Context mContext;
- private final AudioManager mAudioManager;
- private AvrcpMessageHandler mHandler;
- private RemoteController mRemoteController;
- private RemoteControllerWeak mRemoteControllerCb;
- private Metadata mMetadata;
- private int mTransportControlFlags;
- private int mCurrentPlayState;
- private int mPlayStatusChangedNT;
- private int mPlayerStatusChangeNT;
- private int mTrackChangedNT;
- private long mTrackNumber;
- private long mCurrentPosMs;
- private long mPlayStartTimeMs;
- private long mSongLengthMs;
- private long mPlaybackIntervalMs;
- private int mPlayPosChangedNT;
- private long mNextPosMs;
- private long mPrevPosMs;
- private long mSkipStartTime;
- private int mFeatures;
- private int mAbsoluteVolume;
- private int mLastSetVolume;
- private int mLastDirection;
- private final int mVolumeStep;
- private final int mAudioStreamMax;
- private boolean mVolCmdInProgress;
- private int mAbsVolRetryTimes;
- private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
- private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
- private int mSkipAmount;
- private int keyPressState;
- /* BTRC features */
- public static final int BTRC_FEAT_METADATA = 0x01;
- public static final int BTRC_FEAT_ABSOLUTE_VOLUME = 0x02;
- public static final int BTRC_FEAT_BROWSE = 0x04;
- /* AVRC response codes, from avrc_defs */
- private static final int AVRC_RSP_NOT_IMPL = 8;
- private static final int AVRC_RSP_ACCEPT = 9;
- private static final int AVRC_RSP_REJ = 10;
- private static final int AVRC_RSP_IN_TRANS = 11;
- private static final int AVRC_RSP_IMPL_STBL = 12;
- private static final int AVRC_RSP_CHANGED = 13;
- private static final int AVRC_RSP_INTERIM = 15;
- private static final int MESSAGE_GET_RC_FEATURES = 1;
- private static final int MESSAGE_GET_PLAY_STATUS = 2;
- private static final int MESSAGE_GET_ELEM_ATTRS = 3;
- private static final int MESSAGE_REGISTER_NOTIFICATION = 4;
- private static final int MESSAGE_PLAY_INTERVAL_TIMEOUT = 5;
- private static final int MESSAGE_VOLUME_CHANGED = 6;
- private static final int MESSAGE_ADJUST_VOLUME = 7;
- private static final int MESSAGE_SET_ABSOLUTE_VOLUME = 8;
- private static final int MESSAGE_ABS_VOL_TIMEOUT = 9;
- private static final int MESSAGE_FAST_FORWARD = 10;
- private static final int MESSAGE_REWIND = 11;
- private static final int MESSAGE_CHANGE_PLAY_POS = 12;
- private static final int MESSAGE_SET_A2DP_AUDIO_STATE = 13;
- private static final int MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT = 14;
- private static final int AVRCP_BR_RSP_TIMEOUT = 2000;
- private static final int MESSAGE_SEND_PASS_THROUGH_CMD = 2001;
- private static final int MESSAGE_SET_ADDR_PLAYER = 2002;
- private static final int MESSAGE_GET_FOLDER_ITEMS = 2003;
- private static final int MESSAGE_SET_BROWSED_PLAYER = 2004;
- private static final int MESSAGE_CHANGE_PATH = 2005;
- private static final int MESSAGE_PLAY_ITEM = 2006;
- private static final int MESSAGE_GET_ITEM_ATTRS = 2007;
- private int mAddressedPlayerChangedNT;
- private int mAvailablePlayersChangedNT;
- private int mNowPlayingContentChangedNT;
- private int mAddressedPlayerId;
- private String mRequestedAddressedPlayerPackageName;
- private CachedRequest mCachedRequest = null;
- private static final int MSG_UPDATE_STATE = 100;
- private static final int MSG_SET_METADATA = 101;
- private static final int MSG_SET_TRANSPORT_CONTROLS = 102;
- private static final int MSG_SET_GENERATION_ID = 104;
- private static final int MSG_UPDATE_AVAILABLE_PLAYERS = 201;
- private static final int MSG_UPDATE_ADDRESSED_PLAYER = 202;
- private static final int MSG_UPDATE_RCC_CHANGE = 203;
- private static final int MSG_UPDATE_BROWSED_PLAYER_FOLDER = 204;
- private static final int MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED = 205;
- private static final int MSG_PLAY_ITEM_RESPONSE = 206;
- private static final int MSG_NOW_PLAYING_ENTRIES_RECEIVED = 207;
- private MediaPlayerInfo mediaPlayerInfo1;
- private MediaPlayerInfo mediaPlayerInfo2;
- private static final int BUTTON_TIMEOUT_TIME = 2000;
- private static final int BASE_SKIP_AMOUNT = 2000;
- private static final int KEY_STATE_PRESS = 1;
- private static final int KEY_STATE_RELEASE = 0;
- private static final int SKIP_PERIOD = 400;
- private static final int SKIP_DOUBLE_INTERVAL = 3000;
- private static final long MAX_MULTIPLIER_VALUE = 128L;
- private static final int CMD_TIMEOUT_DELAY = 2000;
- private static final int MAX_ERROR_RETRY_TIMES = 3;
- private static final int AVRCP_MAX_VOL = 127;
- private static final int AVRCP_BASE_VOLUME_STEP = 1;
- private final static int MESSAGE_PLAYERSETTINGS_TIMEOUT = 602;
- private static final int AVRCP_CONNECTED = 1;
- public static final int KEY_STATE_PRESSED = 0;
- public static final int KEY_STATE_RELEASED = 1;
- private String mCurrentPath;
- private String mCurrentPathUid;
- private static Uri mMediaUri;
- private final static int TYPE_MEDIA_PLAYER_ITEM = 0x01;
- private final static int TYPE_FOLDER_ITEM = 0x02;
- private final static int TYPE_MEDIA_ELEMENT_ITEM = 0x03;
- private final static int FOLDER_UP = 0x00;
- private final static int FOLDER_DOWN = 0x01;
- private static final String PATH_INVALID = "invalid";
- private static final String PATH_ROOT = "root";
- private static final String PATH_TITLES = "titles";
- private static final String PATH_ALBUMS = "albums";
- private static final String PATH_ARTISTS = "artists";
- private static final String PATH_PLAYLISTS = "playlists";
- private final static long UID_TITLES = 0x01;
- private final static long UID_ALBUM = 0x02;
- private final static long UID_ARTIST = 0x03;
- private final static long UID_PLAYLIST = 0x04;
- private final static int NUM_ROOT_ELEMENTS = 0x04;
- private static final int INTERNAL_ERROR = 0x03;
- private static final int OPERATION_SUCCESSFUL = 0x04;
- private static final int INVALID_DIRECTION = 0x07;
- private static final int NOT_A_DIRECTORY = 0x08;
- private static final int DOES_NOT_EXIST = 0x09;
- private static final int INVALID_SCOPE = 0x0a;
- private static final int RANGE_OUT_OF_BOUNDS = 0x0b;
- private static final int UID_A_DIRECTORY = 0x0c;
- private static final int MEDIA_IN_USE = 0x0d;
- private static final int INVALID_PLAYER_ID = 0x11;
- private static final int PLAYER_NOT_BROWSABLE = 0x12;
- private static final int PLAYER_NOT_ADDRESSED = 0x13;
- private static final int FOLDER_TYPE_MIXED = 0x00;
- private static final int FOLDER_TYPE_TITLES = 0x01;
- private static final int FOLDER_TYPE_ALBUMS = 0x02;
- private static final int FOLDER_TYPE_ARTISTS = 0x03;
- private static final int FOLDER_TYPE_GENRES = 0x04;
- private static final int FOLDER_TYPE_PLAYLISTS = 0x05;
- private static final int MEDIA_TYPE_AUDIO = 0X00;
- private static final int MEDIA_TYPE_VIDEO = 0X01;
- private static final int MAX_BROWSE_ITEM_TO_SEND = 0x03;
- private static final int MAX_ATTRIB_COUNT = 0x07;
- private final static int ALBUMS_ITEM_INDEX = 0;
- private final static int ARTISTS_ITEM_INDEX = 1;
- private final static int PLAYLISTS_ITEM_INDEX = 2;
- private final static int TITLES_ITEM_INDEX = 3;
- //Intents for PlayerApplication Settings
- private static final String PLAYERSETTINGS_REQUEST = "org.codeaurora.music.playersettingsrequest";
- private static final String PLAYERSETTINGS_RESPONSE =
- "org.codeaurora.music.playersettingsresponse";
- private class PlayerSettings {
- public byte attr;
- public byte [] attrIds;
- public String path;
- };
- private PlayerSettings mPlayerSettings = new PlayerSettings();
- private class localPlayerSettings {
- public byte eq_value = 0x01;
- public byte repeat_value = 0x01;
- public byte shuffle_value = 0x01;
- public byte scan_value = 0x01;
- };
- private localPlayerSettings settingValues = new localPlayerSettings();
- private static final String COMMAND = "command";
- private static final String CMDGET = "get";
- private static final String CMDSET = "set";
- private static final String EXTRA_GET_COMMAND = "commandExtra";
- private static final String EXTRA_GET_RESPONSE = "Response";
- private static final int GET_ATTRIBUTE_IDS = 0;
- private static final int GET_VALUE_IDS = 1;
- private static final int GET_ATTRIBUTE_TEXT = 2;
- private static final int GET_VALUE_TEXT = 3;
- private static final int GET_ATTRIBUTE_VALUES = 4;
- private static final int NOTIFY_ATTRIBUTE_VALUES = 5;
- private static final int SET_ATTRIBUTE_VALUES = 6;
- private static final int GET_INVALID = 0xff;
- private static final String EXTRA_ATTRIBUTE_ID = "Attribute";
- private static final String EXTRA_VALUE_STRING_ARRAY = "ValueStrings";
- private static final String EXTRA_ATTRIB_VALUE_PAIRS = "AttribValuePairs";
- private static final String EXTRA_ATTRIBUTE_STRING_ARRAY = "AttributeStrings";
- private static final String EXTRA_VALUE_ID_ARRAY = "Values";
- private static final String EXTRA_ATTIBUTE_ID_ARRAY = "Attributes";
- public static final int VALUE_SHUFFLEMODE_OFF = 1;
- public static final int VALUE_SHUFFLEMODE_ALL = 2;
- public static final int VALUE_REPEATMODE_OFF = 1;
- public static final int VALUE_REPEATMODE_SINGLE = 2;
- public static final int VALUE_REPEATMODE_ALL = 3;
- public static final int VALUE_INVALID = 0;
- public static final int ATTRIBUTE_NOTSUPPORTED = -1;
- public static final int ATTRIBUTE_EQUALIZER = 1;
- public static final int ATTRIBUTE_REPEATMODE = 2;
- public static final int ATTRIBUTE_SHUFFLEMODE = 3;
- public static final int ATTRIBUTE_SCANMODE = 4;
- public static final int NUMPLAYER_ATTRIBUTE = 2;
- private byte [] def_attrib = new byte [] {ATTRIBUTE_REPEATMODE, ATTRIBUTE_SHUFFLEMODE};
- private byte [] value_repmode = new byte [] { VALUE_REPEATMODE_OFF,
- VALUE_REPEATMODE_SINGLE,
- VALUE_REPEATMODE_ALL };
- private byte [] value_shufmode = new byte [] { VALUE_SHUFFLEMODE_OFF,
- VALUE_SHUFFLEMODE_ALL };
- private byte [] value_default = new byte [] {0};
- private final String UPDATE_ATTRIBUTES = "UpdateSupportedAttributes";
- private final String UPDATE_VALUES = "UpdateSupportedValues";
- private final String UPDATE_ATTRIB_VALUE = "UpdateCurrentValues";
- private final String UPDATE_ATTRIB_TEXT = "UpdateAttributesText";
- private final String UPDATE_VALUE_TEXT = "UpdateValuesText";
- private ArrayList <Integer> mPendingCmds;
- private ArrayList <Integer> mPendingSetAttributes;
- static {
- classInitNative();
- }
- private Avrcp(Context context) {
- if (DEBUG) Log.v(TAG, "Avrcp");
- mMetadata = new Metadata();
- mCurrentPlayState = RemoteControlClient.PLAYSTATE_NONE; // until we get a callback
- mPlayStatusChangedNT = NOTIFICATION_TYPE_CHANGED;
- mTrackChangedNT = NOTIFICATION_TYPE_CHANGED;
- mPlayerStatusChangeNT = NOTIFICATION_TYPE_CHANGED;
- mAddressedPlayerChangedNT = NOTIFICATION_TYPE_CHANGED;
- mAvailablePlayersChangedNT = NOTIFICATION_TYPE_CHANGED;
- mNowPlayingContentChangedNT = NOTIFICATION_TYPE_CHANGED;
- mTrackNumber = -1L;
- mCurrentPosMs = -1L;
- mPlayStartTimeMs = -1L;
- mSongLengthMs = 0L;
- mPlaybackIntervalMs = 0L;
- mAddressedPlayerId = 0; // 0 signifies bad entry
- mPlayPosChangedNT = NOTIFICATION_TYPE_CHANGED;
- mFeatures = 0;
- mAbsoluteVolume = -1;
- mLastSetVolume = -1;
- mLastDirection = 0;
- mVolCmdInProgress = false;
- mAbsVolRetryTimes = 0;
- keyPressState = KEY_STATE_RELEASE; //Key release state
- mContext = context;
- mCurrentPath = PATH_INVALID;
- mCurrentPathUid = null;
- mMediaUri = Uri.EMPTY;
- initNative();
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- mAudioStreamMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
- mVolumeStep = Math.max(AVRCP_BASE_VOLUME_STEP, AVRCP_MAX_VOL/mAudioStreamMax);
- }
- private void start() {
- if (DEBUG) Log.v(TAG, "start");
- HandlerThread thread = new HandlerThread("BluetoothAvrcpHandler");
- thread.start();
- Looper looper = thread.getLooper();
- mHandler = new AvrcpMessageHandler(looper);
- mPendingCmds = new ArrayList<Integer>();
- mPendingSetAttributes = new ArrayList<Integer>();
- mCurrentPath = PATH_INVALID;
- mCurrentPathUid = null;
- mMediaUri = Uri.EMPTY;
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(AudioManager.RCC_CHANGED_ACTION);
- intentFilter.addAction(PLAYERSETTINGS_RESPONSE);
- try {
- mContext.registerReceiver(mIntentReceiver, intentFilter);
- }catch (Exception e) {
- Log.e(TAG,"Unable to register Avrcp receiver", e);
- }
- registerMediaPlayers();
- mRemoteControllerCb = new RemoteControllerWeak(mHandler);
- mRemoteController = new RemoteController(mContext, mRemoteControllerCb);
- mAudioManager.registerRemoteController(mRemoteController);
- mRemoteController.setSynchronizationMode(RemoteController.POSITION_SYNCHRONIZATION_CHECK);
- }
- //Listen to intents from MediaPlayer and Audio Manager and update data structures
- private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(AudioManager.RCC_CHANGED_ACTION)) {
- Log.v(TAG, "received RCC_CHANGED_ACTION");
- int isRCCFocussed = 0;
- int isRCCAvailable = 0;
- String callingPackageName = intent.getStringExtra(AudioManager.EXTRA_CALLING_PACKAGE_NAME);
- boolean isFocussed = intent.getBooleanExtra(AudioManager.EXTRA_FOCUS_CHANGED_VALUE,false);
- boolean isAvailable = intent.getBooleanExtra(AudioManager.EXTRA_AVAILABLITY_CHANGED_VALUE, false);
- if (isFocussed)
- isRCCFocussed = 1;
- if (isAvailable)
- isRCCAvailable = 1;
- Log.v(TAG, "focus: " + isFocussed + " , availability: " + isAvailable);
- if (mHandler != null) {
- mHandler.obtainMessage(MSG_UPDATE_RCC_CHANGE, isRCCFocussed, isRCCAvailable, callingPackageName).sendToTarget();
- }
- } else if (action.equals(PLAYERSETTINGS_RESPONSE)) {
- int getResponse = intent.getIntExtra(EXTRA_GET_RESPONSE,
- GET_INVALID);
- byte [] data;
- String [] text;
- boolean isSetAttrValRsp = false;
- synchronized (mPendingCmds) {
- Integer val = new Integer(getResponse);
- if (mPendingCmds.contains(val)) {
- if (getResponse == SET_ATTRIBUTE_VALUES) {
- isSetAttrValRsp = true;
- if (DEBUG) Log.v(TAG,"Response received for SET_ATTRIBUTE_VALUES");
- }
- mHandler.removeMessages(MESSAGE_PLAYERSETTINGS_TIMEOUT);
- mPendingCmds.remove(val);
- }
- }
- if (DEBUG) Log.v(TAG,"getResponse " + getResponse);
- switch (getResponse) {
- case GET_ATTRIBUTE_IDS:
- data = intent.getByteArrayExtra(EXTRA_ATTIBUTE_ID_ARRAY);
- byte numAttr = (byte) data.length;
- if (DEBUG) Log.v(TAG,"GET_ATTRIBUTE_IDS");
- getListPlayerappAttrRspNative(numAttr,data);
- break;
- case GET_VALUE_IDS:
- data = intent.getByteArrayExtra(EXTRA_VALUE_ID_ARRAY);
- numAttr = (byte) data.length;
- if (DEBUG) Log.v(TAG,"GET_VALUE_IDS " + numAttr);
- getPlayerAppValueRspNative(numAttr, data);
- break;
- case GET_ATTRIBUTE_VALUES:
- data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS);
- updateLocalPlayerSettings(data);
- numAttr = (byte) data.length;
- if (DEBUG) Log.v(TAG,"GET_ATTRIBUTE_VALUES " + numAttr);
- SendCurrentPlayerValueRspNative(numAttr, data);
- break;
- case SET_ATTRIBUTE_VALUES:
- data = intent.getByteArrayExtra(EXTRA_ATTRIB_VALUE_PAIRS);
- updateLocalPlayerSettings(data);
- Log.v(TAG,"SET_ATTRIBUTE_VALUES: ");
- if (isSetAttrValRsp){
- isSetAttrValRsp = false;
- Log.v(TAG,"Respond to SET_ATTRIBUTE_VALUES request");
- if (checkPlayerAttributeResponse(data)) {
- SendSetPlayerAppRspNative(OPERATION_SUCCESSFUL);
- } else {
- SendSetPlayerAppRspNative(INTERNAL_ERROR);
- }
- }
- if (mPlayerStatusChangeNT == NOTIFICATION_TYPE_INTERIM) {
- Log.v(TAG,"Send Player appl attribute changed response");
- mPlayerStatusChangeNT = NOTIFICATION_TYPE_CHANGED;
- sendPlayerAppChangedRsp(mPlayerStatusChangeNT);
- } else {
- Log.v(TAG,"Drop Set Attr Val update from media player");
- }
- break;
- case GET_ATTRIBUTE_TEXT:
- text = intent.getStringArrayExtra(EXTRA_ATTRIBUTE_STRING_ARRAY);
- sendSettingsTextRspNative(mPlayerSettings.attrIds.length ,
- mPlayerSettings.attrIds, text.length,text);
- if (DEBUG) Log.v(TAG,"mPlayerSettings.attrIds"
- + mPlayerSettings.attrIds.length);
- break;
- case GET_VALUE_TEXT:
- text = intent.getStringArrayExtra(EXTRA_VALUE_STRING_ARRAY);
- sendValueTextRspNative(mPlayerSettings.attrIds.length ,
- mPlayerSettings.attrIds, text.length , text);
- break;
- }
- }
- }
- };
- /* This method is used for create entries of existing media players on RCD start
- * Later when media players become avaialable corresponding entries
- * are marked accordingly and similarly when media players changes focus
- * the corresponding fields are modified */
- private void registerMediaPlayers () {
- if (DEBUG) Log.v(TAG, "registerMediaPlayers");
- int[] featureMasks = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- int[] featureMasks2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- byte[] playerName1 = {0x4d, 0x75, 0x73, 0x69, 0x63}/*Music*/;
- byte[] playerName2 = {0x4d, 0x75, 0x73, 0x69, 0x63, 0x32}/*Music2*/;
- featureMasks[FEATURE_MASK_PLAY_OFFSET] =
- featureMasks[FEATURE_MASK_PLAY_OFFSET] | FEATURE_MASK_PLAY_MASK;
- featureMasks[FEATURE_MASK_PAUSE_OFFSET] =
- featureMasks[FEATURE_MASK_PAUSE_OFFSET] | FEATURE_MASK_PAUSE_MASK;
- featureMasks[FEATURE_MASK_STOP_OFFSET] =
- featureMasks[FEATURE_MASK_STOP_OFFSET] | FEATURE_MASK_STOP_MASK;
- featureMasks[FEATURE_MASK_PAGE_UP_OFFSET] =
- featureMasks[FEATURE_MASK_PAGE_UP_OFFSET] | FEATURE_MASK_PAGE_UP_MASK;
- featureMasks[FEATURE_MASK_PAGE_DOWN_OFFSET] =
- featureMasks[FEATURE_MASK_PAGE_DOWN_OFFSET] | FEATURE_MASK_PAGE_DOWN_MASK;
- featureMasks[FEATURE_MASK_REWIND_OFFSET] =
- featureMasks[FEATURE_MASK_REWIND_OFFSET] | FEATURE_MASK_REWIND_MASK;
- featureMasks[FEATURE_MASK_FAST_FWD_OFFSET] =
- featureMasks[FEATURE_MASK_FAST_FWD_OFFSET] | FEATURE_MASK_FAST_FWD_MASK;
- featureMasks[FEATURE_MASK_VENDOR_OFFSET] =
- featureMasks[FEATURE_MASK_VENDOR_OFFSET] | FEATURE_MASK_VENDOR_MASK;
- featureMasks[FEATURE_MASK_ADV_CTRL_OFFSET] =
- featureMasks[FEATURE_MASK_ADV_CTRL_OFFSET] | FEATURE_MASK_ADV_CTRL_MASK;
- featureMasks[FEATURE_MASK_BROWSE_OFFSET] =
- featureMasks[FEATURE_MASK_BROWSE_OFFSET] | FEATURE_MASK_BROWSE_MASK;
- featureMasks[FEATURE_MASK_NOW_PLAY_OFFSET] =
- featureMasks[FEATURE_MASK_NOW_PLAY_OFFSET] | FEATURE_MASK_NOW_PLAY_MASK;
- featureMasks[FEATURE_MASK_BR_WH_ADDR_OFFSET] =
- featureMasks[FEATURE_MASK_BR_WH_ADDR_OFFSET] | FEATURE_MASK_BR_WH_ADDR_MASK;
- /*Google player does not support browsing and now playing,
- hence updated the masks properly*/
- featureMasks2[FEATURE_MASK_PLAY_OFFSET] =
- featureMasks2[FEATURE_MASK_PLAY_OFFSET] | FEATURE_MASK_PLAY_MASK;
- featureMasks2[FEATURE_MASK_PAUSE_OFFSET] =
- featureMasks2[FEATURE_MASK_PAUSE_OFFSET] | FEATURE_MASK_PAUSE_MASK;
- featureMasks2[FEATURE_MASK_STOP_OFFSET] =
- featureMasks2[FEATURE_MASK_STOP_OFFSET] | FEATURE_MASK_STOP_MASK;
- featureMasks2[FEATURE_MASK_PAGE_UP_OFFSET] =
- featureMasks2[FEATURE_MASK_PAGE_UP_OFFSET] | FEATURE_MASK_PAGE_UP_MASK;
- featureMasks2[FEATURE_MASK_PAGE_DOWN_OFFSET] =
- featureMasks2[FEATURE_MASK_PAGE_DOWN_OFFSET] | FEATURE_MASK_PAGE_DOWN_MASK;
- featureMasks2[FEATURE_MASK_REWIND_OFFSET] =
- featureMasks2[FEATURE_MASK_REWIND_OFFSET] | FEATURE_MASK_REWIND_MASK;
- featureMasks2[FEATURE_MASK_FAST_FWD_OFFSET] =
- featureMasks2[FEATURE_MASK_FAST_FWD_OFFSET] | FEATURE_MASK_FAST_FWD_MASK;
- featureMasks2[FEATURE_MASK_VENDOR_OFFSET] =
- featureMasks2[FEATURE_MASK_VENDOR_OFFSET] | FEATURE_MASK_VENDOR_MASK;
- featureMasks2[FEATURE_MASK_ADV_CTRL_OFFSET] =
- featureMasks2[FEATURE_MASK_ADV_CTRL_OFFSET] | FEATURE_MASK_ADV_CTRL_MASK;
- mediaPlayerInfo1 = new MediaPlayerInfo ((short)0x0001,
- MAJOR_TYPE_AUDIO,
- SUB_TYPE_NONE,
- (byte)RemoteControlClient.PLAYSTATE_PAUSED,
- CHAR_SET_UTF8,
- (short)0x05,
- playerName1,
- "com.android.music",
- true,
- featureMasks);
- mediaPlayerInfo2 = new MediaPlayerInfo ((short)0x0002,
- MAJOR_TYPE_AUDIO,
- SUB_TYPE_NONE,
- (byte)RemoteControlClient.PLAYSTATE_PAUSED,
- CHAR_SET_UTF8,
- (short)0x06,
- playerName2,
- "com.google.android.music",
- false,
- featureMasks2);
- mMediaPlayers.add(mediaPlayerInfo1);
- mMediaPlayers.add(mediaPlayerInfo2);
- }
- public static Avrcp make(Context context) {
- if (DEBUG) Log.v(TAG, "make");
- Avrcp ar = new Avrcp(context);
- ar.start();
- return ar;
- }
- public void doQuit() {
- if (DEBUG) Log.v(TAG, "doQuit");
- mHandler.removeCallbacksAndMessages(null);
- Looper looper = mHandler.getLooper();
- if (looper != null) {
- looper.quit();
- }
- mAudioManager.unregisterRemoteController(mRemoteController);
- keyPressState = KEY_STATE_RELEASE; //Key release state
- try {
- mContext.unregisterReceiver(mIntentReceiver);
- }catch (Exception e) {
- Log.e(TAG,"Unable to unregister Avrcp receiver", e);
- }
- mMediaPlayers.clear();
- if (mHandler.hasMessages(MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT)) {
- mHandler.removeMessages(MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT);
- mRequestedAddressedPlayerPackageName = null;
- if (DEBUG) Log.v(TAG, "Addressed player message cleanup as part of doQuit");
- }
- mCurrentPath = PATH_INVALID;
- mMediaUri = Uri.EMPTY;
- mCurrentPathUid = null;
- }
- public void cleanup() {
- if (DEBUG) Log.v(TAG, "cleanup");
- cleanupNative();
- }
- private static class RemoteControllerWeak implements RemoteController.OnClientUpdateListener {
- private final WeakReference<Handler> mLocalHandler;
- public RemoteControllerWeak(Handler handler) {
- mLocalHandler = new WeakReference<Handler>(handler);
- }
- @Override
- public void onClientChange(boolean clearing) {
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_SET_GENERATION_ID,
- 0, (clearing ? 1 : 0), null).sendToTarget();
- }
- }
- @Override
- public void onClientPlaybackStateUpdate(int state) {
- // Should never be called with the existing code, but just in case
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_UPDATE_STATE, 0, state,
- new Long(RemoteControlClient.PLAYBACK_POSITION_INVALID)).sendToTarget();
- }
- }
- @Override
- public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs,
- long currentPosMs, float speed) {
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_UPDATE_STATE, 0, state,
- new Long(currentPosMs)).sendToTarget();
- }
- }
- @Override
- public void onClientTransportControlUpdate(int transportControlFlags) {
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_SET_TRANSPORT_CONTROLS, 0, transportControlFlags)
- .sendToTarget();
- }
- }
- @Override
- public void onClientMetadataUpdate(MetadataEditor metadataEditor) {
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_SET_METADATA, 0, 0, metadataEditor).sendToTarget();
- }
- }
- @Override
- public void onClientFolderInfoBrowsedPlayer(String stringUri) {
- Log.v(TAG, "onClientFolderInfoBrowsedPlayer: stringUri: " + stringUri);
- Handler handler = mLocalHandler.get();
- if (stringUri != null) {
- String[] ExternalPath = stringUri.split("/");
- if (ExternalPath.length < 4) {
- Log.d(TAG, "Wrong entries.");
- handler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, 0, 0, null)
- .sendToTarget();
- return;
- }
- Uri uri = Uri.parse(stringUri);
- Log.v(TAG, "URI received: " + uri);
- String[] SplitPath = new String[ExternalPath.length - 3];
- for (int count = 2; count < (ExternalPath.length - 1); count++) {
- SplitPath[count - 2] = ExternalPath[count];
- Log.d(TAG, "SplitPath[" + (count - 2) + "] = " + SplitPath[count - 2]);
- }
- Log.v(TAG, "folderDepth: " + SplitPath.length);
- for (int count = 0; count < SplitPath.length; count++) {
- Log.v(TAG, "folderName: " + SplitPath[count]);
- }
- mMediaUri = uri;
- if (handler != null) {
- // Don't send the complete path to CK as few gets confused by that
- // Send only the name of the root folder
- handler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, NUM_ROOT_ELEMENTS,
- 1, SplitPath).sendToTarget();
- }
- } else {
- handler.obtainMessage(MSG_UPDATE_BROWSED_PLAYER_FOLDER, 0, 0, null)
- .sendToTarget();
- }
- }
- @Override
- public void onClientUpdateNowPlayingEntries(long[] playList) {
- Log.v(TAG, "onClientUpdateNowPlayingEntries");
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_NOW_PLAYING_ENTRIES_RECEIVED, 0, 0,
- playList).sendToTarget();
- }
- }
- @Override
- public void onClientNowPlayingContentChange() {
- Log.v(TAG, "onClientNowPlayingContentChange");
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED).sendToTarget();
- }
- }
- @Override
- public void onClientPlayItemResponse(boolean success) {
- Log.v(TAG, "onClientPlayItemResponse");
- Handler handler = mLocalHandler.get();
- if (handler != null) {
- handler.obtainMessage(MSG_PLAY_ITEM_RESPONSE, 0, 0, new Boolean(success))
- .sendToTarget();
- }
- }
- }
- /** Handles Avrcp messages. */
- private final class AvrcpMessageHandler extends Handler {
- private AvrcpMessageHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_PLAYERSETTINGS_TIMEOUT:
- if (DEBUG) Log.v(TAG, "**MESSAGE_PLAYSTATUS_TIMEOUT");
- synchronized (mPendingCmds) {
- Integer val = new Integer(msg.arg1);
- if (!mPendingCmds.contains(val)) {
- break;
- }
- mPendingCmds.remove(val);
- }
- switch (msg.arg1) {
- case GET_ATTRIBUTE_IDS:
- getListPlayerappAttrRspNative((byte)def_attrib.length, def_attrib);
- break;
- case GET_VALUE_IDS:
- if (DEBUG) Log.v(TAG, "GET_VALUE_IDS");
- switch (mPlayerSettings.attr) {
- case ATTRIBUTE_REPEATMODE:
- getPlayerAppValueRspNative((byte)value_repmode.length, value_repmode);
- break;
- case ATTRIBUTE_SHUFFLEMODE:
- getPlayerAppValueRspNative((byte)value_shufmode.length, value_shufmode);
- break;
- default:
- getPlayerAppValueRspNative((byte)value_default.length, value_default);
- break;
- }
- break;
- case GET_ATTRIBUTE_VALUES:
- int j = 0;
- byte [] retVal = new byte [mPlayerSettings.attrIds.length*2];
- for (int i = 0; i < mPlayerSettings.attrIds.length; i++) {
- retVal[j++] = mPlayerSettings.attrIds[i];
- if (mPlayerSettings.attrIds[i] == ATTRIBUTE_REPEATMODE) {
- retVal[j++] = settingValues.repeat_value;
- } else if (mPlayerSettings.attrIds[i] == ATTRIBUTE_SHUFFLEMODE) {
- retVal[j++] = settingValues.shuffle_value;
- } else {
- retVal[j++] = 0x0;
- }
- }
- SendCurrentPlayerValueRspNative((byte)retVal.length, retVal);
- break;
- case SET_ATTRIBUTE_VALUES :
- SendSetPlayerAppRspNative(INTERNAL_ERROR);
- break;
- case GET_ATTRIBUTE_TEXT:
- case GET_VALUE_TEXT:
- String [] values = new String [mPlayerSettings.attrIds.length];
- String msgVal = (msg.what == GET_ATTRIBUTE_TEXT) ? UPDATE_ATTRIB_TEXT :
- UPDATE_VALUE_TEXT;
- for (int i = 0; i < mPlayerSettings.attrIds.length; i++) {
- values[i] = "";
- }
- if (msg.arg1 == GET_ATTRIBUTE_TEXT) {
- sendSettingsTextRspNative(mPlayerSettings.attrIds.length,
- mPlayerSettings.attrIds, values.length, values);
- } else {
- sendValueTextRspNative(mPlayerSettings.attrIds.length,
- mPlayerSettings.attrIds, values.length, values);
- }
- break;
- default :
- break;
- }
- break;
- case MSG_UPDATE_STATE:
- updatePlayPauseState(msg.arg2, ((Long) msg.obj).longValue());
- break;
- case MSG_SET_METADATA:
- updateMetadata((MetadataEditor) msg.obj);
- break;
- case MSG_UPDATE_AVAILABLE_PLAYERS:
- updateAvailableMediaPlayers();
- break;
- case MSG_UPDATE_ADDRESSED_PLAYER:
- updateAddressedMediaPlayer(msg.arg1);
- break;
- case MSG_UPDATE_BROWSED_PLAYER_FOLDER:
- Log.v(TAG, "MSG_UPDATE_BROWSED_PLAYER_FOLDER");
- updateBrowsedPlayerFolder(msg.arg1, msg.arg2, (String [])msg.obj);
- break;
- case MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED:
- Log.v(TAG, "MSG_UPDATE_NOW_PLAYING_CONTENT_CHANGED");
- updateNowPlayingContentChanged();
- break;
- case MSG_PLAY_ITEM_RESPONSE:
- Log.v(TAG, "MSG_PLAY_ITEM_RESPONSE");
- boolean success = ((Boolean)msg.obj).booleanValue();
- Log.v(TAG, "success: " + success);
- updatePlayItemResponse(success);
- break;
- case MSG_NOW_PLAYING_ENTRIES_RECEIVED:
- Log.v(TAG, "MSG_NOW_PLAYING_ENTRIES_RECEIVED");
- updateNowPlayingEntriesReceived((long [])msg.obj);
- break;
- case MSG_SET_TRANSPORT_CONTROLS:
- updateTransportControls(msg.arg2);
- break;
- case MSG_SET_GENERATION_ID:
- if (DEBUG) Log.v(TAG, "New genId = " + msg.arg1 + ", clearing = " + msg.arg2);
- break;
- case MESSAGE_GET_RC_FEATURES:
- String address = (String) msg.obj;
- if (DEBUG) Log.v(TAG, "MESSAGE_GET_RC_FEATURES: address="+address+
- ", features="+msg.arg1);
- mFeatures = msg.arg1;
- mAudioManager.avrcpSupportsAbsoluteVolume(address, isAbsoluteVolumeSupported());
- break;
- case MESSAGE_GET_PLAY_STATUS:
- if (DEBUG) Log.v(TAG, "MESSAGE_GET_PLAY_STATUS");
- getPlayStatusRspNative(convertPlayStateToPlayStatus(mCurrentPlayState),
- (int)mSongLengthMs, (int)getPlayPosition());
- break;
- case MESSAGE_GET_ELEM_ATTRS:
- {
- String[] textArray;
- int[] attrIds;
- byte numAttr = (byte) msg.arg1;
- ArrayList<Integer> attrList = (ArrayList<Integer>) msg.obj;
- if (DEBUG) Log.v(TAG, "MESSAGE_GET_ELEM_ATTRS:numAttr=" + numAttr);
- attrIds = new int[numAttr];
- textArray = new String[numAttr];
- for (int i = 0; i < numAttr; ++i) {
- attrIds[i] = attrList.get(i).intValue();
- textArray[i] = getAttributeString(attrIds[i]);
- }
- getElementAttrRspNative(numAttr, attrIds, textArray);
- break;
- }
- case MESSAGE_REGISTER_NOTIFICATION:
- if (DEBUG) Log.v(TAG, "MESSAGE_REGISTER_NOTIFICATION:event=" + msg.arg1 +
- " param=" + msg.arg2);
- processRegisterNotification(msg.arg1, msg.arg2);
- break;
- case MESSAGE_PLAY_INTERVAL_TIMEOUT:
- if (DEBUG) Log.v(TAG, "MESSAGE_PLAY_INTERVAL_TIMEOUT");
- mPlayPosChangedNT = NOTIFICATION_TYPE_CHANGED;
- registerNotificationRspPlayPosNative(mPlayPosChangedNT, (int)getPlayPosition());
- break;
- case MESSAGE_SET_ADDR_PLAYER_REQ_TIMEOUT:
- if (DEBUG) Log.v(TAG, "setAddressedPlayer fails, Times out");
- setAdressedPlayerRspNative ((byte)PLAYER_NOT_ADDRESSED);
- mRequestedAddressedPlayerPackageName = null;
- break;
- case MESSAGE_VOLUME_CHANGED:
- if (DEBUG) Log.v(TAG, "MESSAGE_VOLUME_CHANGED: volume=" + ((byte)msg.arg1 & 0x7f)
- + " ctype=" + msg.arg2);
- if (msg.arg2 == AVRC_RSP_ACCEPT || msg.arg2 == AVRC_RSP_REJ) {
- if (mVolCmdInProgress == false) {
- Log.e(TAG, "Unsolicited response, ignored");
- break;
- }
- removeMessages(MESSAGE_ABS_VOL_TIMEOUT);
- mVolCmdInProgress = false;
- mAbsVolRetryTimes = 0;
- }
- if (mAbsoluteVolume != msg.arg1 && (msg.arg2 == AVRC_RSP_ACCEPT ||
- msg.arg2 == AVRC_RSP_CHANGED ||
- msg.arg2 == AVRC_RSP_INTERIM)) {
- byte absVol = (byte)((byte)msg.arg1 & 0x7f); // discard MSB as it is RFD
- notifyVolumeChanged(absVol);
- mAbsoluteVolume = absVol;
- long pecentVolChanged = ((long)absVol * 100) / 0x7f;
- Log.e(TAG, "percent volume changed: " + pecentVolChanged + "%");
- } else if (msg.arg2 == AVRC_RSP_REJ) {
- Log.e(TAG, "setAbsoluteVolume call rejected");
- }
- break;
- case MESSAGE_ADJUST_VOLUME:
- if (DEBUG) Log.d(TAG, "MESSAGE_ADJUST_VOLUME: direction=" + msg.arg1);
- if (mVolCmdInProgress) {
- if (DEBUG) Log.w(TAG, "There is already a volume command in progress.");
- break;
- }
- // Wait on verification on volume from device, before changing the volume.
- if (mAbsoluteVolume != -1 && (msg.arg1 == -1 || msg.arg1 == 1)) {
- int setVol = Math.min(AVRCP_MAX_VOL,
- Math.max(0, mAbsoluteVolume + msg.arg1*mVolumeStep));
- if (setVolumeNative(setVol)) {
- sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT),
- CMD_TIMEOUT_DELAY);
- mVolCmdInProgress = true;
- mLastDirection = msg.arg1;
- mLastSetVolume = setVol;
- }
- } else {
- Log.e(TAG, "Unknown direction in MESSAGE_ADJUST_VOLUME");
- }
- break;
- case MESSAGE_SET_ABSOLUTE_VOLUME:
- if (DEBUG) Log.v(TAG, "MESSAGE_SET_ABSOLUTE_VOLUME");
- if (mVolCmdInProgress) {
- if (DEBUG) Log.w(TAG, "There is already a volume command in progress.");
- break;
- }
- if (setVolumeNative(msg.arg1)) {
- sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT), CMD_TIMEOUT_DELAY);
- mVolCmdInProgress = true;
- mLastSetVolume = msg.arg1;
- }
- break;
- case MESSAGE_ABS_VOL_TIMEOUT:
- if (DEBUG) Log.v(TAG, "MESSAGE_ABS_VOL_TIMEOUT: Volume change cmd timed out.");
- mVolCmdInProgress = false;
- if (mAbsVolRetryTimes >= MAX_ERROR_RETRY_TIMES) {
- mAbsVolRetryTimes = 0;
- } else {
- mAbsVolRetryTimes += 1;
- if (setVolumeNative(mLastSetVolume)) {
- sendMessageDelayed(obtainMessage(MESSAGE_ABS_VOL_TIMEOUT),
- CMD_TIMEOUT_DELAY);
- mVolCmdInProgress = true;
- }
- }
- break;
- case MESSAGE_FAST_FORWARD:
- case MESSAGE_REWIND:
- if(msg.what == MESSAGE_FAST_FORWARD) {
- if((mTransportControlFlags &
- RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD) != 0) {
- int keyState = msg.arg1 == KEY_STATE_PRESS ?
- KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
- KeyEvent keyEvent =
- new KeyEvent(keyState, KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
- mRemoteController.sendMediaKeyEvent(keyEvent);
- break;
- }
- } else if((mTransportControlFlags &
- RemoteControlClient.FLAG_KEY_MEDIA_REWIND) != 0) {
- int keyState = msg.arg1 == KEY_STATE_PRESS ?
- KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP;
- KeyEvent keyEvent =
- new KeyEvent(keyState, KeyEvent.KEYCODE_MEDIA_REWIND);
- mRemoteController.sendMediaKeyEvent(keyEvent);
- break;
- }
- int skipAmount;
- if (msg.what == MESSAGE_FAST_FORWARD) {
- if (DEBUG) Log.v(TAG, "MESSAGE_FAST_FORWARD");
- removeMessages(MESSAGE_FAST_FORWARD);
- skipAmount = BASE_SKIP_AMOUNT;
- } else {
- if (DEBUG) Log.v(TAG, "MESSAGE_REWIND");
- removeMessages(MESSAGE_REWIND);
- skipAmount = -BASE_SKIP_AMOUNT;
- }
- if (hasMessages(MESSAGE_CHANGE_PLAY_POS) &&
- (skipAmount != mSkipAmount)) {
- Log.w(TAG, "missing release button event:" + mSkipAmount);
- }
- if ((!hasMessages(MESSAGE_CHANGE_PLAY_POS)) ||
- (skipAmount != mSkipAmount)) {
- mSkipStartTime = SystemClock.elapsedRealtime();
- }
- removeMessages(MESSAGE_CHANGE_PLAY_POS);
- if (msg.arg1 == KEY_STATE_PRESS) {
- mSkipAmount = skipAmount;
- changePositionBy(mSkipAmount * getSkipMultiplier());
- Message posMsg = obtainMessage(MESSAGE_CHANGE_PLAY_POS);
- posMsg.arg1 = 1;
- sendMessageDelayed(posMsg, SKIP_PERIOD);
- }
- break;
- case MESSAGE_CHANGE_PLAY_POS:
- if (DEBUG) Log.v(TAG, "MESSAGE_CHANGE_PLAY_POS:" + msg.arg1);
- changePositionBy(mSkipAmount * getSkipMultiplier());
- if (msg.arg1 * SKIP_PERIOD < BUTTON_TIMEOUT_TIME) {
- Message posMsg = obtainMessage(MESSAGE_CHANGE_PLAY_POS);
- posMsg.arg1 = msg.arg1 + 1;
- sendMessageDelayed(posMsg, SKIP_PERIOD);
- }
- break;
- case MESSAGE_SET_A2DP_AUDIO_STATE:
- if (DEBUG) Log.v(TAG, "MESSAGE_SET_A2DP_AUDIO_STATE:" + msg.arg1);
- updateA2dpAudioState(msg.arg1);
- break;
- case MSG_UPDATE_RCC_CHANGE:
- Log.v(TAG, "MSG_UPDATE_RCC_CHANGE");
- String callingPackageName = (String)msg.obj;
- int isFocussed = msg.arg1;
- int isAvailable = msg.arg2;
- processRCCStateChange(callingPackageName, isFocussed, isAvailable);
- break;
- case MESSAGE_SET_ADDR_PLAYER:
- processSetAddressedPlayer(msg.arg1);
- break;
- case MESSAGE_SET_BROWSED_PLAYER:
- processSetBrowsedPlayer(msg.arg1);
- break;
- case MESSAGE_CHANGE_PATH:
- processChangePath(msg.arg1, ((Long)msg.obj).longValue());
- break;
- case MESSAGE_PLAY_ITEM:
- processPlayItem(msg.arg1, ((Long)msg.obj).longValue());
- break;
- case MESSAGE_GET_ITEM_ATTRS:
- int[] attrIds;
- ItemAttr itemAttr = (ItemAttr)msg.obj;
- attrIds = new int[msg.arg1];
- for (int i = 0; i < msg.arg1; ++i) {
- attrIds[i] = itemAttr.mAttrList.get(i).intValue();
- }
- processGetItemAttr((byte)msg.arg2, itemAttr.mUid, (byte)msg.arg1, attrIds);
- break;
- case MESSAGE_GET_FOLDER_ITEMS:
- FolderListEntries folderListEntries = (FolderListEntries)msg.obj;
- attrIds = new int[folderListEntries.mNumAttr];
- for (int i = 0; i < folderListEntries.mNumAttr; ++i) {
- attrIds[i] = folderListEntries.mAttrList.get(i).intValue();
- }
- processGetFolderItems(folderListEntries.mScope, folderListEntries.mStart,
- folderListEntries.mEnd, folderListEntries.mAttrCnt,
- folderListEntries.mNumAttr, attrIds);
- break;
- }
- }
- }
- private void updateA2dpAudioState(int state) {
- boolean isPlaying = (state == BluetoothA2dp.STATE_PLAYING);
- if (isPlaying != isPlayingState(mCurrentPlayState)) {
- /* if a2dp is streaming, check to make sure music is active */
- if ( (isPlaying) && !mAudioManager.isMusicActive())
- return;
- updatePlayPauseState(isPlaying ? RemoteControlClient.PLAYSTATE_PLAYING :
- RemoteControlClient.PLAYSTATE_PAUSED,
- …
Large files files are truncated, but you can click here to view the full file