1c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu/* 2e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * Copyright (C) 2016 The Android Open Source Project 3c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 4c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Licensed under the Apache License, Version 2.0 (the "License"); 5c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * you may not use this file except in compliance with the License. 6c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * You may obtain a copy of the License at 7c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 8c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * http://www.apache.org/licenses/LICENSE-2.0 9c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * 10c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * Unless required by applicable law or agreed to in writing, software 11c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * distributed under the License is distributed on an "AS IS" BASIS, 12c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * See the License for the specific language governing permissions and 14c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu * limitations under the License. 15c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu */ 16c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 17066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodpackage com.android.bluetooth.avrcp; 18c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1929174eb9ad6e255d7ec216ab9a2ce8d20e2fe13cMarie Janssenimport android.annotation.NonNull; 2078d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssenimport android.annotation.Nullable; 21188f205b5f093850d4cc627917a21204be36c56aZhihai Xuimport android.bluetooth.BluetoothA2dp; 22066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodimport android.bluetooth.BluetoothAvrcp; 23e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.BroadcastReceiver; 24e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.ComponentName; 25c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.content.Context; 26e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.Intent; 27e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.IntentFilter; 28c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport android.content.SharedPreferences; 29e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.pm.ApplicationInfo; 30e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.pm.PackageManager; 31e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.pm.PackageManager.NameNotFoundException; 32e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.content.pm.ResolveInfo; 3311798b011c962b602217b479130d413f3b30f19aLiejun Taoimport android.content.res.Resources; 34c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.media.AudioManager; 35a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavovimport android.media.AudioPlaybackConfiguration; 363b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssenimport android.media.MediaDescription; 370e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssenimport android.media.MediaMetadata; 38e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.media.session.MediaSession; 390e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssenimport android.media.session.MediaSessionManager; 400e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssenimport android.media.session.PlaybackState; 41e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport android.os.Bundle; 42c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.os.Handler; 43c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.os.HandlerThread; 44c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.os.Looper; 45c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.os.Message; 46aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xuimport android.os.SystemClock; 470427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panickerimport android.os.UserManager; 48c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport android.util.Log; 49881675b362bde18acbbcf69c513175addca4a8baZhenye Zhuimport android.view.KeyEvent; 506e29e12add362546784126119f26f04fc760f021RoboErik 51e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport com.android.bluetooth.R; 52aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xuimport com.android.bluetooth.Utils; 53c4fbd756e2645147470c486ae96f2253f5e13a52Jack Heimport com.android.bluetooth.btservice.ProfileService; 546e29e12add362546784126119f26f04fc760f021RoboErik 55c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport java.util.ArrayList; 5678d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssenimport java.util.Collections; 5711798b011c962b602217b479130d413f3b30f19aLiejun Taoimport java.util.HashMap; 58bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssenimport java.util.HashSet; 59e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport java.util.Iterator; 60c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xuimport java.util.List; 61e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shahimport java.util.Map; 62bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssenimport java.util.Set; 63eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssenimport java.util.SortedMap; 64eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssenimport java.util.TreeMap; 65e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 66e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah/****************************************************************************** 67e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * support Bluetooth AVRCP profile. support metadata, play status, event 68e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * notifications, address player selection and browse feature implementation. 69e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ******************************************************************************/ 70eb7b90f5b93db1230a5b64caa3d8d05a642e33a6Marie Janssen 71066ad9e16a548218b139424f758b92db7af34af2Mike Lockwoodpublic final class Avrcp { 7206457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski private static final boolean DEBUG = false; 73c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private static final String TAG = "Avrcp"; 7411798b011c962b602217b479130d413f3b30f19aLiejun Tao private static final String ABSOLUTE_VOLUME_BLACKLIST = "absolute_volume_blacklist"; 75c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 76c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private Context mContext; 77c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private final AudioManager mAudioManager; 78ded973620f204f11f20d40928735a4d87e00afedHansong Zhang private volatile AvrcpMessageHandler mHandler; 79a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov private Handler mAudioManagerPlaybackHandler; 80a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov private AudioManagerPlaybackListener mAudioManagerPlaybackCb; 810e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen private MediaSessionManager mMediaSessionManager; 82dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He @Nullable private MediaController mMediaController; 830e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen private MediaControllerListener mMediaControllerCb; 843b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private MediaAttributes mMediaAttributes; 855aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen private long mLastQueueId; 86e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private PackageManager mPackageManager; 87c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private int mTransportControlFlags; 88dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He @NonNull private PlaybackState mCurrentPlayState; 890a429916782c20980e7f0893c503c633b8341f88Marie Janssen private int mA2dpState; 90a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov private boolean mAudioManagerIsPlaying; 91c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private int mPlayStatusChangedNT; 92cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker private byte mReportedPlayStatus; 93c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private int mTrackChangedNT; 94f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen private int mPlayPosChangedNT; 9559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private int mAddrPlayerChangedNT; 9659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private int mReportedPlayerID; 9705723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker private int mNowPlayingListChangedNT; 98aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu private long mPlaybackIntervalMs; 99fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen private long mLastReportedPosition; 100aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu private long mNextPosMs; 101aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu private long mPrevPosMs; 10217675906064bb72fdcca75baa56cdf8bb8968d01John Du private int mFeatures; 10311798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mRemoteVolume; 10411798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mLastRemoteVolume; 10511798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mInitialRemoteVolume; 10611798b011c962b602217b479130d413f3b30f19aLiejun Tao 10711798b011c962b602217b479130d413f3b30f19aLiejun Tao /* Local volume in audio index 0-15 */ 10811798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mLocalVolume; 10911798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mLastLocalVolume; 11011798b011c962b602217b479130d413f3b30f19aLiejun Tao private int mAbsVolThreshold; 11111798b011c962b602217b479130d413f3b30f19aLiejun Tao 11211798b011c962b602217b479130d413f3b30f19aLiejun Tao private String mAddress; 11311798b011c962b602217b479130d413f3b30f19aLiejun Tao private HashMap<Integer, Integer> mVolumeMapping; 11411798b011c962b602217b479130d413f3b30f19aLiejun Tao 11517675906064bb72fdcca75baa56cdf8bb8968d01John Du private int mLastDirection; 1162e90040ffc6f1c4cd5187338c9f708df4d380aeeMatthew Xie private final int mVolumeStep; 1172e90040ffc6f1c4cd5187338c9f708df4d380aeeMatthew Xie private final int mAudioStreamMax; 11811798b011c962b602217b479130d413f3b30f19aLiejun Tao private boolean mVolCmdSetInProgress; 11917675906064bb72fdcca75baa56cdf8bb8968d01John Du private int mAbsVolRetryTimes; 120eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 121384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen private static final int NO_PLAYER_ID = 0; 122384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen 123e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private int mCurrAddrPlayerID; 124e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private int mCurrBrowsePlayerID; 125eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen private int mLastUsedPlayerID; 126e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private AvrcpMediaRsp mAvrcpMediaRsp; 127e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 128e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* UID counter to be shared across different files. */ 12959b1c77f883bd97816332046a3a98be4431cceddMarie Janssen static short sUIDCounter = AvrcpConstants.DEFAULT_UID_COUNTER; 130ace834feb02adabd61f628c4471147aea02d939cJohn Du 13117675906064bb72fdcca75baa56cdf8bb8968d01John Du /* BTRC features */ 13217675906064bb72fdcca75baa56cdf8bb8968d01John Du public static final int BTRC_FEAT_METADATA = 0x01; 13317675906064bb72fdcca75baa56cdf8bb8968d01John Du public static final int BTRC_FEAT_ABSOLUTE_VOLUME = 0x02; 13417675906064bb72fdcca75baa56cdf8bb8968d01John Du public static final int BTRC_FEAT_BROWSE = 0x04; 13517675906064bb72fdcca75baa56cdf8bb8968d01John Du 13617675906064bb72fdcca75baa56cdf8bb8968d01John Du /* AVRC response codes, from avrc_defs */ 13717675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_NOT_IMPL = 8; 13817675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_ACCEPT = 9; 13917675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_REJ = 10; 14017675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_IN_TRANS = 11; 14117675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_IMPL_STBL = 12; 14217675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_CHANGED = 13; 14317675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRC_RSP_INTERIM = 15; 14417675906064bb72fdcca75baa56cdf8bb8968d01John Du 145e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* AVRC request commands from Native */ 146e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_RC_FEATURES = 1; 147e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_PLAY_STATUS = 2; 148e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_ELEM_ATTRS = 3; 149e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_REGISTER_NOTIFICATION = 4; 150e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_VOLUME_CHANGE = 5; 151e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_FOLDER_ITEMS = 6; 152e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_SET_ADDR_PLAYER = 7; 153e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_SET_BR_PLAYER = 8; 154e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_CHANGE_PATH = 9; 155e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_PLAY_ITEM = 10; 156e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_ITEM_ATTR = 11; 157e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS = 12; 158e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_NATIVE_REQ_PASS_THROUGH = 13; 159e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 160e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* other AVRC messages */ 161e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_PLAY_INTERVAL_TIMEOUT = 14; 162e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_SET_ABSOLUTE_VOLUME = 16; 163e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final int MSG_ABS_VOL_TIMEOUT = 17; 16459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private static final int MSG_SET_A2DP_AUDIO_STATE = 18; 165f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen private static final int MSG_NOW_PLAYING_CHANGED_RSP = 19; 16605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 16717675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int CMD_TIMEOUT_DELAY = 2000; 168f8201e1c6bf7fadc0a332151a652325a7f31255aLiejun Tao private static final int MAX_ERROR_RETRY_TIMES = 6; 16917675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRCP_MAX_VOL = 127; 17017675906064bb72fdcca75baa56cdf8bb8968d01John Du private static final int AVRCP_BASE_VOLUME_STEP = 1; 171ace834feb02adabd61f628c4471147aea02d939cJohn Du 172e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Communicates with MediaPlayer to fetch media content */ 173e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private BrowsedMediaPlayer mBrowsedMediaPlayer; 174e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 17505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /* Addressed player handling */ 176e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private AddressedMediaPlayer mAddressedMediaPlayer; 177e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 178e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* List of Media player instances, useful for retrieving MediaPlayerList or MediaPlayerInfo */ 179eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen private SortedMap<Integer, MediaPlayerInfo> mMediaPlayerInfoList; 180f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen private boolean mAvailablePlayerViewChanged; 181e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 182e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* List of media players which supports browse */ 1835146bd27869df5473aa53e6271266f51733971efMarie Janssen private List<BrowsePlayerInfo> mBrowsePlayerInfoList; 184e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 185e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Manage browsed players */ 186e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private AvrcpBrowseManager mAvrcpBrowseManager; 187e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 188e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Broadcast receiver for device connections intent broadcasts */ 189e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private final BroadcastReceiver mAvrcpReceiver = new AvrcpServiceBroadcastReceiver(); 1900427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker private final BroadcastReceiver mBootReceiver = new AvrcpServiceBootReceiver(); 191e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 19205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /* Recording passthrough key dispatches */ 193dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He private static final int PASSTHROUGH_LOG_MAX_SIZE = DEBUG ? 50 : 10; 19405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private EvictingQueue<MediaKeyLog> mPassthroughLogs; // Passthorugh keys dispatched 19578d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen private List<MediaKeyLog> mPassthroughPending; // Passthrough keys sent not dispatched yet 19605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private int mPassthroughDispatched; // Number of keys dispatched 19705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 19805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private class MediaKeyLog { 19905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private long mTimeSent; 20005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private long mTimeProcessed; 20105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private String mPackage; 20205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private KeyEvent mEvent; 20305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 204d04c0a8609b39f891d5787f051b1dfb105ceee93Jack He MediaKeyLog(long time, KeyEvent event) { 20505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mEvent = event; 20605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mTimeSent = time; 20705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 20805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 20905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public boolean addDispatch(long time, KeyEvent event, String packageName) { 210c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mPackage != null) { 211c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return false; 212c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 213c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (event.getAction() != mEvent.getAction()) { 214c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return false; 215c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 216c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (event.getKeyCode() != mEvent.getKeyCode()) { 217c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return false; 218c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 21905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mPackage = packageName; 22005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mTimeProcessed = time; 22105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return true; 22205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 22305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 2242fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 22505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public String toString() { 22605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen StringBuilder sb = new StringBuilder(); 22705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen sb.append(android.text.format.DateFormat.format("MM-dd HH:mm:ss", mTimeSent)); 22805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen sb.append(" " + mEvent.toString()); 22905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (mPackage == null) { 23005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen sb.append(" (undispatched)"); 23105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } else { 23205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen sb.append(" to " + mPackage); 23305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen sb.append(" in " + (mTimeProcessed - mTimeSent) + "ms"); 23405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 23505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return sb.toString(); 23605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 23705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 23805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 239c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu static { 240c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu classInitNative(); 241c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 242c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 243c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private Avrcp(Context context) { 2443b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen mMediaAttributes = new MediaAttributes(null); 2455aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen mLastQueueId = MediaSession.QueueItem.UNKNOWN_ID; 246c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mCurrentPlayState = 247c4fbd756e2645147470c486ae96f2253f5e13a52Jack He new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, -1L, 0.0f).build(); 24859b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mReportedPlayStatus = PLAYSTATUS_ERROR; 2490a429916782c20980e7f0893c503c633b8341f88Marie Janssen mA2dpState = BluetoothA2dp.STATE_NOT_PLAYING; 250a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerIsPlaying = false; 251e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 252e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 253e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 25459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 25505723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 25659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mPlaybackIntervalMs = 0L; 257fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen mLastReportedPosition = -1; 2583635a926bd7316a55b288a54d409a1070a9c19e8Marie Janssen mNextPosMs = -1; 2593635a926bd7316a55b288a54d409a1070a9c19e8Marie Janssen mPrevPosMs = -1; 26017675906064bb72fdcca75baa56cdf8bb8968d01John Du mFeatures = 0; 26111798b011c962b602217b479130d413f3b30f19aLiejun Tao mRemoteVolume = -1; 26211798b011c962b602217b479130d413f3b30f19aLiejun Tao mInitialRemoteVolume = -1; 26311798b011c962b602217b479130d413f3b30f19aLiejun Tao mLastRemoteVolume = -1; 26417675906064bb72fdcca75baa56cdf8bb8968d01John Du mLastDirection = 0; 26511798b011c962b602217b479130d413f3b30f19aLiejun Tao mVolCmdSetInProgress = false; 26617675906064bb72fdcca75baa56cdf8bb8968d01John Du mAbsVolRetryTimes = 0; 26711798b011c962b602217b479130d413f3b30f19aLiejun Tao mLocalVolume = -1; 26811798b011c962b602217b479130d413f3b30f19aLiejun Tao mLastLocalVolume = -1; 26911798b011c962b602217b479130d413f3b30f19aLiejun Tao mAbsVolThreshold = 0; 27011798b011c962b602217b479130d413f3b30f19aLiejun Tao mVolumeMapping = new HashMap<Integer, Integer>(); 271384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen mCurrAddrPlayerID = NO_PLAYER_ID; 27259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mReportedPlayerID = mCurrAddrPlayerID; 273294ff299ca4837fd7f56861941b274fadee97ec4Marie Janssen mCurrBrowsePlayerID = 0; 274c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mContext = context; 275eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen mLastUsedPlayerID = 0; 276e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAddressedMediaPlayer = null; 277c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 278c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu initNative(); 279c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 280c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mMediaSessionManager = 281c4fbd756e2645147470c486ae96f2253f5e13a52Jack He (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE); 282c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 2832e90040ffc6f1c4cd5187338c9f708df4d380aeeMatthew Xie mAudioStreamMax = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 284c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mVolumeStep = Math.max(AVRCP_BASE_VOLUME_STEP, AVRCP_MAX_VOL / mAudioStreamMax); 285e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 28611798b011c962b602217b479130d413f3b30f19aLiejun Tao Resources resources = context.getResources(); 28711798b011c962b602217b479130d413f3b30f19aLiejun Tao if (resources != null) { 288c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAbsVolThreshold = 289c4fbd756e2645147470c486ae96f2253f5e13a52Jack He resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold); 290241337c1482c484e1a3a5fb24bc642937ab1a47cPavlin Radoslavov 2915ef52da260f8b4c1baed22bceb2983a694bb022cJack He // Update the threshold if the thresholdPercent is valid 2925ef52da260f8b4c1baed22bceb2983a694bb022cJack He int thresholdPercent = 293241337c1482c484e1a3a5fb24bc642937ab1a47cPavlin Radoslavov resources.getInteger(R.integer.a2dp_absolute_volume_initial_threshold_percent); 2945ef52da260f8b4c1baed22bceb2983a694bb022cJack He if (thresholdPercent >= 0 && thresholdPercent <= 100) { 2955ef52da260f8b4c1baed22bceb2983a694bb022cJack He mAbsVolThreshold = (thresholdPercent * mAudioStreamMax) / 100; 296241337c1482c484e1a3a5fb24bc642937ab1a47cPavlin Radoslavov } 29711798b011c962b602217b479130d413f3b30f19aLiejun Tao } 298e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 299e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // Register for package removal intent broadcasts for media button receiver persistence 300e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah IntentFilter pkgFilter = new IntentFilter(); 301e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 302e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 303e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah pkgFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); 304e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah pkgFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); 305e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah pkgFilter.addDataScheme("package"); 306e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah context.registerReceiver(mAvrcpReceiver, pkgFilter); 3070427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker 3080427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker IntentFilter bootFilter = new IntentFilter(); 3099c2ff5bb5082c653ee91d336dcd7f95e4c25e833Ajay Panicker bootFilter.addAction(Intent.ACTION_USER_UNLOCKED); 3100427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker context.registerReceiver(mBootReceiver, bootFilter); 311c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 312c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 3139a5f80a6528d76153a7e97821f114f3370df89a5Marie Janssen private synchronized void start() { 314c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu HandlerThread thread = new HandlerThread("BluetoothAvrcpHandler"); 315c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu thread.start(); 316c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu Looper looper = thread.getLooper(); 317c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mHandler = new AvrcpMessageHandler(looper); 318a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerPlaybackHandler = new Handler(looper); 319a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerPlaybackCb = new AudioManagerPlaybackListener(); 3209d4035307b85e78f10fba961e225ca09bfb7d0c7Jakub Pawlowski mMediaControllerCb = new MediaControllerListener(); 321e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAvrcpMediaRsp = new AvrcpMediaRsp(); 322eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen mMediaPlayerInfoList = new TreeMap<Integer, MediaPlayerInfo>(); 323f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen mAvailablePlayerViewChanged = false; 3245146bd27869df5473aa53e6271266f51733971efMarie Janssen mBrowsePlayerInfoList = Collections.synchronizedList(new ArrayList<BrowsePlayerInfo>()); 32505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mPassthroughDispatched = 0; 32605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mPassthroughLogs = new EvictingQueue<MediaKeyLog>(PASSTHROUGH_LOG_MAX_SIZE); 32778d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen mPassthroughPending = Collections.synchronizedList(new ArrayList<MediaKeyLog>()); 328f65765e71b2a6552c319eb5199914045a1ecdb04Marie Janssen if (mMediaSessionManager != null) { 329f65765e71b2a6552c319eb5199914045a1ecdb04Marie Janssen mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveSessionListener, null, 330f65765e71b2a6552c319eb5199914045a1ecdb04Marie Janssen mHandler); 33105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mMediaSessionManager.setCallback(mButtonDispatchCallback, null); 332f65765e71b2a6552c319eb5199914045a1ecdb04Marie Janssen } 333e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mPackageManager = mContext.getApplicationContext().getPackageManager(); 334e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 335e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* create object to communicate with addressed player */ 336e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAddressedMediaPlayer = new AddressedMediaPlayer(mAvrcpMediaRsp); 337e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 338e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* initialize BrowseMananger which manages Browse commands and response */ 339e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAvrcpBrowseManager = new AvrcpBrowseManager(mContext, mAvrcpMediaRsp); 3400427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker 34105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen initMediaPlayersList(); 34211bf73ff614f48a41dc379763bc007f271197b26Ajay Panicker 3430427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker UserManager manager = UserManager.get(mContext); 3440427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker if (manager == null || manager.isUserUnlocked()) { 345c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 346c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "User already unlocked, initializing player lists"); 347c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 3483843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen // initialize browsable player list and build media player list 349754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker buildBrowsablePlayerList(); 3500427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker } 351a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov 352c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAudioManager.registerAudioPlaybackCallback(mAudioManagerPlaybackCb, 353c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAudioManagerPlaybackHandler); 354c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 355c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 356066ad9e16a548218b139424f758b92db7af34af2Mike Lockwood public static Avrcp make(Context context) { 357c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 358c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "make"); 359c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 360c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu Avrcp ar = new Avrcp(context); 361c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu ar.start(); 362c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu return ar; 363c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 364c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 3659a5f80a6528d76153a7e97821f114f3370df89a5Marie Janssen public synchronized void doQuit() { 366c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 367c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "doQuit"); 368c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 369a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov if (mAudioManager != null) { 370a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManager.unregisterAudioPlaybackCallback(mAudioManagerPlaybackCb); 371a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 372c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mMediaController != null) { 373c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mMediaController.unregisterCallback(mMediaControllerCb); 374c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 3757c7cc128e93e7e1db8a5ed7f69583ddc6d99493eMarie Janssen if (mMediaSessionManager != null) { 3767c7cc128e93e7e1db8a5ed7f69583ddc6d99493eMarie Janssen mMediaSessionManager.setCallback(null, null); 3777c7cc128e93e7e1db8a5ed7f69583ddc6d99493eMarie Janssen mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveSessionListener); 3787c7cc128e93e7e1db8a5ed7f69583ddc6d99493eMarie Janssen } 3797c7cc128e93e7e1db8a5ed7f69583ddc6d99493eMarie Janssen 380a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerPlaybackHandler.removeCallbacksAndMessages(null); 381c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mHandler.removeCallbacksAndMessages(null); 382c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu Looper looper = mHandler.getLooper(); 383ded973620f204f11f20d40928735a4d87e00afedHansong Zhang mHandler = null; 384c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu if (looper != null) { 385ded973620f204f11f20d40928735a4d87e00afedHansong Zhang looper.quitSafely(); 386c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 387e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 388a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerPlaybackHandler = null; 389e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mContext.unregisterReceiver(mAvrcpReceiver); 3900427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker mContext.unregisterReceiver(mBootReceiver); 391e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 392e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAddressedMediaPlayer.cleanup(); 393e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAvrcpBrowseManager.cleanup(); 394c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 395c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 396c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu public void cleanup() { 397c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 398c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "cleanup"); 399c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 400c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu cleanupNative(); 401c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mVolumeMapping != null) { 40211798b011c962b602217b479130d413f3b30f19aLiejun Tao mVolumeMapping.clear(); 403c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 404c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 405c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 406a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov private class AudioManagerPlaybackListener extends AudioManager.AudioPlaybackCallback { 407a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov @Override 408a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) { 409a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov super.onPlaybackConfigChanged(configs); 410a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov boolean isPlaying = false; 411a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov for (AudioPlaybackConfiguration config : configs) { 412a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov if (DEBUG) { 413c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "AudioManager Player: " 414c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + AudioPlaybackConfiguration.toLogFriendlyString(config)); 415a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 416a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov if (config.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) { 417a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov isPlaying = true; 418a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov break; 419a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 420a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 421c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 422c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "AudioManager isPlaying: " + isPlaying); 423c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 424a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov if (mAudioManagerIsPlaying != isPlaying) { 425a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov mAudioManagerIsPlaying = isPlaying; 426a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov updateCurrentMediaState(); 427a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 428a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 429a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 430a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov 4310e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen private class MediaControllerListener extends MediaController.Callback { 4320e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen @Override 4330e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen public void onMetadataChanged(MediaMetadata metadata) { 434c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 435c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "onMetadataChanged"); 436c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 43785aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 438c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 439c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 440bc10e7d58aa55da25c18d8056a0254a2b736146aZhihai Xu @Override 441e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public synchronized void onPlaybackStateChanged(PlaybackState state) { 442c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 443c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "onPlaybackStateChanged: state " + state.toString()); 444c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 445cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker 44685aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 447c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 448c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 449c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu @Override 4500e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen public void onSessionDestroyed() { 4510e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen Log.v(TAG, "MediaController session destroyed"); 452ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen synchronized (Avrcp.this) { 453c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mMediaController != null) { 454ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen removeMediaController(mMediaController.getWrappedInstance()); 455c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 456384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } 457c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 458c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 459c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu @Override 460e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void onQueueChanged(List<MediaSession.QueueItem> queue) { 461e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (queue == null) { 462e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.v(TAG, "onQueueChanged: received null queue"); 463e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return; 464e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 4652b903c7262c9b8c0493e36b93b37831e7e075bfcMarie Janssen 466ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 467ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 468ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "onQueueChanged: mHandler is already null"); 469ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 470ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 471ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 472ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Log.v(TAG, "onQueueChanged: NowPlaying list changed, Queue Size = " 473ded973620f204f11f20d40928735a4d87e00afedHansong Zhang + queue.size()); 474ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendEmptyMessage(MSG_NOW_PLAYING_CHANGED_RSP); 475c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 476c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 477c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 478c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu /** Handles Avrcp messages. */ 479c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private final class AvrcpMessageHandler extends Handler { 480c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private AvrcpMessageHandler(Looper looper) { 481c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu super(looper); 482c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 483c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 484c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu @Override 485c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu public void handleMessage(Message msg) { 486c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu switch (msg.what) { 487c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_RC_FEATURES: { 488c4fbd756e2645147470c486ae96f2253f5e13a52Jack He String address = (String) msg.obj; 489c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mFeatures = msg.arg1; 490c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mFeatures = modifyRcFeatureFromBlacklist(mFeatures, address); 491c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 492c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 493c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "MSG_NATIVE_REQ_GET_RC_FEATURES: address=" + address + ", features=" 494c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + msg.arg1 + ", mFeatures=" + mFeatures); 495c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 496c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAudioManager.avrcpSupportsAbsoluteVolume(address, isAbsoluteVolumeSupported()); 497c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLastLocalVolume = -1; 498c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mRemoteVolume = -1; 499c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLocalVolume = -1; 500c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mInitialRemoteVolume = -1; 501c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAddress = address; 502c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mVolumeMapping != null) { 503c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mVolumeMapping.clear(); 504c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 505c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 506414480de643b551c1d2dd7db971cc24cff29a605Pavlin Radoslavov } 50717675906064bb72fdcca75baa56cdf8bb8968d01John Du 508c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_PLAY_STATUS: { 509c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] address = (byte[]) msg.obj; 510c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int btstate = getBluetoothPlayState(mCurrentPlayState); 511c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int length = (int) mMediaAttributes.getLength(); 512c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int position = (int) getPlayPosition(); 513c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 514c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 515c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "MSG_NATIVE_REQ_GET_PLAY_STATUS, responding with state " + btstate 516c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " len " + length + " pos " + position); 517cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen } 518c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getPlayStatusRspNative(address, btstate, length, position); 519c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 520c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 521c1124a7c6679f612b80926a19084655f9a71580aMarie Janssen 522c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_ELEM_ATTRS: { 523c4fbd756e2645147470c486ae96f2253f5e13a52Jack He String[] textArray; 524c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpCmd.ElementAttrCmd elem = (AvrcpCmd.ElementAttrCmd) msg.obj; 525c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte numAttr = elem.mNumAttr; 526c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int[] attrIds = elem.mAttrIDs; 527c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 528c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_GET_ELEM_ATTRS:numAttr=" + numAttr); 529c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 530c4fbd756e2645147470c486ae96f2253f5e13a52Jack He textArray = new String[numAttr]; 531c4fbd756e2645147470c486ae96f2253f5e13a52Jack He StringBuilder responseDebug = new StringBuilder(); 532c4fbd756e2645147470c486ae96f2253f5e13a52Jack He responseDebug.append("getElementAttr response: "); 533c4fbd756e2645147470c486ae96f2253f5e13a52Jack He for (int i = 0; i < numAttr; ++i) { 534c4fbd756e2645147470c486ae96f2253f5e13a52Jack He textArray[i] = mMediaAttributes.getString(attrIds[i]); 535c4fbd756e2645147470c486ae96f2253f5e13a52Jack He responseDebug.append("[" + attrIds[i] + "="); 536c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (attrIds[i] == AvrcpConstants.ATTRID_TITLE 537c4fbd756e2645147470c486ae96f2253f5e13a52Jack He || attrIds[i] == AvrcpConstants.ATTRID_ARTIST 538c4fbd756e2645147470c486ae96f2253f5e13a52Jack He || attrIds[i] == AvrcpConstants.ATTRID_ALBUM) { 539c4fbd756e2645147470c486ae96f2253f5e13a52Jack He responseDebug.append(Utils.ellipsize(textArray[i]) + "] "); 540c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 541c4fbd756e2645147470c486ae96f2253f5e13a52Jack He responseDebug.append(textArray[i] + "] "); 542c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 543c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 544c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, responseDebug.toString()); 545c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] bdaddr = elem.mAddress; 546c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getElementAttrRspNative(bdaddr, numAttr, attrIds, textArray); 547c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 548c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 549c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 550c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_REGISTER_NOTIFICATION: 551c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 552c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 553c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "MSG_NATIVE_REQ_REGISTER_NOTIFICATION:event=" + msg.arg1 + " param=" 554c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + msg.arg2); 555c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 556c4fbd756e2645147470c486ae96f2253f5e13a52Jack He processRegisterNotification((byte[]) msg.obj, msg.arg1, msg.arg2); 557c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 558e2619781c799435cf0273d381069c754c5f89a20Marie Janssen 559c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NOW_PLAYING_CHANGED_RSP: 560c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 561c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NOW_PLAYING_CHANGED_RSP"); 562c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 563c4fbd756e2645147470c486ae96f2253f5e13a52Jack He removeMessages(MSG_NOW_PLAYING_CHANGED_RSP); 564c4fbd756e2645147470c486ae96f2253f5e13a52Jack He updateCurrentMediaState(); 565c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 566aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 567c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_PLAY_INTERVAL_TIMEOUT: 568c4fbd756e2645147470c486ae96f2253f5e13a52Jack He sendPlayPosNotificationRsp(false); 56911798b011c962b602217b479130d413f3b30f19aLiejun Tao break; 570c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 571c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_VOLUME_CHANGE: 572c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!isAbsoluteVolumeSupported()) { 573c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 574c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_VOLUME_CHANGE ignored, not supported"); 575c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 57617675906064bb72fdcca75baa56cdf8bb8968d01John Du break; 57717675906064bb72fdcca75baa56cdf8bb8968d01John Du } 578c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte absVol = (byte) ((byte) msg.arg1 & 0x7f); // discard MSB as it is RFD 579c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 580c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_VOLUME_CHANGE: volume=" + absVol + " ctype=" 581c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + msg.arg2); 582c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 58311798b011c962b602217b479130d413f3b30f19aLiejun Tao 584c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (msg.arg2 == AVRC_RSP_ACCEPT || msg.arg2 == AVRC_RSP_REJ) { 585ff77fb7108403626cfd2a8b0c90601e431a5dc09Ajay Panicker if (!mVolCmdSetInProgress) { 586c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "Unsolicited response, ignored"); 587c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 588c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 589c4fbd756e2645147470c486ae96f2253f5e13a52Jack He removeMessages(MSG_ABS_VOL_TIMEOUT); 59011798b011c962b602217b479130d413f3b30f19aLiejun Tao 591c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mVolCmdSetInProgress = false; 592c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAbsVolRetryTimes = 0; 593c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 594c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 595c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // convert remote volume to local volume 596c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int volIndex = convertToAudioStreamVolume(absVol); 597c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mInitialRemoteVolume == -1) { 598c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mInitialRemoteVolume = absVol; 599c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mAbsVolThreshold > 0 && mAbsVolThreshold < mAudioStreamMax 600c4fbd756e2645147470c486ae96f2253f5e13a52Jack He && volIndex > mAbsVolThreshold) { 601c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 602c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "remote inital volume too high " + volIndex + ">" 603c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + mAbsVolThreshold); 604c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 605ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg1 = this.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, 606c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAbsVolThreshold, 0); 607ded973620f204f11f20d40928735a4d87e00afedHansong Zhang this.sendMessage(msg1); 608c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mRemoteVolume = absVol; 609c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLocalVolume = volIndex; 610c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 611c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 61211798b011c962b602217b479130d413f3b30f19aLiejun Tao } 61311798b011c962b602217b479130d413f3b30f19aLiejun Tao 614c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mLocalVolume != volIndex && (msg.arg2 == AVRC_RSP_ACCEPT 615c4fbd756e2645147470c486ae96f2253f5e13a52Jack He || msg.arg2 == AVRC_RSP_CHANGED || msg.arg2 == AVRC_RSP_INTERIM)) { 61611798b011c962b602217b479130d413f3b30f19aLiejun Tao /* If the volume has successfully changed */ 617c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLocalVolume = volIndex; 618c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mLastLocalVolume != -1 && msg.arg2 == AVRC_RSP_ACCEPT) { 619c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mLastLocalVolume != volIndex) { 62011798b011c962b602217b479130d413f3b30f19aLiejun Tao /* remote volume changed more than requested due to 62111798b011c962b602217b479130d413f3b30f19aLiejun Tao * local and remote has different volume steps */ 622c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 623c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, 624c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "Remote returned volume does not match desired volume " 625c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + mLastLocalVolume + " vs " + volIndex); 626c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 627c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLastLocalVolume = mLocalVolume; 628c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 62911798b011c962b602217b479130d413f3b30f19aLiejun Tao } 63011798b011c962b602217b479130d413f3b30f19aLiejun Tao 631c4fbd756e2645147470c486ae96f2253f5e13a52Jack He notifyVolumeChanged(mLocalVolume); 632c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mRemoteVolume = absVol; 633c4fbd756e2645147470c486ae96f2253f5e13a52Jack He long pecentVolChanged = ((long) absVol * 100) / 0x7f; 634c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "percent volume changed: " + pecentVolChanged + "%"); 635c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else if (msg.arg2 == AVRC_RSP_REJ) { 636c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "setAbsoluteVolume call rejected"); 63717675906064bb72fdcca75baa56cdf8bb8968d01John Du } 63811798b011c962b602217b479130d413f3b30f19aLiejun Tao break; 63911798b011c962b602217b479130d413f3b30f19aLiejun Tao 640c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_SET_ABSOLUTE_VOLUME: 641c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!isAbsoluteVolumeSupported()) { 642c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 643c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "ignore MSG_SET_ABSOLUTE_VOLUME"); 644c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 645c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 646c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 64711798b011c962b602217b479130d413f3b30f19aLiejun Tao 648c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 649c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_SET_ABSOLUTE_VOLUME"); 650c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 65111798b011c962b602217b479130d413f3b30f19aLiejun Tao 652ff77fb7108403626cfd2a8b0c90601e431a5dc09Ajay Panicker if (mVolCmdSetInProgress) { 653c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 654c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.w(TAG, "There is already a volume command in progress."); 655c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 656c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 657c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 65811798b011c962b602217b479130d413f3b30f19aLiejun Tao 659c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // Remote device didn't set initial volume. Let's black list it 660c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mInitialRemoteVolume == -1) { 661c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 662c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "remote " + mAddress 663c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " never tell us initial volume, black list it."); 664c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 665fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov blackListCurrentDevice("MSG_SET_ABSOLUTE_VOLUME"); 666c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 667c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 66817675906064bb72fdcca75baa56cdf8bb8968d01John Du 669c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int avrcpVolume = convertToAvrcpVolume(msg.arg1); 670c4fbd756e2645147470c486ae96f2253f5e13a52Jack He avrcpVolume = Math.min(AVRCP_MAX_VOL, Math.max(0, avrcpVolume)); 671c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 672c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Setting volume to " + msg.arg1 + "-" + avrcpVolume); 673c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 674c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (setVolumeNative(avrcpVolume)) { 675e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah sendMessageDelayed(obtainMessage(MSG_ABS_VOL_TIMEOUT), CMD_TIMEOUT_DELAY); 67611798b011c962b602217b479130d413f3b30f19aLiejun Tao mVolCmdSetInProgress = true; 677c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLastRemoteVolume = avrcpVolume; 678c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mLastLocalVolume = msg.arg1; 679c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 680c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 681c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "setVolumeNative failed"); 682c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 68317675906064bb72fdcca75baa56cdf8bb8968d01John Du } 684c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 68517675906064bb72fdcca75baa56cdf8bb8968d01John Du 686c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_ABS_VOL_TIMEOUT: 687c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 688c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_ABS_VOL_TIMEOUT: Volume change cmd timed out."); 689c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 690c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mVolCmdSetInProgress = false; 691c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mAbsVolRetryTimes >= MAX_ERROR_RETRY_TIMES) { 692c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAbsVolRetryTimes = 0; 693c4fbd756e2645147470c486ae96f2253f5e13a52Jack He /* too many volume change failures, black list the device */ 694fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov blackListCurrentDevice("MSG_ABS_VOL_TIMEOUT"); 695c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 696c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAbsVolRetryTimes += 1; 697c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (setVolumeNative(mLastRemoteVolume)) { 698c4fbd756e2645147470c486ae96f2253f5e13a52Jack He sendMessageDelayed(obtainMessage(MSG_ABS_VOL_TIMEOUT), 699c4fbd756e2645147470c486ae96f2253f5e13a52Jack He CMD_TIMEOUT_DELAY); 700c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mVolCmdSetInProgress = true; 701c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 702c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 703c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 704e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 705c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_SET_A2DP_AUDIO_STATE: 706c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 707c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_SET_A2DP_AUDIO_STATE:" + msg.arg1); 708c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 709c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mA2dpState = msg.arg1; 710c4fbd756e2645147470c486ae96f2253f5e13a52Jack He updateCurrentMediaState(); 711c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 712c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 713c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_FOLDER_ITEMS: { 714c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpCmd.FolderItemsCmd folderObj = (AvrcpCmd.FolderItemsCmd) msg.obj; 715c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 716c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_GET_FOLDER_ITEMS " + folderObj); 717c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 718c4fbd756e2645147470c486ae96f2253f5e13a52Jack He switch (folderObj.mScope) { 719c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case AvrcpConstants.BTRC_SCOPE_PLAYER_LIST: 720c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handleMediaPlayerListRsp(folderObj); 721c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 722c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case AvrcpConstants.BTRC_SCOPE_FILE_SYSTEM: 723c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case AvrcpConstants.BTRC_SCOPE_NOW_PLAYING: 724c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handleGetFolderItemBrowseResponse(folderObj, folderObj.mAddress); 725c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 726c4fbd756e2645147470c486ae96f2253f5e13a52Jack He default: 727c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "unknown scope for getfolderitems. scope = " 728c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + folderObj.mScope); 729c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getFolderItemsRspNative(folderObj.mAddress, 730c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpConstants.RSP_INV_SCOPE, (short) 0, (byte) 0, 0, null, 731c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null, null, null, null, null, null, null); 732c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 733c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 734e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 735e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 736c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_SET_ADDR_PLAYER: 737c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // object is bdaddr, argument 1 is the selected player id 738c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 739c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_SET_ADDR_PLAYER id=" + msg.arg1); 740c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 741c4fbd756e2645147470c486ae96f2253f5e13a52Jack He setAddressedPlayer((byte[]) msg.obj, msg.arg1); 742c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 743e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 744c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_ITEM_ATTR: 745c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // msg object contains the item attribute object 746c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpCmd.ItemAttrCmd cmd = (AvrcpCmd.ItemAttrCmd) msg.obj; 747c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 748c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_GET_ITEM_ATTR " + cmd); 749c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 750c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handleGetItemAttr(cmd); 751c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 752e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 753c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_SET_BR_PLAYER: 754c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // argument 1 is the selected player id 755c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 756c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_SET_BR_PLAYER id=" + msg.arg1); 757c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 758c4fbd756e2645147470c486ae96f2253f5e13a52Jack He setBrowsedPlayer((byte[]) msg.obj, msg.arg1); 759c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 760e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 761c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_CHANGE_PATH: { 762c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 763c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_CHANGE_PATH"); 764c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 765c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Bundle data = msg.getData(); 766c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] bdaddr = data.getByteArray("BdAddress"); 767c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] folderUid = data.getByteArray("folderUid"); 768c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte direction = data.getByte("direction"); 769c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) != null) { 770c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) 771c4fbd756e2645147470c486ae96f2253f5e13a52Jack He .changePath(folderUid, direction); 772c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 773c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "Remote requesting change path before setbrowsedplayer"); 774c4fbd756e2645147470c486ae96f2253f5e13a52Jack He changePathRspNative(bdaddr, AvrcpConstants.RSP_BAD_CMD, 0); 775c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 776c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 777e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 778e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 779c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_PLAY_ITEM: { 780c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Bundle data = msg.getData(); 781c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] bdaddr = data.getByteArray("BdAddress"); 782c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] uid = data.getByteArray("uid"); 783c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte scope = data.getByte("scope"); 784c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 785c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_PLAY_ITEM scope=" + scope + " id=" 786c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + Utils.byteArrayToString(uid)); 787c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 788c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handlePlayItemResponse(bdaddr, uid, scope); 789c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 790c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 791e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 792c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS: 793c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 794c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS scope=" + msg.arg1); 795c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 796c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // argument 1 is scope, object is bdaddr 797c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handleGetTotalNumOfItemsResponse((byte[]) msg.obj, (byte) msg.arg1); 798c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 799e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 800c4fbd756e2645147470c486ae96f2253f5e13a52Jack He case MSG_NATIVE_REQ_PASS_THROUGH: 801c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 802c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 803c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "MSG_NATIVE_REQ_PASS_THROUGH: id=" + msg.arg1 + " st=" + msg.arg2); 804c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 805c4fbd756e2645147470c486ae96f2253f5e13a52Jack He // argument 1 is id, argument 2 is keyState 806c4fbd756e2645147470c486ae96f2253f5e13a52Jack He handlePassthroughCmd(msg.arg1, msg.arg2); 807c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 808e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 809c4fbd756e2645147470c486ae96f2253f5e13a52Jack He default: 810c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "unknown message! msg.what=" + msg.what); 811c4fbd756e2645147470c486ae96f2253f5e13a52Jack He break; 812c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 813c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 814c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 815c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 81659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private PlaybackState updatePlaybackState() { 817c4fbd756e2645147470c486ae96f2253f5e13a52Jack He PlaybackState newState = new PlaybackState.Builder().setState(PlaybackState.STATE_NONE, 818c4fbd756e2645147470c486ae96f2253f5e13a52Jack He PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0.0f).build(); 81959b1c77f883bd97816332046a3a98be4431cceddMarie Janssen synchronized (this) { 82059b1c77f883bd97816332046a3a98be4431cceddMarie Janssen PlaybackState controllerState = null; 82159b1c77f883bd97816332046a3a98be4431cceddMarie Janssen if (mMediaController != null) { 82259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen controllerState = mMediaController.getPlaybackState(); 82359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen } 82459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen 82559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen if (controllerState != null) { 82659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen newState = controllerState; 827a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov } 828a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // Use the AudioManager to update the playback state. 829a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // NOTE: We cannot use the 830a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // (mA2dpState == BluetoothA2dp.STATE_PLAYING) 831a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // check, because after Pause, the A2DP state remains in 832a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // STATE_PLAYING for 3 more seconds. 833a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // As a result of that, if we pause the music, on carkits the 834a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // Play status indicator will continue to display "Playing" 835a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // for 3 more seconds which can be confusing. 836c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if ((mAudioManagerIsPlaying && newState.getState() != PlaybackState.STATE_PLAYING) || ( 837c4fbd756e2645147470c486ae96f2253f5e13a52Jack He controllerState == null && mAudioManager != null 838c4fbd756e2645147470c486ae96f2253f5e13a52Jack He && mAudioManager.isMusicActive())) { 839a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // Use AudioManager playback state if we don't have the state 840a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov // from MediaControlller 84159b1c77f883bd97816332046a3a98be4431cceddMarie Janssen PlaybackState.Builder builder = new PlaybackState.Builder(); 842a24231afabc31d1e7c903441108e19931d52a599Pavlin Radoslavov if (mAudioManagerIsPlaying) { 84359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen builder.setState(PlaybackState.STATE_PLAYING, 84459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen PlaybackState.PLAYBACK_POSITION_UNKNOWN, 1.0f); 84559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen } else { 84659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen builder.setState(PlaybackState.STATE_PAUSED, 84759b1c77f883bd97816332046a3a98be4431cceddMarie Janssen PlaybackState.PLAYBACK_POSITION_UNKNOWN, 0.0f); 84859b1c77f883bd97816332046a3a98be4431cceddMarie Janssen } 84959b1c77f883bd97816332046a3a98be4431cceddMarie Janssen newState = builder.build(); 85059b1c77f883bd97816332046a3a98be4431cceddMarie Janssen } 8510e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen } 852f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 85359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen byte newPlayStatus = getBluetoothPlayState(newState); 8540a429916782c20980e7f0893c503c633b8341f88Marie Janssen 85559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen /* update play status in global media player list */ 8560a429916782c20980e7f0893c503c633b8341f88Marie Janssen MediaPlayerInfo player = getAddressedPlayerInfo(); 8570a429916782c20980e7f0893c503c633b8341f88Marie Janssen if (player != null) { 85859b1c77f883bd97816332046a3a98be4431cceddMarie Janssen player.setPlayStatus(newPlayStatus); 8590a429916782c20980e7f0893c503c633b8341f88Marie Janssen } 8600a429916782c20980e7f0893c503c633b8341f88Marie Janssen 861fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen if (DEBUG) { 86259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen Log.v(TAG, "updatePlaybackState (" + mPlayStatusChangedNT + "): " + mReportedPlayStatus 863c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + "➡" + newPlayStatus + "(" + newState + ")"); 864fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen } 865fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen 866c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (newState != null) { 867c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mCurrentPlayState = newState; 868c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 869aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 87059b1c77f883bd97816332046a3a98be4431cceddMarie Janssen return mCurrentPlayState; 87159b1c77f883bd97816332046a3a98be4431cceddMarie Janssen } 87259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen 87359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private void sendPlaybackStatus(int playStatusChangedNT, byte playbackState) { 87459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen registerNotificationRspPlayStatusNative(playStatusChangedNT, playbackState); 87559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mPlayStatusChangedNT = playStatusChangedNT; 87659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mReportedPlayStatus = playbackState; 877c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 878c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 879c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private void updateTransportControls(int transportControlFlags) { 880c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mTransportControlFlags = transportControlFlags; 881c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 882c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 8833b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen class MediaAttributes { 8848bc413b0b749ea9df59e858493273e05087fe887Jack He private boolean mExists; 8858bc413b0b749ea9df59e858493273e05087fe887Jack He private String mTitle; 8868bc413b0b749ea9df59e858493273e05087fe887Jack He private String mArtistName; 8878bc413b0b749ea9df59e858493273e05087fe887Jack He private String mAlbumName; 8888bc413b0b749ea9df59e858493273e05087fe887Jack He private String mMediaNumber; 8898bc413b0b749ea9df59e858493273e05087fe887Jack He private String mMediaTotalNumber; 8908bc413b0b749ea9df59e858493273e05087fe887Jack He private String mGenre; 8918bc413b0b749ea9df59e858493273e05087fe887Jack He private long mPlayingTimeMs; 8923b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 8933b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_TITLE = 1; 8943b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_ARTIST_NAME = 2; 8953b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_ALBUM_NAME = 3; 8963b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_MEDIA_NUMBER = 4; 8973b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_MEDIA_TOTAL_NUMBER = 5; 8983b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_GENRE = 6; 8993b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private static final int ATTR_PLAYING_TIME_MS = 7; 9003b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9013b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 902d04c0a8609b39f891d5787f051b1dfb105ceee93Jack He MediaAttributes(MediaMetadata data) { 9038bc413b0b749ea9df59e858493273e05087fe887Jack He mExists = data != null; 904c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mExists) { 9053b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return; 906c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9073b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9088bc413b0b749ea9df59e858493273e05087fe887Jack He mArtistName = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_ARTIST)); 9098bc413b0b749ea9df59e858493273e05087fe887Jack He mAlbumName = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_ALBUM)); 9108bc413b0b749ea9df59e858493273e05087fe887Jack He mMediaNumber = longStringOrBlank(data.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER)); 911c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mMediaTotalNumber = 912c4fbd756e2645147470c486ae96f2253f5e13a52Jack He longStringOrBlank(data.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS)); 9138bc413b0b749ea9df59e858493273e05087fe887Jack He mGenre = stringOrBlank(data.getString(MediaMetadata.METADATA_KEY_GENRE)); 9148bc413b0b749ea9df59e858493273e05087fe887Jack He mPlayingTimeMs = data.getLong(MediaMetadata.METADATA_KEY_DURATION); 9153b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9163b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen // Try harder for the title. 9178bc413b0b749ea9df59e858493273e05087fe887Jack He mTitle = data.getString(MediaMetadata.METADATA_KEY_TITLE); 9183b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9198bc413b0b749ea9df59e858493273e05087fe887Jack He if (mTitle == null) { 9203b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen MediaDescription desc = data.getDescription(); 9213b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen if (desc != null) { 9223b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen CharSequence val = desc.getDescription(); 923c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (val != null) { 9248bc413b0b749ea9df59e858493273e05087fe887Jack He mTitle = val.toString(); 925c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9263b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9273b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9283b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 929c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mTitle == null) { 9308bc413b0b749ea9df59e858493273e05087fe887Jack He mTitle = new String(); 931c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9323b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9333b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9340a429916782c20980e7f0893c503c633b8341f88Marie Janssen public long getLength() { 935c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mExists) { 936c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return 0L; 937c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9388bc413b0b749ea9df59e858493273e05087fe887Jack He return mPlayingTimeMs; 9390a429916782c20980e7f0893c503c633b8341f88Marie Janssen } 9400a429916782c20980e7f0893c503c633b8341f88Marie Janssen 9413b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen public boolean equals(MediaAttributes other) { 942c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (other == null) { 9433b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return false; 944c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9453b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 946c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mExists != other.mExists) { 9473b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return false; 948c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9493b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 950c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mExists) { 9513b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return true; 952c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9533b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9548bc413b0b749ea9df59e858493273e05087fe887Jack He return (mTitle.equals(other.mTitle)) && (mArtistName.equals(other.mArtistName)) 955c4fbd756e2645147470c486ae96f2253f5e13a52Jack He && (mAlbumName.equals(other.mAlbumName)) && (mMediaNumber.equals( 956c4fbd756e2645147470c486ae96f2253f5e13a52Jack He other.mMediaNumber)) && (mMediaTotalNumber.equals(other.mMediaTotalNumber)) 9578bc413b0b749ea9df59e858493273e05087fe887Jack He && (mGenre.equals(other.mGenre)) && (mPlayingTimeMs == other.mPlayingTimeMs); 9583b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9593b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9603b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen public String getString(int attrId) { 961c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mExists) { 9623b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return new String(); 963c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 9643b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9653b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen switch (attrId) { 9663b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_TITLE: 9678bc413b0b749ea9df59e858493273e05087fe887Jack He return mTitle; 9683b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_ARTIST_NAME: 9698bc413b0b749ea9df59e858493273e05087fe887Jack He return mArtistName; 9703b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_ALBUM_NAME: 9718bc413b0b749ea9df59e858493273e05087fe887Jack He return mAlbumName; 9723b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_MEDIA_NUMBER: 9738bc413b0b749ea9df59e858493273e05087fe887Jack He return mMediaNumber; 9743b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_MEDIA_TOTAL_NUMBER: 9758bc413b0b749ea9df59e858493273e05087fe887Jack He return mMediaTotalNumber; 9763b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_GENRE: 9778bc413b0b749ea9df59e858493273e05087fe887Jack He return mGenre; 9783b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen case ATTR_PLAYING_TIME_MS: 9798bc413b0b749ea9df59e858493273e05087fe887Jack He return Long.toString(mPlayingTimeMs); 9803b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen default: 9813b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return new String(); 9823b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9833b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 9843b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9853b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private String stringOrBlank(String s) { 9863b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return s == null ? new String() : s; 9873b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen } 988c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 9893b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen private String longStringOrBlank(Long s) { 9903b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return s == null ? new String() : s.toString(); 991c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 992c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 9932fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 994c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu public String toString() { 9958bc413b0b749ea9df59e858493273e05087fe887Jack He if (!mExists) { 9963b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen return "[MediaAttributes: none]"; 997e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 9983b9b0ca02d74a95c3f1f5b0d7bc58a8a1f9c44dfMarie Janssen 9998bc413b0b749ea9df59e858493273e05087fe887Jack He return "[MediaAttributes: " + mTitle + " - " + mAlbumName + " by " + mArtistName + " (" 10008bc413b0b749ea9df59e858493273e05087fe887Jack He + mPlayingTimeMs + " " + mMediaNumber + "/" + mMediaTotalNumber + ") " + mGenre 10010a429916782c20980e7f0893c503c633b8341f88Marie Janssen + "]"; 1002c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1003cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen 1004cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen public String toRedactedString() { 10058bc413b0b749ea9df59e858493273e05087fe887Jack He if (!mExists) { 1006cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen return "[MediaAttributes: none]"; 1007cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen } 1008cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen 1009c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return "[MediaAttributes: " + Utils.ellipsize(mTitle) + " - " + Utils.ellipsize( 1010c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAlbumName) + " by " + Utils.ellipsize(mArtistName) + " (" + mPlayingTimeMs 1011c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " " + mMediaNumber + "/" + mMediaTotalNumber + ") " + mGenre + "]"; 1012cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen } 1013c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1014c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 101585aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker private void updateCurrentMediaState() { 1016f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen // Only do player updates when we aren't registering for track changes. 10175aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen MediaAttributes currentAttributes; 101859b1c77f883bd97816332046a3a98be4431cceddMarie Janssen PlaybackState newState = updatePlaybackState(); 101959b1c77f883bd97816332046a3a98be4431cceddMarie Janssen 1020ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen synchronized (this) { 1021ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen if (mMediaController == null) { 10225aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen currentAttributes = new MediaAttributes(null); 1023c9f4e0d24e39b372452fa809b12f9c588b29abd9Marie Janssen } else { 10245aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen currentAttributes = new MediaAttributes(mMediaController.getMetadata()); 10250a429916782c20980e7f0893c503c633b8341f88Marie Janssen } 10260e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen } 1027e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1028cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker byte newPlayStatus = getBluetoothPlayState(newState); 1029cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker 1030cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker if (newState.getState() != PlaybackState.STATE_BUFFERING 1031cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker && newState.getState() != PlaybackState.STATE_NONE) { 1032cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker long newQueueId = MediaSession.QueueItem.UNKNOWN_ID; 1033c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (newState != null) { 1034c4fbd756e2645147470c486ae96f2253f5e13a52Jack He newQueueId = newState.getActiveQueueItemId(); 1035c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 103606457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski if (DEBUG) { 103706457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski Log.v(TAG, 103806457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski "Media update: id " + mLastQueueId + "➡" + newQueueId + "? " + currentAttributes 103906457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski .toRedactedString() + " : " + mMediaAttributes.toRedactedString()); 104006457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski } 1041cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker 104285aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker if (mAvailablePlayerViewChanged) { 104385aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker registerNotificationRspAvalPlayerChangedNative( 104485aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker AvrcpConstants.NOTIFICATION_TYPE_CHANGED); 104585aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mAvailablePlayerViewChanged = false; 104685aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker return; 104785aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker } 104885aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker 104985aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker if (mAddrPlayerChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM 105085aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker && mReportedPlayerID != mCurrAddrPlayerID) { 105185aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker registerNotificationRspAvalPlayerChangedNative( 105285aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker AvrcpConstants.NOTIFICATION_TYPE_CHANGED); 105385aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker registerNotificationRspAddrPlayerChangedNative( 105485aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker AvrcpConstants.NOTIFICATION_TYPE_CHANGED, mCurrAddrPlayerID, sUIDCounter); 105585aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker 105685aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mAvailablePlayerViewChanged = false; 105785aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 105885aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mReportedPlayerID = mCurrAddrPlayerID; 105985aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker 106085aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker // Update the now playing list without sending the notification 106185aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 106285aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mAddressedMediaPlayer.updateNowPlayingList(mMediaController); 106385aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 106485aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker } 106585aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker 1066cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker // Dont send now playing list changed if the player doesn't support browsing 1067cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker MediaPlayerInfo info = getAddressedPlayerInfo(); 1068cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker if (info != null && info.isBrowseSupported()) { 106906457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski if (DEBUG) { 107006457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski Log.v(TAG, "Check if NowPlayingList is updated"); 107106457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski } 1072cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker mAddressedMediaPlayer.updateNowPlayingList(mMediaController); 1073cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker } 1074cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker 1075cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker // Notify track changed if: 107685aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker // - The CT is registered for the notification 1077cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker // - Queue ID is UNKNOWN and MediaMetadata is different 107885aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker // - Queue ID is valid and different from last Queue ID sent 107985aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker if ((newQueueId == -1 || newQueueId != mLastQueueId) 108085aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker && mTrackChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM 108185aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker && !currentAttributes.equals(mMediaAttributes) 108285aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker && newPlayStatus == PLAYSTATUS_PLAYING) { 1083cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker Log.v(TAG, "Send track changed"); 1084cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker mMediaAttributes = currentAttributes; 1085cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker mLastQueueId = newQueueId; 108685aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker sendTrackChangedRsp(false); 1087cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker } 1088cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker } else { 1089cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker Log.i(TAG, "Skipping update due to invalid playback state"); 1090c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1091cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker 1092cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker // still send the updated play state if the playback state is none or buffering 109306457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski if (DEBUG) { 109406457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski Log.v(TAG, "play status change " + mReportedPlayStatus + "➡" + newPlayStatus 109506457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski + " mPlayStatusChangedNT: " + mPlayStatusChangedNT); 109606457b672e7182b66230e9da553f261494b9bc03Jakub Pawlowski } 1097c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mPlayStatusChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM || (mReportedPlayStatus 1098c4fbd756e2645147470c486ae96f2253f5e13a52Jack He != newPlayStatus)) { 1099cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker sendPlaybackStatus(AvrcpConstants.NOTIFICATION_TYPE_CHANGED, newPlayStatus); 1100cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker } 1101cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker 110259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen sendPlayPosNotificationRsp(false); 1103c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1104c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1105e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void getRcFeaturesRequestFromNative(byte[] address, int features) { 1106ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1107ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1108ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "getRcFeaturesRequestFromNative: mHandler is already null"); 1109ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1110ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1111ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1112ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_RC_FEATURES, features, 0, 1113e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Utils.getAddressStringFromByte(address)); 1114ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 111517675906064bb72fdcca75baa56cdf8bb8968d01John Du } 111617675906064bb72fdcca75baa56cdf8bb8968d01John Du 1117e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void getPlayStatusRequestFromNative(byte[] address) { 1118ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1119ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1120ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "getPlayStatusRequestFromNative: mHandler is already null"); 1121ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1122ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1123ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1124ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_PLAY_STATUS); 1125e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = address; 1126ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1127c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1128c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 112989728a4d50001ac76d05efa1c916711ef9f9c2b4Marie Janssen private void getElementAttrRequestFromNative(byte[] address, byte numAttr, int[] attrs) { 1130e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpCmd avrcpCmdobj = new AvrcpCmd(); 1131e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpCmd.ElementAttrCmd elemAttr = avrcpCmdobj.new ElementAttrCmd(address, numAttr, attrs); 1132e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Message msg = mHandler.obtainMessage(MSG_NATIVE_REQ_GET_ELEM_ATTRS); 1133e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = elemAttr; 1134c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu mHandler.sendMessage(msg); 1135c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1136c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1137c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private void registerNotificationRequestFromNative(byte[] address, int eventId, int param) { 1138ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1139ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1140ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) { 1141ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Log.d(TAG, "registerNotificationRequestFromNative: mHandler is already null"); 1142ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1143ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1144ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1145ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_REGISTER_NOTIFICATION, eventId, param); 1146e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = address; 1147ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1148c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1149c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1150e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void processRegisterNotification(byte[] address, int eventId, int param) { 1151c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu switch (eventId) { 1152c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu case EVT_PLAY_STATUS_CHANGED: 115359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mPlayStatusChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 115459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen updatePlaybackState(); 1155cb00f2feb8405508707e41e463a79bf77eac7bc7Ajay Panicker sendPlaybackStatus(AvrcpConstants.NOTIFICATION_TYPE_INTERIM, mReportedPlayStatus); 1156c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu break; 1157c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1158c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu case EVT_TRACK_CHANGED: 11590e949676c5097e1f259caa2e549ecedf0c09269dMarie Janssen Log.v(TAG, "Track changed notification enabled"); 1160e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 1161cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker sendTrackChangedRsp(true); 1162c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu break; 1163c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1164aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu case EVT_PLAY_POS_CHANGED: 1165e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 1166e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mPlaybackIntervalMs = (long) param * 1000L; 1167fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen sendPlayPosNotificationRsp(true); 1168aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu break; 1169aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 1170e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case EVT_AVBL_PLAYERS_CHANGED: 1171e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Notify remote available players changed */ 1172c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1173c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Available Players notification enabled"); 1174c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1175e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah registerNotificationRspAvalPlayerChangedNative( 1176e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpConstants.NOTIFICATION_TYPE_INTERIM); 1177e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah break; 1178e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1179e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case EVT_ADDR_PLAYER_CHANGED: 1180e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Notify remote addressed players changed */ 1181c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1182c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Addressed Player notification enabled"); 1183c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1184e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah registerNotificationRspAddrPlayerChangedNative( 1185c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpConstants.NOTIFICATION_TYPE_INTERIM, mCurrAddrPlayerID, sUIDCounter); 118659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mAddrPlayerChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 118759b1c77f883bd97816332046a3a98be4431cceddMarie Janssen mReportedPlayerID = mCurrAddrPlayerID; 1188e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah break; 1189e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1190e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case EVENT_UIDS_CHANGED: 1191c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1192c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "UIDs changed notification enabled"); 1193c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1194c4fbd756e2645147470c486ae96f2253f5e13a52Jack He registerNotificationRspUIDsChangedNative(AvrcpConstants.NOTIFICATION_TYPE_INTERIM, 1195c4fbd756e2645147470c486ae96f2253f5e13a52Jack He sUIDCounter); 1196e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah break; 1197e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1198e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case EVENT_NOW_PLAYING_CONTENT_CHANGED: 1199c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1200c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Now Playing List changed notification enabled"); 1201c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1202e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* send interim response to remote device */ 120305723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 1204e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspNowPlayingChangedNative( 1205e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpConstants.NOTIFICATION_TYPE_INTERIM)) { 1206c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "EVENT_NOW_PLAYING_CONTENT_CHANGED: " 1207c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + "registerNotificationRspNowPlayingChangedNative for Interim rsp " 1208c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + "failed!"); 1209e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1210e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah break; 1211c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1212c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1213c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1214e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handlePassthroughCmdRequestFromNative(byte[] address, int id, int keyState) { 1215ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1216ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1217ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) { 1218ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Log.d(TAG, "handlePassthroughCmdRequestFromNative: mHandler is already null"); 1219ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1220ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1221ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1222ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1223ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PASS_THROUGH, id, keyState); 1224ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1225ace834feb02adabd61f628c4471147aea02d939cJohn Du } 1226ace834feb02adabd61f628c4471147aea02d939cJohn Du 12275aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen private void sendTrackChangedRsp(boolean registering) { 12285aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen if (!registering && mTrackChangedNT != AvrcpConstants.NOTIFICATION_TYPE_INTERIM) { 1229c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1230c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "sendTrackChangedRsp: Not registered or registering."); 1231c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 12328ac88214fdbf5e5197033b89ba82a6bf728706a4Marie Janssen return; 12338ac88214fdbf5e5197033b89ba82a6bf728706a4Marie Janssen } 12345aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen 12355aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 1236c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (registering) { 1237c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mTrackChangedNT = AvrcpConstants.NOTIFICATION_TYPE_INTERIM; 1238c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 12395aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen 12405aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen MediaPlayerInfo info = getAddressedPlayerInfo(); 12415aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen // for non-browsable players or no player 1242eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen if (info != null && !info.isBrowseSupported()) { 12435aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen byte[] track = AvrcpConstants.TRACK_IS_SELECTED; 1244c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!mMediaAttributes.mExists) { 1245c4fbd756e2645147470c486ae96f2253f5e13a52Jack He track = AvrcpConstants.NO_TRACK_SELECTED; 1246c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 12475aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen registerNotificationRspTrackChangeNative(mTrackChangedNT, track); 12485aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen return; 1249e8e870c24930f9b687572dbb80614e5aad6fbdfaberyl hou } 1250e8e870c24930f9b687572dbb80614e5aad6fbdfaberyl hou 12515aca05c1d79f3412b6964b3b6335ad6f2d558756Marie Janssen mAddressedMediaPlayer.sendTrackChangeWithId(mTrackChangedNT, mMediaController); 1252c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu } 1253c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1254aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu private long getPlayPosition() { 1255e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (mCurrentPlayState == null) { 1256f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen return -1L; 1257e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1258f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 1259e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (mCurrentPlayState.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) { 1260f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen return -1L; 1261e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1262f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 1263f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen if (isPlayingState(mCurrentPlayState)) { 12640a429916782c20980e7f0893c503c633b8341f88Marie Janssen long sinceUpdate = 12650a429916782c20980e7f0893c503c633b8341f88Marie Janssen (SystemClock.elapsedRealtime() - mCurrentPlayState.getLastPositionUpdateTime()); 12660a429916782c20980e7f0893c503c633b8341f88Marie Janssen return sinceUpdate + mCurrentPlayState.getPosition(); 1267aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu } 1268f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 12693635a926bd7316a55b288a54d409a1070a9c19e8Marie Janssen return mCurrentPlayState.getPosition(); 1270aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu } 1271aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu 127259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private boolean isPlayingState(@Nullable PlaybackState state) { 1273c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (state == null) { 1274c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return false; 1275c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1276cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker return (state != null) && (state.getState() == PlaybackState.STATE_PLAYING); 1277188f205b5f093850d4cc627917a21204be36c56aZhihai Xu } 1278188f205b5f093850d4cc627917a21204be36c56aZhihai Xu 127917675906064bb72fdcca75baa56cdf8bb8968d01John Du /** 1280f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen * Sends a play position notification, or schedules one to be 1281f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen * sent later at an appropriate time. If |requested| is true, 1282f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen * does both because this was called in reponse to a request from the 1283f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen * TG. 1284f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen */ 1285f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen private void sendPlayPosNotificationRsp(boolean requested) { 1286e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!requested && mPlayPosChangedNT != AvrcpConstants.NOTIFICATION_TYPE_INTERIM) { 1287c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1288c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "sendPlayPosNotificationRsp: Not registered or requesting."); 1289c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1290fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen return; 1291fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen } 1292fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen 1293ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1294ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1295ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "sendPlayPosNotificationRsp: handler is already null"); 1296ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1297ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1298ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1299f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen long playPositionMs = getPlayPosition(); 13000ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen String debugLine = "sendPlayPosNotificationRsp: "; 1301f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 1302f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen // mNextPosMs is set to -1 when the previous position was invalid 1303f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen // so this will be true if the new position is valid & old was invalid. 1304f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen // mPlayPositionMs is set to -1 when the new position is invalid, 1305f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen // and the old mPrevPosMs is >= 0 so this is true when the new is invalid 1306f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen // and the old was valid. 13070ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen if (DEBUG) { 13080ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen debugLine += "(" + requested + ") " + mPrevPosMs + " <=? " + playPositionMs + " <=? " 13090ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen + mNextPosMs; 1310c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (isPlayingState(mCurrentPlayState)) { 1311c4fbd756e2645147470c486ae96f2253f5e13a52Jack He debugLine += " Playing"; 1312c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 13130ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen debugLine += " State: " + mCurrentPlayState.getState(); 13140ace2d5941549e466ada4258c6c6fbb1debdf48dMarie Janssen } 1315c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (requested || ( 1316c4fbd756e2645147470c486ae96f2253f5e13a52Jack He (mLastReportedPosition != playPositionMs) && (playPositionMs >= mNextPosMs) || ( 1317c4fbd756e2645147470c486ae96f2253f5e13a52Jack He playPositionMs <= mPrevPosMs))) { 1318c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!requested) { 1319c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mPlayPosChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 1320c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1321e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah registerNotificationRspPlayPosNative(mPlayPosChangedNT, (int) playPositionMs); 1322fa81085f6cda571d56c62eb1d646ae4a52cb90eeMarie Janssen mLastReportedPosition = playPositionMs; 1323f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen if (playPositionMs != PlaybackState.PLAYBACK_POSITION_UNKNOWN) { 1324f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen mNextPosMs = playPositionMs + mPlaybackIntervalMs; 1325f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen mPrevPosMs = playPositionMs - mPlaybackIntervalMs; 1326f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } else { 1327f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen mNextPosMs = -1; 1328f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen mPrevPosMs = -1; 1329f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } 1330f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } 1331f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 1332ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.removeMessages(MSG_PLAY_INTERVAL_TIMEOUT); 1333c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mPlayPosChangedNT == AvrcpConstants.NOTIFICATION_TYPE_INTERIM && isPlayingState( 1334c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mCurrentPlayState)) { 1335ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_PLAY_INTERVAL_TIMEOUT); 1336f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen long delay = mPlaybackIntervalMs; 1337f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen if (mNextPosMs != -1) { 1338f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen delay = mNextPosMs - (playPositionMs > 0 ? playPositionMs : 0); 1339f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } 1340c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1341c4fbd756e2645147470c486ae96f2253f5e13a52Jack He debugLine += " Timeout " + delay + "ms"; 1342c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1343ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessageDelayed(msg, delay); 1344f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } 1345c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1346c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, debugLine); 1347c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1348f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen } 1349f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen 1350f7942360dd9d807bea087c4ef42773f5e800c0c4Marie Janssen /** 135117675906064bb72fdcca75baa56cdf8bb8968d01John Du * This is called from AudioService. It will return whether this device supports abs volume. 135217675906064bb72fdcca75baa56cdf8bb8968d01John Du * NOT USED AT THE MOMENT. 135317675906064bb72fdcca75baa56cdf8bb8968d01John Du */ 135417675906064bb72fdcca75baa56cdf8bb8968d01John Du public boolean isAbsoluteVolumeSupported() { 135517675906064bb72fdcca75baa56cdf8bb8968d01John Du return ((mFeatures & BTRC_FEAT_ABSOLUTE_VOLUME) != 0); 135617675906064bb72fdcca75baa56cdf8bb8968d01John Du } 135717675906064bb72fdcca75baa56cdf8bb8968d01John Du 135817675906064bb72fdcca75baa56cdf8bb8968d01John Du /** 135917675906064bb72fdcca75baa56cdf8bb8968d01John Du * We get this call from AudioService. This will send a message to our handler object, 136017675906064bb72fdcca75baa56cdf8bb8968d01John Du * requesting our handler to call setVolumeNative() 136117675906064bb72fdcca75baa56cdf8bb8968d01John Du */ 136217675906064bb72fdcca75baa56cdf8bb8968d01John Du public void setAbsoluteVolume(int volume) { 136311798b011c962b602217b479130d413f3b30f19aLiejun Tao if (volume == mLocalVolume) { 1364c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1365c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "setAbsoluteVolume is setting same index, ignore " + volume); 1366c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 136711798b011c962b602217b479130d413f3b30f19aLiejun Tao return; 136811798b011c962b602217b479130d413f3b30f19aLiejun Tao } 136911798b011c962b602217b479130d413f3b30f19aLiejun Tao 1370ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1371ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1372ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "setAbsoluteVolume: mHandler is already null"); 1373ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1374ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1375ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1376ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_SET_ABSOLUTE_VOLUME, volume, 0); 1377ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 13785c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta } 13795c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 138017675906064bb72fdcca75baa56cdf8bb8968d01John Du /* Called in the native layer as a btrc_callback to return the volume set on the carkit in the 138117675906064bb72fdcca75baa56cdf8bb8968d01John Du * case when the volume is change locally on the carkit. This notification is not called when 138217675906064bb72fdcca75baa56cdf8bb8968d01John Du * the volume is changed from the phone. 138317675906064bb72fdcca75baa56cdf8bb8968d01John Du * 138417675906064bb72fdcca75baa56cdf8bb8968d01John Du * This method will send a message to our handler to change the local stored volume and notify 138517675906064bb72fdcca75baa56cdf8bb8968d01John Du * AudioService to update the UI 138617675906064bb72fdcca75baa56cdf8bb8968d01John Du */ 1387e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void volumeChangeRequestFromNative(byte[] address, int volume, int ctype) { 1388ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1389ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1390ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "volumeChangeRequestFromNative: mHandler is already null"); 1391ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1392ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1393ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1394ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_VOLUME_CHANGE, volume, ctype); 1395e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Bundle data = new Bundle(); 1396c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByteArray("BdAddress", address); 1397e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.setData(data); 1398ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1399e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1400e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1401c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private void getFolderItemsRequestFromNative(byte[] address, byte scope, long startItem, 1402c4fbd756e2645147470c486ae96f2253f5e13a52Jack He long endItem, byte numAttr, int[] attrIds) { 1403ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1404ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1405ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "getFolderItemsRequestFromNative: mHandler is already null"); 1406ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1407ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1408e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpCmd avrcpCmdobj = new AvrcpCmd(); 1409c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpCmd.FolderItemsCmd folderObj = 1410c4fbd756e2645147470c486ae96f2253f5e13a52Jack He avrcpCmdobj.new FolderItemsCmd(address, scope, startItem, endItem, numAttr, 1411c4fbd756e2645147470c486ae96f2253f5e13a52Jack He attrIds); 1412ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_FOLDER_ITEMS, 0, 0); 1413e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = folderObj; 1414ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1415e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1416e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1417e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void setAddressedPlayerRequestFromNative(byte[] address, int playerId) { 1418ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1419ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1420ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "setAddressedPlayerRequestFromNative: mHandler is already null"); 1421ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1422ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1423ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1424ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_ADDR_PLAYER, playerId, 0); 1425e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = address; 1426ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1427e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1428e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1429e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void setBrowsedPlayerRequestFromNative(byte[] address, int playerId) { 1430ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1431ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1432ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "setBrowsedPlayerRequestFromNative: mHandler is already null"); 1433ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1434ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1435ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1436ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_SET_BR_PLAYER, playerId, 0); 1437e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = address; 1438ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1439e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1440e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1441e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void changePathRequestFromNative(byte[] address, byte direction, byte[] folderUid) { 1442ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1443ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1444ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "changePathRequestFromNative: mHandler is already null"); 1445ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1446ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1447ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1448e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Bundle data = new Bundle(); 1449ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_CHANGE_PATH); 1450c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByteArray("BdAddress", address); 1451c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByteArray("folderUid", folderUid); 1452c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByte("direction", direction); 1453e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.setData(data); 1454ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1455e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1456e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1457c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private void getItemAttrRequestFromNative(byte[] address, byte scope, byte[] itemUid, 1458c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int uidCounter, byte numAttr, int[] attrs) { 1459ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1460ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1461ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "getItemAttrRequestFromNative: mHandler is already null"); 1462ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1463ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1464e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah AvrcpCmd avrcpCmdobj = new AvrcpCmd(); 1465c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AvrcpCmd.ItemAttrCmd itemAttr = 1466c4fbd756e2645147470c486ae96f2253f5e13a52Jack He avrcpCmdobj.new ItemAttrCmd(address, scope, itemUid, uidCounter, numAttr, attrs); 1467ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_ITEM_ATTR); 1468e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = itemAttr; 1469ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1470e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1471e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1472e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void searchRequestFromNative(byte[] address, int charsetId, byte[] searchStr) { 1473e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Search is not supported */ 1474e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen Log.w(TAG, "searchRequestFromNative: search is not supported"); 1475e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah searchRspNative(address, AvrcpConstants.RSP_SRCH_NOT_SPRTD, 0, 0); 1476e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1477e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1478e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void playItemRequestFromNative(byte[] address, byte scope, int uidCounter, byte[] uid) { 1479ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1480ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1481ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "playItemRequestFromNative: mHandler is already null"); 1482ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1483ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1484ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1485e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Bundle data = new Bundle(); 1486ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_PLAY_ITEM); 1487c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByteArray("BdAddress", address); 1488c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByteArray("uid", uid); 1489c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putInt("uidCounter", uidCounter); 1490c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data.putByte("scope", scope); 1491ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1492e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.setData(data); 1493ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1494e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1495e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1496c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private void addToPlayListRequestFromNative(byte[] address, byte scope, byte[] uid, 1497c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int uidCounter) { 1498e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* add to NowPlaying not supported */ 1499e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen Log.w(TAG, "addToPlayListRequestFromNative: not supported! scope=" + scope); 1500e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah addToNowPlayingRspNative(address, AvrcpConstants.RSP_INTERNAL_ERR); 1501e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1502e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1503e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void getTotalNumOfItemsRequestFromNative(byte[] address, byte scope) { 1504ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1505ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1506ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "getTotalNumOfItemsRequestFromNative: mHandler is already null"); 1507ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1508ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1509ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1510e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Bundle data = new Bundle(); 1511ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_NATIVE_REQ_GET_TOTAL_NUM_OF_ITEMS); 1512e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.arg1 = scope; 1513e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah msg.obj = address; 1514ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 151517675906064bb72fdcca75baa56cdf8bb8968d01John Du } 151617675906064bb72fdcca75baa56cdf8bb8968d01John Du 15172e90040ffc6f1c4cd5187338c9f708df4d380aeeMatthew Xie private void notifyVolumeChanged(int volume) { 15182e90040ffc6f1c4cd5187338c9f708df4d380aeeMatthew Xie mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 1519c4fbd756e2645147470c486ae96f2253f5e13a52Jack He AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME); 152017675906064bb72fdcca75baa56cdf8bb8968d01John Du } 152117675906064bb72fdcca75baa56cdf8bb8968d01John Du 152217675906064bb72fdcca75baa56cdf8bb8968d01John Du private int convertToAudioStreamVolume(int volume) { 152317675906064bb72fdcca75baa56cdf8bb8968d01John Du // Rescale volume to match AudioSystem's volume 1524c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return (int) Math.floor((double) volume * mAudioStreamMax / AVRCP_MAX_VOL); 152517675906064bb72fdcca75baa56cdf8bb8968d01John Du } 152617675906064bb72fdcca75baa56cdf8bb8968d01John Du 152717675906064bb72fdcca75baa56cdf8bb8968d01John Du private int convertToAvrcpVolume(int volume) { 1528c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return (int) Math.ceil((double) volume * AVRCP_MAX_VOL / mAudioStreamMax); 152917675906064bb72fdcca75baa56cdf8bb8968d01John Du } 153017675906064bb72fdcca75baa56cdf8bb8968d01John Du 1531fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov private void blackListCurrentDevice(String reason) { 153211798b011c962b602217b479130d413f3b30f19aLiejun Tao mFeatures &= ~BTRC_FEAT_ABSOLUTE_VOLUME; 153311798b011c962b602217b479130d413f3b30f19aLiejun Tao mAudioManager.avrcpSupportsAbsoluteVolume(mAddress, isAbsoluteVolumeSupported()); 153411798b011c962b602217b479130d413f3b30f19aLiejun Tao 1535c4fbd756e2645147470c486ae96f2253f5e13a52Jack He SharedPreferences pref = 1536c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE); 153711798b011c962b602217b479130d413f3b30f19aLiejun Tao SharedPreferences.Editor editor = pref.edit(); 1538fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov 1539fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov StringBuilder sb = new StringBuilder(); 1540fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov sb.append("Time: "); 1541fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov sb.append(android.text.format.DateFormat.format("yyyy/MM/dd HH:mm:ss", 1542fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov System.currentTimeMillis())); 1543fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov sb.append(" Reason: "); 1544fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov sb.append(reason); 1545fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov editor.putString(mAddress, sb.toString()); 15467eeb95b6f29a6f55e117e329468168d4bcbec0c8Jack He editor.apply(); 154711798b011c962b602217b479130d413f3b30f19aLiejun Tao } 154811798b011c962b602217b479130d413f3b30f19aLiejun Tao 154911798b011c962b602217b479130d413f3b30f19aLiejun Tao private int modifyRcFeatureFromBlacklist(int feature, String address) { 1550c4fbd756e2645147470c486ae96f2253f5e13a52Jack He SharedPreferences pref = 1551c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE); 155211798b011c962b602217b479130d413f3b30f19aLiejun Tao if (!pref.contains(address)) { 155311798b011c962b602217b479130d413f3b30f19aLiejun Tao return feature; 155411798b011c962b602217b479130d413f3b30f19aLiejun Tao } 1555fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov return feature & ~BTRC_FEAT_ABSOLUTE_VOLUME; 155611798b011c962b602217b479130d413f3b30f19aLiejun Tao } 155711798b011c962b602217b479130d413f3b30f19aLiejun Tao 155811798b011c962b602217b479130d413f3b30f19aLiejun Tao public void resetBlackList(String address) { 1559c4fbd756e2645147470c486ae96f2253f5e13a52Jack He SharedPreferences pref = 1560c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE); 156111798b011c962b602217b479130d413f3b30f19aLiejun Tao SharedPreferences.Editor editor = pref.edit(); 156211798b011c962b602217b479130d413f3b30f19aLiejun Tao editor.remove(address); 15637eeb95b6f29a6f55e117e329468168d4bcbec0c8Jack He editor.apply(); 156411798b011c962b602217b479130d413f3b30f19aLiejun Tao } 156511798b011c962b602217b479130d413f3b30f19aLiejun Tao 1566188f205b5f093850d4cc627917a21204be36c56aZhihai Xu /** 1567188f205b5f093850d4cc627917a21204be36c56aZhihai Xu * This is called from A2dpStateMachine to set A2dp audio state. 1568188f205b5f093850d4cc627917a21204be36c56aZhihai Xu */ 1569188f205b5f093850d4cc627917a21204be36c56aZhihai Xu public void setA2dpAudioState(int state) { 1570ded973620f204f11f20d40928735a4d87e00afedHansong Zhang final AvrcpMessageHandler handler = mHandler; 1571ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (handler == null) { 1572ded973620f204f11f20d40928735a4d87e00afedHansong Zhang if (DEBUG) Log.d(TAG, "setA2dpAudioState: mHandler is already null"); 1573ded973620f204f11f20d40928735a4d87e00afedHansong Zhang return; 1574ded973620f204f11f20d40928735a4d87e00afedHansong Zhang } 1575ded973620f204f11f20d40928735a4d87e00afedHansong Zhang 1576ded973620f204f11f20d40928735a4d87e00afedHansong Zhang Message msg = handler.obtainMessage(MSG_SET_A2DP_AUDIO_STATE, state, 0); 1577ded973620f204f11f20d40928735a4d87e00afedHansong Zhang handler.sendMessage(msg); 1578188f205b5f093850d4cc627917a21204be36c56aZhihai Xu } 1579188f205b5f093850d4cc627917a21204be36c56aZhihai Xu 15800427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker private class AvrcpServiceBootReceiver extends BroadcastReceiver { 15810427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker @Override 15820427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker public void onReceive(Context context, Intent intent) { 15830427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker String action = intent.getAction(); 15849c2ff5bb5082c653ee91d336dcd7f95e4c25e833Ajay Panicker if (action.equals(Intent.ACTION_USER_UNLOCKED)) { 1585c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1586c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "User unlocked, initializing player lists"); 1587c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 15880427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker /* initializing media player's list */ 1589754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker buildBrowsablePlayerList(); 15900427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker } 15910427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker } 15920427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker } 15930427c02017744a749b99230b5bd080e2d4cfa3e1Ajay Panicker 1594e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private class AvrcpServiceBroadcastReceiver extends BroadcastReceiver { 1595e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah @Override 1596e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void onReceive(Context context, Intent intent) { 1597e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String action = intent.getAction(); 1598c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1599c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "AvrcpServiceBroadcastReceiver-> Action: " + action); 1600c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1601e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1602c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || action.equals( 1603c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Intent.ACTION_PACKAGE_DATA_CLEARED)) { 1604e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 1605e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // a package is being removed, not replaced 1606e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String packageName = intent.getData().getSchemeSpecificPart(); 1607e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (packageName != null) { 1608e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah handlePackageModified(packageName, true); 1609e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1610e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1611e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1612c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else if (action.equals(Intent.ACTION_PACKAGE_ADDED) || action.equals( 1613c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Intent.ACTION_PACKAGE_CHANGED)) { 1614e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String packageName = intent.getData().getSchemeSpecificPart(); 1615c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1616c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "AvrcpServiceBroadcastReceiver-> packageName: " + packageName); 1617c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1618e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (packageName != null) { 1619e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah handlePackageModified(packageName, false); 1620e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1621e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1622e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1623838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 1624838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood 1625e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handlePackageModified(String packageName, boolean removed) { 1626c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1627c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "packageName: " + packageName + " removed: " + removed); 1628c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1629c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1630e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (removed) { 1631384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen removeMediaPlayerInfo(packageName); 1632e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // old package is removed, updating local browsable player's list 1633e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (isBrowseSupported(packageName)) { 1634e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah removePackageFromBrowseList(packageName); 1635e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1636e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 1637e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // new package has been added. 1638e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (isBrowsableListUpdated(packageName)) { 1639e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // Rebuilding browsable players list 1640754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker buildBrowsablePlayerList(); 1641e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1642e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1643e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1644c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 1645e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean isBrowsableListUpdated(String newPackageName) { 1646e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // getting the browsable media players list from package manager 1647e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Intent intent = new Intent("android.media.browse.MediaBrowserService"); 1648c4fbd756e2645147470c486ae96f2253f5e13a52Jack He List<ResolveInfo> resInfos = 1649c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mPackageManager.queryIntentServices(intent, PackageManager.MATCH_ALL); 1650e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah for (ResolveInfo resolveInfo : resInfos) { 16513843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen if (resolveInfo.serviceInfo.packageName.equals(newPackageName)) { 1652c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 16533843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen Log.d(TAG, 16543843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen "isBrowsableListUpdated: package includes MediaBrowserService, true"); 1655c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 16563843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen return true; 16573843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen } 1658e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1659c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu 16603843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen // if list has different size 16613843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen if (resInfos.size() != mBrowsePlayerInfoList.size()) { 1662c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1663c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "isBrowsableListUpdated: browsable list size mismatch, true"); 1664c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 16653843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen return true; 1666e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 16673843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen 16683843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen Log.d(TAG, "isBrowsableListUpdated: false"); 16693843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen return false; 1670e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1671e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1672511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private void removePackageFromBrowseList(String packageName) { 1673c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1674c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "removePackageFromBrowseList: " + packageName); 1675c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1676511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mBrowsePlayerInfoList) { 1677511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int browseInfoID = getBrowseId(packageName); 1678511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (browseInfoID != -1) { 1679511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mBrowsePlayerInfoList.remove(browseInfoID); 1680511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1681e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1682e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1683e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1684e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* 1685e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * utility function to get the browse player index from global browsable 1686e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * list. It may return -1 if specified package name is not in the list. 1687e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 1688511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private int getBrowseId(String packageName) { 1689e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah boolean response = false; 1690e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int browseInfoID = 0; 1691511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mBrowsePlayerInfoList) { 1692511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (BrowsePlayerInfo info : mBrowsePlayerInfoList) { 1693511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (info.packageName.equals(packageName)) { 1694511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen response = true; 1695511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen break; 1696511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1697511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen browseInfoID++; 1698e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1699e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1700e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1701e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!response) { 1702e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah browseInfoID = -1; 1703e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1704e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1705c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1706c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "getBrowseId for packageName: " + packageName + " , browseInfoID: " 1707c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + browseInfoID); 1708c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1709e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return browseInfoID; 1710e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1711e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1712e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void setAddressedPlayer(byte[] bdaddr, int selectedId) { 1713eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen String functionTag = "setAddressedPlayer(" + selectedId + "): "; 1714e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1715511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 1716511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (mMediaPlayerInfoList.isEmpty()) { 1717eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Log.w(TAG, functionTag + "no players, send no available players"); 1718eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen setAddressedPlayerRspNative(bdaddr, AvrcpConstants.RSP_NO_AVBL_PLAY); 1719eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen return; 1720eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen } 1721eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen if (!mMediaPlayerInfoList.containsKey(selectedId)) { 1722eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Log.w(TAG, functionTag + "invalid id, sending response back "); 1723eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen setAddressedPlayerRspNative(bdaddr, AvrcpConstants.RSP_INV_PLAYER); 1724eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen return; 1725eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen } 1726eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen 1727eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen if (isPlayerAlreadyAddressed(selectedId)) { 1728511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen MediaPlayerInfo info = getAddressedPlayerInfo(); 1729eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Log.i(TAG, functionTag + "player already addressed: " + info); 1730eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen setAddressedPlayerRspNative(bdaddr, AvrcpConstants.RSP_NO_ERROR); 1731eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen return; 1732eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen } 1733eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen // register new Media Controller Callback and update the current IDs 1734eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen if (!updateCurrentController(selectedId, mCurrBrowsePlayerID)) { 1735eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Log.e(TAG, functionTag + "updateCurrentController failed!"); 1736eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen setAddressedPlayerRspNative(bdaddr, AvrcpConstants.RSP_INTERNAL_ERR); 1737eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen return; 1738eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen } 1739eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen // If we don't have a controller, try to launch the player 1740eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen MediaPlayerInfo info = getAddressedPlayerInfo(); 1741eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen if (info.getMediaController() == null) { 1742eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Intent launch = mPackageManager.getLaunchIntentForPackage(info.getPackageName()); 1743eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen Log.i(TAG, functionTag + "launching player " + launch); 1744eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen mContext.startActivity(launch); 1745e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1746e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1747eb3c55797d3ba16916327effa6b36acec5f1de36Marie Janssen setAddressedPlayerRspNative(bdaddr, AvrcpConstants.RSP_NO_ERROR); 1748e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1749e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1750e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void setBrowsedPlayer(byte[] bdaddr, int selectedId) { 1751e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int status = AvrcpConstants.RSP_NO_ERROR; 1752e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1753e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // checking for error cases 1754511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (mMediaPlayerInfoList.isEmpty()) { 1755e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah status = AvrcpConstants.RSP_NO_AVBL_PLAY; 1756819122df0eff426a43d175b14098339fa9f8f648Marie Janssen Log.w(TAG, "setBrowsedPlayer: No available players! "); 1757e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 1758819122df0eff426a43d175b14098339fa9f8f648Marie Janssen // Workaround for broken controllers selecting ID 0 1759819122df0eff426a43d175b14098339fa9f8f648Marie Janssen // Seen at least on Ford, Chevrolet MyLink 1760819122df0eff426a43d175b14098339fa9f8f648Marie Janssen if (selectedId == 0) { 1761819122df0eff426a43d175b14098339fa9f8f648Marie Janssen Log.w(TAG, "setBrowsedPlayer: workaround invalid id 0"); 1762819122df0eff426a43d175b14098339fa9f8f648Marie Janssen selectedId = mCurrAddrPlayerID; 1763819122df0eff426a43d175b14098339fa9f8f648Marie Janssen } 1764819122df0eff426a43d175b14098339fa9f8f648Marie Janssen 1765e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // update current browse player id and start browsing service 1766e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah updateNewIds(mCurrAddrPlayerID, selectedId); 1767e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String browsedPackage = getPackageName(selectedId); 1768e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1769e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!isPackageNameValid(browsedPackage)) { 1770e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.w(TAG, " Invalid package for id:" + mCurrBrowsePlayerID); 1771e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah status = AvrcpConstants.RSP_INV_PLAYER; 1772e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else if (!isBrowseSupported(browsedPackage)) { 1773c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.w(TAG, "Browse unsupported for id:" + mCurrBrowsePlayerID + ", packagename : " 1774c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + browsedPackage); 1775e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah status = AvrcpConstants.RSP_PLAY_NOT_BROW; 1776e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else if (!startBrowseService(bdaddr, browsedPackage)) { 1777e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "service cannot be started for browse player id:" + mCurrBrowsePlayerID 1778e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah + ", packagename : " + browsedPackage); 1779e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah status = AvrcpConstants.RSP_INTERNAL_ERR; 1780e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1781e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1782e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1783e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (status != AvrcpConstants.RSP_NO_ERROR) { 1784e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah setBrowsedPlayerRspNative(bdaddr, status, (byte) 0x00, 0, null); 1785e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1786e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1787c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1788c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "setBrowsedPlayer for selectedId: " + selectedId + " , status: " + status); 1789c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1790e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1791e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 179205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private MediaSessionManager.OnActiveSessionsChangedListener mActiveSessionListener = 179305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen new MediaSessionManager.OnActiveSessionsChangedListener() { 1794e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 179505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen @Override 179605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void onActiveSessionsChanged( 179705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen List<android.media.session.MediaController> newControllers) { 1798bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssen Set<String> updatedPackages = new HashSet<String>(); 179905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // Update the current players 180005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen for (android.media.session.MediaController controller : newControllers) { 1801bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssen String packageName = controller.getPackageName(); 1802c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1803de778443fdb539d38db92069661fdc18626a4c9cAjay Panicker Log.v(TAG, "ActiveSession: " + MediaControllerFactory.wrap(controller)); 1804c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1805bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssen // Only use the first (highest priority) controller from each package 1806c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (updatedPackages.contains(packageName)) { 1807c4fbd756e2645147470c486ae96f2253f5e13a52Jack He continue; 1808c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 180905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen addMediaPlayerController(controller); 1810bc5aacf160c5cc7ff5a196c7c3c1cf62f322fc14Marie Janssen updatedPackages.add(packageName); 1811eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 1812d996f17ea97b2c592338bcfbc93056d0224da1cdAjay Panicker 1813f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen if (newControllers.size() > 0 && getAddressedPlayerInfo() == null) { 1814c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1815f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen Log.v(TAG, "No addressed player but active sessions, taking first."); 1816c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1817f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen setAddressedMediaSessionPackage(newControllers.get(0).getPackageName()); 1818eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 181985aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 1820e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 182105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen }; 182205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 182378d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen private void setAddressedMediaSessionPackage(@Nullable String packageName) { 182441527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen if (packageName == null) { 182541527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen // Should only happen when there's no media players, reset to no available player. 182641527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen updateCurrentController(0, mCurrBrowsePlayerID); 182741527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen return; 182841527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen } 18295e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker if (packageName.equals("com.android.server.telecom")) { 18305e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker Log.d(TAG, "Ignore addressed media session change to telecom"); 18315e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker return; 18325e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker } 183305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // No change. 1834c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (getPackageName(mCurrAddrPlayerID).equals(packageName)) { 1835c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return; 1836c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1837c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1838c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "Changing addressed media session to " + packageName); 1839c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 184005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // If the player doesn't exist, we need to add it. 184105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (getMediaPlayerInfo(packageName) == null) { 184205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen addMediaPlayerPackage(packageName); 184385aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 184405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 1845511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 1846511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 1847511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (entry.getValue().getPackageName().equals(packageName)) { 1848511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int newAddrID = entry.getKey(); 1849c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1850c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "Set addressed #" + newAddrID + " " + entry.getValue()); 1851c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1852511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen updateCurrentController(newAddrID, mCurrBrowsePlayerID); 185385aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 1854511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return; 1855511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1856e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1857e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 185805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // We shouldn't ever get here. 185905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.e(TAG, "Player info for " + packageName + " doesn't exist!"); 186005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 1861e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 186205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private void setActiveMediaSession(MediaSession.Token token) { 186305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen android.media.session.MediaController activeController = 186405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen new android.media.session.MediaController(mContext, token); 18655e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker if (activeController.getPackageName().equals("com.android.server.telecom")) { 18665e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker Log.d(TAG, "Ignore active media session change to telecom"); 18675e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker return; 18685e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker } 1869c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1870c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "Set active media session " + activeController.getPackageName()); 1871c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 187205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen addMediaPlayerController(activeController); 187305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen setAddressedMediaSessionPackage(activeController.getPackageName()); 187405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 1875e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1876e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean startBrowseService(byte[] bdaddr, String packageName) { 1877e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah boolean status = true; 1878e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1879e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* creating new instance for Browse Media Player */ 1880e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String browseService = getBrowseServiceName(packageName); 1881e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!browseService.isEmpty()) { 1882c4fbd756e2645147470c486ae96f2253f5e13a52Jack He mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) 1883c4fbd756e2645147470c486ae96f2253f5e13a52Jack He .setBrowsed(packageName, browseService); 1884e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 1885e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.w(TAG, "No Browser service available for " + packageName); 1886e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah status = false; 1887e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1888e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1889c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1890c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, 1891c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "startBrowseService for packageName: " + packageName + ", status = " + status); 1892c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1893e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return status; 1894e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1895e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1896511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private String getBrowseServiceName(String packageName) { 1897e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String browseServiceName = ""; 1898e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1899e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // getting the browse service name from browse player info 1900511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mBrowsePlayerInfoList) { 1901511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int browseInfoID = getBrowseId(packageName); 1902511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (browseInfoID != -1) { 1903511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen browseServiceName = mBrowsePlayerInfoList.get(browseInfoID).serviceClass; 1904511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1905e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1906e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1907c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1908c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "getBrowseServiceName for packageName: " + packageName 1909c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + ", browseServiceName = " + browseServiceName); 1910c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1911e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return browseServiceName; 1912e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1913e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1914754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker void buildBrowsablePlayerList() { 1915754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker synchronized (mBrowsePlayerInfoList) { 19163843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen mBrowsePlayerInfoList.clear(); 19173843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen Intent intent = new Intent(android.service.media.MediaBrowserService.SERVICE_INTERFACE); 1918754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker List<ResolveInfo> playerList = 1919754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker mPackageManager.queryIntentServices(intent, PackageManager.MATCH_ALL); 1920754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker 1921754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker for (ResolveInfo info : playerList) { 1922754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker String displayableName = info.loadLabel(mPackageManager).toString(); 1923754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker String serviceName = info.serviceInfo.name; 1924754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker String packageName = info.serviceInfo.packageName; 1925754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker 1926c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1927c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "Adding " + serviceName + " to list of browsable players"); 1928c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1929754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker BrowsePlayerInfo currentPlayer = 1930754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker new BrowsePlayerInfo(packageName, displayableName, serviceName); 1931754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker mBrowsePlayerInfoList.add(currentPlayer); 1932754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker MediaPlayerInfo playerInfo = getMediaPlayerInfo(packageName); 1933754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker MediaController controller = 1934754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker (playerInfo == null) ? null : playerInfo.getMediaController(); 1935754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker // Refresh the media player entry so it notices we can browse 1936754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker if (controller != null) { 1937754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker addMediaPlayerController(controller.getWrappedInstance()); 1938754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker } else { 1939754c469a24029e5b9a1c921fb91e3799937eb918Ajay Panicker addMediaPlayerPackage(packageName); 1940eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 19413843256f294cfd3e9b1d883e71ed7306738b6ca1Marie Janssen } 194285aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 1943e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1944e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1945e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 194605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /* Initializes list of media players identified from session manager active sessions */ 1947511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private void initMediaPlayersList() { 1948511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 1949511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen // Clearing old browsable player's list 1950511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mMediaPlayerInfoList.clear(); 195105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 1952511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (mMediaSessionManager == null) { 1953c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1954c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.w(TAG, "initMediaPlayersList: no media session manager!"); 1955c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1956511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return; 1957511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 195805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 1959511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen List<android.media.session.MediaController> controllers = 1960511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mMediaSessionManager.getActiveSessions(null); 1961c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 1962511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen Log.v(TAG, "initMediaPlayerInfoList: " + controllers.size() + " controllers"); 1963c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 1964511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen /* Initializing all media players */ 1965511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (android.media.session.MediaController controller : controllers) { 1966511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen addMediaPlayerController(controller); 1967511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1968f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen 196985aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 1970e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1971511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (mMediaPlayerInfoList.size() > 0) { 1972511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen // Set the first one as the Addressed Player 1973511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen updateCurrentController(mMediaPlayerInfoList.firstKey(), -1); 1974511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1975e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1976e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 1977e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 1978eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen private List<android.media.session.MediaController> getMediaControllers() { 1979eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen List<android.media.session.MediaController> controllers = 1980eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen new ArrayList<android.media.session.MediaController>(); 1981511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 1982511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (MediaPlayerInfo info : mMediaPlayerInfoList.values()) { 1983a1e42e29b15323e1a4d0559235a0987200663b2fMarie Janssen MediaController controller = info.getMediaController(); 1984a1e42e29b15323e1a4d0559235a0987200663b2fMarie Janssen if (controller != null) { 1985a1e42e29b15323e1a4d0559235a0987200663b2fMarie Janssen controllers.add(controller.getWrappedInstance()); 1986511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 1987eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 1988eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 1989eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return controllers; 1990eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 1991eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 1992eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen /** Add (or update) a player to the media player list without a controller */ 1993511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private boolean addMediaPlayerPackage(String packageName) { 1994eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen MediaPlayerInfo info = new MediaPlayerInfo(null, AvrcpConstants.PLAYER_TYPE_AUDIO, 199559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen AvrcpConstants.PLAYER_SUBTYPE_NONE, PLAYSTATUS_STOPPED, 1996b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen getFeatureBitMask(packageName), packageName, getAppLabel(packageName)); 199705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return addMediaPlayerInfo(info); 1998eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 1999eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2000eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen /** Add (or update) a player to the media player list given an active controller */ 2001511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private boolean addMediaPlayerController(android.media.session.MediaController controller) { 2002eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen String packageName = controller.getPackageName(); 2003de778443fdb539d38db92069661fdc18626a4c9cAjay Panicker MediaPlayerInfo info = new MediaPlayerInfo(MediaControllerFactory.wrap(controller), 2004eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen AvrcpConstants.PLAYER_TYPE_AUDIO, AvrcpConstants.PLAYER_SUBTYPE_NONE, 200559b1c77f883bd97816332046a3a98be4431cceddMarie Janssen getBluetoothPlayState(controller.getPlaybackState()), 200659b1c77f883bd97816332046a3a98be4431cceddMarie Janssen getFeatureBitMask(packageName), controller.getPackageName(), 200759b1c77f883bd97816332046a3a98be4431cceddMarie Janssen getAppLabel(packageName)); 200805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return addMediaPlayerInfo(info); 2009eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2010eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 201105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /** Add or update a player to the media player list given the MediaPlayerInfo object. 201205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen * @return true if an item was updated, false if it was added instead 201305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen */ 2014511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private boolean addMediaPlayerInfo(MediaPlayerInfo info) { 2015b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen int updateId = -1; 201605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen boolean updated = false; 2017f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen boolean currentRemoved = false; 20185e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker if (info.getPackageName().equals("com.android.server.telecom")) { 20195e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker Log.d(TAG, "Skip adding telecom to the media player info list"); 20205e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker return updated; 20215e5cfd5f5e651367111c5553230e066fc6817942Ajay Panicker } 2022511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2023511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 2024f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen MediaPlayerInfo current = entry.getValue(); 2025f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen int id = entry.getKey(); 2026f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen if (info.getPackageName().equals(current.getPackageName())) { 2027f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen if (!current.equalView(info)) { 2028f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen // If we would present a different player, make it a new player 2029f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen // so that controllers know whether a player is browsable or not. 2030f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen mMediaPlayerInfoList.remove(id); 2031f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen currentRemoved = (mCurrAddrPlayerID == id); 2032f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen break; 2033f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen } 2034f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen updateId = id; 2035511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen updated = true; 2036511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen break; 2037511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2038b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen } 2039511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (updateId == -1) { 2040511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen // New player 2041511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mLastUsedPlayerID++; 2042511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen updateId = mLastUsedPlayerID; 2043f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen mAvailablePlayerViewChanged = true; 2044511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2045511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mMediaPlayerInfoList.put(updateId, info); 2046fecc92279a01e377962b9b33b02d5db0ff3d1440Jack He } 2047c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2048c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, (updated ? "update #" : "add #") + updateId + ":" + info.toString()); 2049c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2050fecc92279a01e377962b9b33b02d5db0ff3d1440Jack He if (currentRemoved || updateId == mCurrAddrPlayerID) { 2051fecc92279a01e377962b9b33b02d5db0ff3d1440Jack He updateCurrentController(updateId, mCurrBrowsePlayerID); 2052b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen } 205305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return updated; 2054eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2055eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2056eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen /** Remove all players related to |packageName| from the media player info list */ 2057511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private MediaPlayerInfo removeMediaPlayerInfo(String packageName) { 2058511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2059511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int removeKey = -1; 2060511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 2061511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (entry.getValue().getPackageName().equals(packageName)) { 2062511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen removeKey = entry.getKey(); 2063511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen break; 2064511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2065511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2066511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (removeKey != -1) { 2067c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2068384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen Log.d(TAG, "remove #" + removeKey + ":" + mMediaPlayerInfoList.get(removeKey)); 2069c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2070f2f6a4ea02e9456f71ea0490112845110ca5d975Marie Janssen mAvailablePlayerViewChanged = true; 2071511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return mMediaPlayerInfoList.remove(removeKey); 2072eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2073b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen 2074511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return null; 2075511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2076eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2077eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2078384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen /** Remove the controller referenced by |controller| from any player in the list */ 2079f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen private void removeMediaController(@Nullable android.media.session.MediaController controller) { 2080c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (controller == null) { 2081c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return; 2082c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2083384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen synchronized (mMediaPlayerInfoList) { 2084f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 2085f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen MediaPlayerInfo info = entry.getValue(); 2086a1e42e29b15323e1a4d0559235a0987200663b2fMarie Janssen MediaController c = info.getMediaController(); 2087f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen if (c != null && c.equals(controller)) { 2088f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen info.setMediaController(null); 2089f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen if (entry.getKey() == mCurrAddrPlayerID) { 2090f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen updateCurrentController(mCurrAddrPlayerID, mCurrBrowsePlayerID); 2091f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen } 2092f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen } 2093384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } 2094384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } 2095384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } 2096384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen 2097e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* 2098e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * utility function to get the playback state of any media player through 2099e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * media controller APIs. 2100e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 210159b1c77f883bd97816332046a3a98be4431cceddMarie Janssen private byte getBluetoothPlayState(PlaybackState pbState) { 210259b1c77f883bd97816332046a3a98be4431cceddMarie Janssen if (pbState == null) { 210359b1c77f883bd97816332046a3a98be4431cceddMarie Janssen Log.w(TAG, "playState object null, sending STOPPED"); 210459b1c77f883bd97816332046a3a98be4431cceddMarie Janssen return PLAYSTATUS_STOPPED; 2105e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2106e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 210759b1c77f883bd97816332046a3a98be4431cceddMarie Janssen switch (pbState.getState()) { 2108e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_PLAYING: 2109e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_PLAYING; 2110e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2111cd1345961b7211ef6d130bd88b672835b52b3f60Ajay Panicker case PlaybackState.STATE_BUFFERING: 2112e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_STOPPED: 2113e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_NONE: 2114e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_CONNECTING: 2115e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_STOPPED; 2116e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2117e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_PAUSED: 2118e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_PAUSED; 2119e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2120e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_FAST_FORWARDING: 2121e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_SKIPPING_TO_NEXT: 2122e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM: 2123e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_FWD_SEEK; 2124e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2125e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_REWINDING: 2126e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_SKIPPING_TO_PREVIOUS: 2127e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_REV_SEEK; 2128e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2129e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah case PlaybackState.STATE_ERROR: 2130e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah default: 2131e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return PLAYSTATUS_ERROR; 2132e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2133e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2134e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2135e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* 2136e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * utility function to get the feature bit mask of any media player through 2137e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * package name 2138e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 2139e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private short[] getFeatureBitMask(String packageName) { 2140e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2141e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ArrayList<Short> featureBitsList = new ArrayList<Short>(); 2142e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2143e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* adding default feature bits */ 2144e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_PLAY_BIT_NO); 2145e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_STOP_BIT_NO); 2146e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_PAUSE_BIT_NO); 2147e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_REWIND_BIT_NO); 2148e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_FAST_FWD_BIT_NO); 2149e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_FORWARD_BIT_NO); 2150e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_BACKWARD_BIT_NO); 2151e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_ADV_CTRL_BIT_NO); 2152e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2153e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Add/Modify browse player supported features. */ 2154e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (isBrowseSupported(packageName)) { 2155e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_BROWSE_BIT_NO); 2156e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_UID_UNIQUE_BIT_NO); 2157e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_NOW_PLAY_BIT_NO); 2158e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsList.add(AvrcpConstants.AVRC_PF_GET_NUM_OF_ITEMS_BIT_NO); 2159e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2160e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2161e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // converting arraylist to array for response 2162e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah short[] featureBitsArray = new short[featureBitsList.size()]; 2163e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2164e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah for (int i = 0; i < featureBitsList.size(); i++) { 2165e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah featureBitsArray[i] = featureBitsList.get(i).shortValue(); 2166e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2167e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2168e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return featureBitsArray; 2169e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2170e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2171e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /** 2172e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * Checks the Package name if it supports Browsing or not. 2173e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * 2174e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * @param packageName - name of the package to get the Id. 2175e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * @return true if it supports browsing, else false. 2176e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 2177511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private boolean isBrowseSupported(String packageName) { 2178511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mBrowsePlayerInfoList) { 2179511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen /* check if Browsable Player's list contains this package name */ 2180511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (BrowsePlayerInfo info : mBrowsePlayerInfoList) { 2181511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (info.packageName.equals(packageName)) { 2182c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2183c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "isBrowseSupported for " + packageName + ": true"); 2184c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2185511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return true; 2186511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2187e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2188e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2189e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2190c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2191c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "isBrowseSupported for " + packageName + ": false"); 2192c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 21931b70ec148be773651d5ad00e3ce0d28b3a63306dAjay Panicker return false; 2194e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2195e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2196e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private String getPackageName(int id) { 2197511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen MediaPlayerInfo player = null; 2198511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2199511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen player = mMediaPlayerInfoList.getOrDefault(id, null); 2200511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2201e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2202eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen if (player == null) { 2203eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen Log.w(TAG, "No package name for player (" + id + " not valid)"); 2204eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return ""; 2205e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2206eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2207eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen String packageName = player.getPackageName(); 2208c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2209c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "Player " + id + " package: " + packageName); 2210c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2211e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return packageName; 2212e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2213e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2214e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* from the global object, getting the current browsed player's package name */ 2215e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private String getCurrentBrowsedPlayer(byte[] bdaddr) { 2216e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String browsedPlayerPackage = ""; 2217e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2218e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Map<String, BrowsedMediaPlayer> connList = mAvrcpBrowseManager.getConnList(); 2219e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String bdaddrStr = new String(bdaddr); 2220c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (connList.containsKey(bdaddrStr)) { 2221e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah browsedPlayerPackage = connList.get(bdaddrStr).getPackageName(); 2222e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2223c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2224c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "getCurrentBrowsedPlayerPackage: " + browsedPlayerPackage); 2225c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2226e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return browsedPlayerPackage; 2227e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2228e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2229eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen /* Returns the MediaPlayerInfo for the currently addressed media player */ 2230511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private MediaPlayerInfo getAddressedPlayerInfo() { 2231511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2232511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return mMediaPlayerInfoList.getOrDefault(mCurrAddrPlayerID, null); 2233511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2234e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2235e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2236e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* 2237e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * Utility function to get the Media player info from package name returns 2238e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * null if package name not found in media players list 2239e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 2240511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private MediaPlayerInfo getMediaPlayerInfo(String packageName) { 2241511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2242511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (mMediaPlayerInfoList.isEmpty()) { 2243c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2244c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "getMediaPlayerInfo: Media players list empty"); 2245c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2246511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return null; 2247511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2248eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2249511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (MediaPlayerInfo info : mMediaPlayerInfoList.values()) { 2250511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (packageName.equals(info.getPackageName())) { 2251c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2252c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, "getMediaPlayerInfo: Found " + packageName); 2253c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2254511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return info; 2255511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2256e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2257c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2258c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.w(TAG, "getMediaPlayerInfo: " + packageName + " not found"); 2259c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2260511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return null; 2261e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2262e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2263e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2264e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* prepare media list & return the media player list response object */ 2265511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private MediaPlayerListRsp prepareMediaPlayerRspObj() { 2266511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 226742b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker // TODO(apanicke): This hack will go away as soon as a developer 226842b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker // option to enable or disable player selection is created. Right 226942b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker // now this is needed to fix BMW i3 carkits and any other carkits 227042b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker // that might try to connect to a player that isnt the current 227142b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker // player based on this list 227242b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker int numPlayers = 1; 2273511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen 2274511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int[] playerIds = new int[numPlayers]; 2275511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen byte[] playerTypes = new byte[numPlayers]; 2276511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int[] playerSubTypes = new int[numPlayers]; 2277511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen String[] displayableNameArray = new String[numPlayers]; 2278511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen byte[] playStatusValues = new byte[numPlayers]; 2279511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen short[] featureBitMaskValues = 2280511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen new short[numPlayers * AvrcpConstants.AVRC_FEATURE_MASK_SIZE]; 2281511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen 22827a44bb23aadc107c369d230fb96f4ce3374f3f5bAjay Panicker // Reserve the first spot for the currently addressed player if 22837a44bb23aadc107c369d230fb96f4ce3374f3f5bAjay Panicker // we have one 22847a44bb23aadc107c369d230fb96f4ce3374f3f5bAjay Panicker int players = mMediaPlayerInfoList.containsKey(mCurrAddrPlayerID) ? 1 : 0; 2285511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 22862a9aba641d081621a373b56171938994447040e3Ajay Panicker int idx = players; 2287c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (entry.getKey() == mCurrAddrPlayerID) { 228842b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker idx = 0; 2289c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 229042b19bc308e155b52e735e38efca42d5c7c6a699Ajay Panicker continue; // TODO(apanicke): Remove, see above note 2291c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2292511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen MediaPlayerInfo info = entry.getValue(); 22932a9aba641d081621a373b56171938994447040e3Ajay Panicker playerIds[idx] = entry.getKey(); 22942a9aba641d081621a373b56171938994447040e3Ajay Panicker playerTypes[idx] = info.getMajorType(); 22952a9aba641d081621a373b56171938994447040e3Ajay Panicker playerSubTypes[idx] = info.getSubType(); 22962a9aba641d081621a373b56171938994447040e3Ajay Panicker displayableNameArray[idx] = info.getDisplayableName(); 22972a9aba641d081621a373b56171938994447040e3Ajay Panicker playStatusValues[idx] = info.getPlayStatus(); 2298511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen 2299511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen short[] featureBits = info.getFeatureBitMask(); 2300511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (int numBit = 0; numBit < featureBits.length; numBit++) { 2301511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen /* gives which octet this belongs to */ 2302511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen byte octet = (byte) (featureBits[numBit] / 8); 2303511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen /* gives the bit position within the octet */ 2304511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen byte bit = (byte) (featureBits[numBit] % 8); 23052a9aba641d081621a373b56171938994447040e3Ajay Panicker featureBitMaskValues[(idx * AvrcpConstants.AVRC_FEATURE_MASK_SIZE) + octet] |= 23062a9aba641d081621a373b56171938994447040e3Ajay Panicker (1 << bit); 2307511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2308e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2309511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen /* printLogs */ 2310511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (DEBUG) { 23112a9aba641d081621a373b56171938994447040e3Ajay Panicker Log.d(TAG, "Player " + playerIds[idx] + ": " + displayableNameArray[idx] 2312c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " type: " + playerTypes[idx] + ", " + playerSubTypes[idx] 2313c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " status: " + playStatusValues[idx]); 2314511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2315e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2316c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (idx != 0) { 2317c4fbd756e2645147470c486ae96f2253f5e13a52Jack He players++; 2318c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2319511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2320e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2321c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2322c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "prepareMediaPlayerRspObj: numPlayers = " + numPlayers); 2323c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2324e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2325511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return new MediaPlayerListRsp(AvrcpConstants.RSP_NO_ERROR, sUIDCounter, numPlayers, 2326511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen AvrcpConstants.BTRC_ITEM_PLAYER, playerIds, playerTypes, playerSubTypes, 2327511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen playStatusValues, featureBitMaskValues, displayableNameArray); 2328511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2329e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2330e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2331c4fbd756e2645147470c486ae96f2253f5e13a52Jack He /* build media player list and send it to remote. */ 2332e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handleMediaPlayerListRsp(AvrcpCmd.FolderItemsCmd folderObj) { 2333511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen MediaPlayerListRsp rspObj = null; 2334511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2335511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int numPlayers = mMediaPlayerInfoList.size(); 2336511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (numPlayers == 0) { 2337511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_NO_AVBL_PLAY, 2338511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen (short) 0, (byte) 0, 0, null, null, null, null, null, null); 2339511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return; 2340511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2341511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen if (folderObj.mStartItem >= numPlayers) { 2342511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen Log.i(TAG, "handleMediaPlayerListRsp: start = " + folderObj.mStartItem 2343c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + " > num of items = " + numPlayers); 2344511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen mediaPlayerListRspNative(folderObj.mAddress, AvrcpConstants.RSP_INV_RANGE, 2345511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen (short) 0, (byte) 0, 0, null, null, null, null, null, null); 2346511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen return; 2347511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2348511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen rspObj = prepareMediaPlayerRspObj(); 2349e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2350c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2351c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "handleMediaPlayerListRsp: sending " + rspObj.mNumItems + " players"); 2352c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2353eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen mediaPlayerListRspNative(folderObj.mAddress, rspObj.mStatus, rspObj.mUIDCounter, 23548bc413b0b749ea9df59e858493273e05087fe887Jack He rspObj.mItemType, rspObj.mNumItems, rspObj.mPlayerIds, rspObj.mPlayerTypes, 2355eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen rspObj.mPlayerSubTypes, rspObj.mPlayStatusValues, rspObj.mFeatureBitMaskValues, 2356eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen rspObj.mPlayerNameList); 2357e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2358e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2359e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* unregister to the old controller, update new IDs and register to the new controller */ 2360e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean updateCurrentController(int addrId, int browseId) { 2361e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah boolean registerRsp = true; 2362e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2363e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah updateNewIds(addrId, browseId); 2364e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2365eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen MediaController newController = null; 2366eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen MediaPlayerInfo info = getAddressedPlayerInfo(); 2367c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (info != null) { 2368c4fbd756e2645147470c486ae96f2253f5e13a52Jack He newController = info.getMediaController(); 2369c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2370eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen 2371c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2372eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen Log.d(TAG, "updateCurrentController: " + mMediaController + " to " + newController); 2373c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2374ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen synchronized (this) { 2375ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen if (mMediaController == null || (!mMediaController.equals(newController))) { 2376f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen if (mMediaController != null) { 2377f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen mMediaController.unregisterCallback(mMediaControllerCb); 2378f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen } 2379f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen mMediaController = newController; 2380f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen if (mMediaController != null) { 2381f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen mMediaController.registerCallback(mMediaControllerCb, mHandler); 2382f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen } else { 2383f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen registerRsp = false; 2384f6521ba818df22d8a853d25f7c6adc1e724875e6Marie Janssen } 2385eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2386e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 238785aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker updateCurrentMediaState(); 2388eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return registerRsp; 2389e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2390e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2391e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Handle getfolderitems for scope = VFS, Search, NowPlayingList */ 2392c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private void handleGetFolderItemBrowseResponse(AvrcpCmd.FolderItemsCmd folderObj, 2393c4fbd756e2645147470c486ae96f2253f5e13a52Jack He byte[] bdaddr) { 2394e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int status = AvrcpConstants.RSP_NO_ERROR; 2395e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2396e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Browsed player is already set */ 239705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (folderObj.mScope == AvrcpConstants.BTRC_SCOPE_FILE_SYSTEM) { 239805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) == null) { 239905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.e(TAG, "handleGetFolderItemBrowseResponse: no browsed player set for " 2400c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + Utils.getAddressStringFromByte(bdaddr)); 240105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen getFolderItemsRspNative(bdaddr, AvrcpConstants.RSP_INTERNAL_ERR, (short) 0, 240205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen (byte) 0x00, 0, null, null, null, null, null, null, null, null); 240305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return; 240405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 240505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr).getFolderItemsVFS(folderObj); 240605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return; 2407e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 240805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (folderObj.mScope == AvrcpConstants.BTRC_SCOPE_NOW_PLAYING) { 240905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mAddressedMediaPlayer.getFolderItemsNowPlaying(bdaddr, folderObj, mMediaController); 241005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return; 2411e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2412e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 241305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /* invalid scope */ 241405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.e(TAG, "handleGetFolderItemBrowseResponse: unknown scope " + folderObj.mScope); 241505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen getFolderItemsRspNative(bdaddr, AvrcpConstants.RSP_INV_SCOPE, (short) 0, (byte) 0x00, 0, 241605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen null, null, null, null, null, null, null, null); 2417e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2418e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2419e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* utility function to update the global values of current Addressed and browsed player */ 2420511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen private void updateNewIds(int addrId, int browseId) { 2421c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2422c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.v(TAG, 2423c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "updateNewIds: Addressed:" + mCurrAddrPlayerID + " to " + addrId + ", Browse:" 2424c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + mCurrBrowsePlayerID + " to " + browseId); 2425c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2426e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mCurrAddrPlayerID = addrId; 2427e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mCurrBrowsePlayerID = browseId; 2428e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2429e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2430e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Getting the application's displayable name from package name */ 2431e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private String getAppLabel(String packageName) { 2432e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ApplicationInfo appInfo = null; 2433e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah try { 2434e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah appInfo = mPackageManager.getApplicationInfo(packageName, 0); 2435e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } catch (NameNotFoundException e) { 2436e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah e.printStackTrace(); 2437e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2438e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2439c4fbd756e2645147470c486ae96f2253f5e13a52Jack He return (String) (appInfo != null ? mPackageManager.getApplicationLabel(appInfo) 2440c4fbd756e2645147470c486ae96f2253f5e13a52Jack He : "Unknown"); 2441e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2442e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2443e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handlePlayItemResponse(byte[] bdaddr, byte[] uid, byte scope) { 2444294ff299ca4837fd7f56861941b274fadee97ec4Marie Janssen if (scope == AvrcpConstants.BTRC_SCOPE_NOW_PLAYING) { 2445294ff299ca4837fd7f56861941b274fadee97ec4Marie Janssen mAddressedMediaPlayer.playItem(bdaddr, uid, mMediaController); 2446c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } else { 2447c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!isAddrPlayerSameAsBrowsed(bdaddr)) { 2448c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.w(TAG, "Remote requesting play item on uid which may not be recognized by" 2449c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + "current addressed player"); 2450e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah playItemRspNative(bdaddr, AvrcpConstants.RSP_INV_ITEM); 2451e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2452e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2453e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) != null) { 2454e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr).playItem(uid, scope); 2455e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2456c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.e(TAG, "handlePlayItemResponse: Remote requested playitem " 2457c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + "before setbrowsedplayer"); 2458e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah playItemRspNative(bdaddr, AvrcpConstants.RSP_INTERNAL_ERR); 2459e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2460e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2461e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2462e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2463e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handleGetItemAttr(AvrcpCmd.ItemAttrCmd itemAttr) { 246445551315d39fd0bc1c5a118b4728c728ce42b412koh.changseok if (itemAttr.mUidCounter != sUIDCounter) { 246545551315d39fd0bc1c5a118b4728c728ce42b412koh.changseok Log.e(TAG, "handleGetItemAttr: invaild uid counter."); 2466c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getItemAttrRspNative(itemAttr.mAddress, AvrcpConstants.RSP_UID_CHANGED, (byte) 0, null, 2467c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null); 246845551315d39fd0bc1c5a118b4728c728ce42b412koh.changseok return; 246945551315d39fd0bc1c5a118b4728c728ce42b412koh.changseok } 2470384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen if (itemAttr.mScope == AvrcpConstants.BTRC_SCOPE_NOW_PLAYING) { 2471384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen if (mCurrAddrPlayerID == NO_PLAYER_ID) { 2472c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getItemAttrRspNative(itemAttr.mAddress, AvrcpConstants.RSP_NO_AVBL_PLAY, (byte) 0, 2473c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null, null); 2474c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen return; 2475384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } 2476c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen mAddressedMediaPlayer.getItemAttr(itemAttr.mAddress, itemAttr, mMediaController); 2477c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen return; 2478c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen } 2479c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen // All other scopes use browsed player 2480c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen if (mAvrcpBrowseManager.getBrowsedMediaPlayer(itemAttr.mAddress) != null) { 2481c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen mAvrcpBrowseManager.getBrowsedMediaPlayer(itemAttr.mAddress).getItemAttr(itemAttr); 2482384011244f5a62ed34f198b8ba91341b4efb4fb6Marie Janssen } else { 2483c1267074b7df0d6e42cefea0ac40b584fdb1430fMarie Janssen Log.e(TAG, "Could not get attributes. mBrowsedMediaPlayer is null"); 2484c4fbd756e2645147470c486ae96f2253f5e13a52Jack He getItemAttrRspNative(itemAttr.mAddress, AvrcpConstants.RSP_INTERNAL_ERR, (byte) 0, null, 2485c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null); 2486e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2487e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2488e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2489e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private void handleGetTotalNumOfItemsResponse(byte[] bdaddr, byte scope) { 2490e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // for scope as media player list 2491e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (scope == AvrcpConstants.BTRC_SCOPE_PLAYER_LIST) { 2492511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int numPlayers = 0; 2493511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2494511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen numPlayers = mMediaPlayerInfoList.size(); 2495511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 2496c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2497c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "handleGetTotalNumOfItemsResponse: " + numPlayers + " players."); 2498c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2499511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen getTotalNumOfItemsRspNative(bdaddr, AvrcpConstants.RSP_NO_ERROR, 0, numPlayers); 2500511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } else if (scope == AvrcpConstants.BTRC_SCOPE_NOW_PLAYING) { 2501294ff299ca4837fd7f56861941b274fadee97ec4Marie Janssen mAddressedMediaPlayer.getTotalNumOfItems(bdaddr, mMediaController); 2502e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2503e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // for FileSystem browsing scopes as VFS, Now Playing 2504e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr) != null) { 2505e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mAvrcpBrowseManager.getBrowsedMediaPlayer(bdaddr).getTotalNumOfItems(scope); 2506e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2507e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "Could not get Total NumOfItems. mBrowsedMediaPlayer is null"); 2508e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah getTotalNumOfItemsRspNative(bdaddr, AvrcpConstants.RSP_INTERNAL_ERR, 0, 0); 2509e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2510e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2511e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2512e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2513e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2514e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* check if browsed player and addressed player are same */ 2515e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean isAddrPlayerSameAsBrowsed(byte[] bdaddr) { 2516e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String browsedPlayer = getCurrentBrowsedPlayer(bdaddr); 2517e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2518e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!isPackageNameValid(browsedPlayer)) { 2519e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.w(TAG, "Browsed player name empty"); 2520eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return false; 2521e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2522e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2523b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen MediaPlayerInfo info = getAddressedPlayerInfo(); 2524db2d487ba559f0e4de02bc2ad4cc7e275878b2fcMarie Janssen String packageName = (info == null) ? "<none>" : info.getPackageName(); 2525db2d487ba559f0e4de02bc2ad4cc7e275878b2fcMarie Janssen if (info == null || !packageName.equals(browsedPlayer)) { 2526c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2527c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, browsedPlayer + " is not addressed player " + packageName); 2528c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2529eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return false; 2530eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen } 2531eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen return true; 2532e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2533e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2534e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* checks if package name is not null or empty */ 2535e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean isPackageNameValid(String browsedPackage) { 2536e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah boolean isValid = (browsedPackage != null && browsedPackage.length() > 0); 2537c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2538c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "isPackageNameValid: browsedPackage = " + browsedPackage + "isValid = " 2539c4fbd756e2645147470c486ae96f2253f5e13a52Jack He + isValid); 2540c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2541e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return isValid; 2542e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2543e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2544e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* checks if selected addressed player is already addressed */ 2545e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private boolean isPlayerAlreadyAddressed(int selectedId) { 2546e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // checking if selected ID is same as the current addressed player id 2547e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah boolean isAddressed = (mCurrAddrPlayerID == selectedId); 2548c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2549c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "isPlayerAlreadyAddressed: isAddressed = " + isAddressed); 2550c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2551e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return isAddressed; 2552e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2553e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2554e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void dump(StringBuilder sb) { 2555e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah sb.append("AVRCP:\n"); 2556cc07ee436d00418ecc69ae3aace986f7fbf0823aMarie Janssen ProfileService.println(sb, "mMediaAttributes: " + mMediaAttributes.toRedactedString()); 2557e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mTransportControlFlags: " + mTransportControlFlags); 2558e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mCurrentPlayState: " + mCurrentPlayState); 2559e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mPlayStatusChangedNT: " + mPlayStatusChangedNT); 2560e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mTrackChangedNT: " + mTrackChangedNT); 2561e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mPlaybackIntervalMs: " + mPlaybackIntervalMs); 2562e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mPlayPosChangedNT: " + mPlayPosChangedNT); 2563e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mNextPosMs: " + mNextPosMs); 2564e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mPrevPosMs: " + mPrevPosMs); 2565e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mFeatures: " + mFeatures); 2566e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mRemoteVolume: " + mRemoteVolume); 2567e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mLastRemoteVolume: " + mLastRemoteVolume); 2568e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mLastDirection: " + mLastDirection); 2569e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mVolumeStep: " + mVolumeStep); 2570e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mAudioStreamMax: " + mAudioStreamMax); 2571e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mVolCmdSetInProgress: " + mVolCmdSetInProgress); 2572e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mAbsVolRetryTimes: " + mAbsVolRetryTimes); 2573e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah ProfileService.println(sb, "mVolumeMapping: " + mVolumeMapping.toString()); 2574ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen synchronized (this) { 2575c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mMediaController != null) { 2576c4fbd756e2645147470c486ae96f2253f5e13a52Jack He ProfileService.println(sb, 2577c4fbd756e2645147470c486ae96f2253f5e13a52Jack He "mMediaController: " + mMediaController.getWrappedInstance() + " pkg " 2578ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen + mMediaController.getPackageName()); 2579c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2580ad7a50ece55752b9b7e47cd86dc45de368c8c6d5Marie Janssen } 258178d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, ""); 258278d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, "Media Players:"); 2583511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen synchronized (mMediaPlayerInfoList) { 2584511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen for (Map.Entry<Integer, MediaPlayerInfo> entry : mMediaPlayerInfoList.entrySet()) { 2585511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen int key = entry.getKey(); 2586c4fbd756e2645147470c486ae96f2253f5e13a52Jack He ProfileService.println(sb, 2587c4fbd756e2645147470c486ae96f2253f5e13a52Jack He ((mCurrAddrPlayerID == key) ? " *#" : " #") + entry.getKey() + ": " + entry 2588c4fbd756e2645147470c486ae96f2253f5e13a52Jack He .getValue()); 2589511ebf9e8dfa9f39315de93ad9a5dcf72556676eMarie Janssen } 259005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 259105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 2592e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen ProfileService.println(sb, ""); 2593e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen mAddressedMediaPlayer.dump(sb, mMediaController); 2594e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen 2595e5384f02ec837a8f274ed59548cb6879849239f5Marie Janssen ProfileService.println(sb, ""); 259678d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, mPassthroughDispatched + " passthrough operations: "); 2597c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (mPassthroughDispatched > mPassthroughLogs.size()) { 259878d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, " (last " + mPassthroughLogs.size() + ")"); 2599c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 260078d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen synchronized (mPassthroughLogs) { 260178d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen for (MediaKeyLog log : mPassthroughLogs) { 260278d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, " " + log); 260378d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen } 260405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 260578d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen synchronized (mPassthroughPending) { 260678d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen for (MediaKeyLog log : mPassthroughPending) { 260778d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen ProfileService.println(sb, " " + log); 260878d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen } 2609b8faaf4863cfae62c32af644765a9190512925c9Marie Janssen } 2610aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov 2611aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov // Print the blacklisted devices (for absolute volume control) 2612aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov SharedPreferences pref = 2613aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov mContext.getSharedPreferences(ABSOLUTE_VOLUME_BLACKLIST, Context.MODE_PRIVATE); 2614aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov Map<String, ?> allKeys = pref.getAll(); 2615aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov ProfileService.println(sb, ""); 2616aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov ProfileService.println(sb, "Runtime Blacklisted Devices (absolute volume):"); 2617aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov if (allKeys.isEmpty()) { 2618aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov ProfileService.println(sb, " None"); 2619aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov } else { 2620fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov for (Map.Entry<String, ?> entry : allKeys.entrySet()) { 2621fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov String key = entry.getKey(); 2622fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov Object value = entry.getValue(); 2623fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov if (value instanceof String) { 2624fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov ProfileService.println(sb, " " + key + " " + value); 2625fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov } else { 2626fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov ProfileService.println(sb, " " + key + " Reason: Unknown"); 2627fb7244393f6f3c14045d726e3c958403a7392519Pavlin Radoslavov } 2628aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov } 2629aad52567f7c3d4b88868f4dab95c148675c91816Pavlin Radoslavov } 2630e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2631e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2632e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public class AvrcpBrowseManager { 26338bc413b0b749ea9df59e858493273e05087fe887Jack He public Map<String, BrowsedMediaPlayer> connList = new HashMap<String, BrowsedMediaPlayer>(); 2634e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private AvrcpMediaRspInterface mMediaInterface; 2635e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private Context mContext; 2636e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2637e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public AvrcpBrowseManager(Context context, AvrcpMediaRspInterface mediaInterface) { 2638e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mContext = context; 2639e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mMediaInterface = mediaInterface; 2640e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2641e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2642e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void cleanup() { 2643e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Iterator entries = connList.entrySet().iterator(); 2644e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah while (entries.hasNext()) { 2645e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Map.Entry entry = (Map.Entry) entries.next(); 2646e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah BrowsedMediaPlayer browsedMediaPlayer = (BrowsedMediaPlayer) entry.getValue(); 2647e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (browsedMediaPlayer != null) { 2648e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah browsedMediaPlayer.cleanup(); 2649e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2650e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2651e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // clean up the map 2652e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah connList.clear(); 2653e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2654e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2655e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // get the a free media player interface based on the passed bd address 2656e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // if the no items is found for the passed media player then it assignes a 2657e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // available media player interface 2658e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public BrowsedMediaPlayer getBrowsedMediaPlayer(byte[] bdaddr) { 2659e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah BrowsedMediaPlayer mediaPlayer; 2660e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String bdaddrStr = new String(bdaddr); 266105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (connList.containsKey(bdaddrStr)) { 2662e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mediaPlayer = connList.get(bdaddrStr); 2663e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2664e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah mediaPlayer = new BrowsedMediaPlayer(bdaddr, mContext, mMediaInterface); 2665e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah connList.put(bdaddrStr, mediaPlayer); 2666e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2667e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return mediaPlayer; 2668e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2669e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2670e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // clears the details pertaining to passed bdaddres 2671e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public boolean clearBrowsedMediaPlayer(byte[] bdaddr) { 2672e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String bdaddrStr = new String(bdaddr); 267305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (connList.containsKey(bdaddrStr)) { 2674e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah connList.remove(bdaddrStr); 2675e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return true; 2676e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2677e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return false; 2678e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2679e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2680e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public Map<String, BrowsedMediaPlayer> getConnList() { 2681e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return connList; 2682e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2683e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2684e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* Helper function to convert colon separated bdaddr to byte string */ 2685e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private byte[] hexStringToByteArray(String s) { 2686e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int len = s.length(); 2687e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah byte[] data = new byte[len / 2]; 2688e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah for (int i = 0; i < len; i += 2) { 2689c4fbd756e2645147470c486ae96f2253f5e13a52Jack He data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit( 2690c4fbd756e2645147470c486ae96f2253f5e13a52Jack He s.charAt(i + 1), 16)); 2691e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2692e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return data; 2693e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2694e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2695e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2696e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* 2697e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * private class which handles responses from AvrcpMediaManager. Maps responses to native 2698e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah * responses. This class implements the AvrcpMediaRspInterface interface. 2699e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah */ 2700e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private class AvrcpMediaRsp implements AvrcpMediaRspInterface { 2701e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private static final String TAG = "AvrcpMediaRsp"; 2702e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27032fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2704e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void setAddrPlayerRsp(byte[] address, int rspStatus) { 2705e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!setAddressedPlayerRspNative(address, rspStatus)) { 2706e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "setAddrPlayerRsp failed!"); 2707e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2708e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2709e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27102fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2711e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void setBrowsedPlayerRsp(byte[] address, int rspStatus, byte depth, int numItems, 2712e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String[] textArray) { 2713e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!setBrowsedPlayerRspNative(address, rspStatus, depth, numItems, textArray)) { 2714e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "setBrowsedPlayerRsp failed!"); 2715e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2716e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2717e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27182fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2719e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void mediaPlayerListRsp(byte[] address, int rspStatus, MediaPlayerListRsp rspObj) { 2720e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (rspObj != null && rspStatus == AvrcpConstants.RSP_NO_ERROR) { 27218bc413b0b749ea9df59e858493273e05087fe887Jack He if (!mediaPlayerListRspNative(address, rspStatus, sUIDCounter, rspObj.mItemType, 2722c4fbd756e2645147470c486ae96f2253f5e13a52Jack He rspObj.mNumItems, rspObj.mPlayerIds, rspObj.mPlayerTypes, 2723c4fbd756e2645147470c486ae96f2253f5e13a52Jack He rspObj.mPlayerSubTypes, rspObj.mPlayStatusValues, 2724c4fbd756e2645147470c486ae96f2253f5e13a52Jack He rspObj.mFeatureBitMaskValues, rspObj.mPlayerNameList)) { 2725eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen Log.e(TAG, "mediaPlayerListRsp failed!"); 2726c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2727e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2728e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "mediaPlayerListRsp: rspObj is null"); 2729eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen if (!mediaPlayerListRspNative(address, rspStatus, sUIDCounter, (byte) 0x00, 0, null, 2730c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null, null, null, null, null)) { 2731eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen Log.e(TAG, "mediaPlayerListRsp failed!"); 2732c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2733e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2734e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2735e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27362fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2737e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void folderItemsRsp(byte[] address, int rspStatus, FolderItemsRsp rspObj) { 2738e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (rspObj != null && rspStatus == AvrcpConstants.RSP_NO_ERROR) { 2739e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!getFolderItemsRspNative(address, rspStatus, sUIDCounter, rspObj.mScope, 2740e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah rspObj.mNumItems, rspObj.mFolderTypes, rspObj.mPlayable, rspObj.mItemTypes, 2741e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah rspObj.mItemUid, rspObj.mDisplayNames, rspObj.mAttributesNum, 2742c4fbd756e2645147470c486ae96f2253f5e13a52Jack He rspObj.mAttrIds, rspObj.mAttrValues)) { 2743e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getFolderItemsRspNative failed!"); 2744c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2745e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2746e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "folderItemsRsp: rspObj is null or rspStatus is error:" + rspStatus); 2747c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!getFolderItemsRspNative(address, rspStatus, sUIDCounter, (byte) 0x00, 0, null, 2748c4fbd756e2645147470c486ae96f2253f5e13a52Jack He null, null, null, null, null, null, null)) { 2749e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getFolderItemsRspNative failed!"); 2750c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2751e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2752e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2753e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2754e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27552fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2756e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void changePathRsp(byte[] address, int rspStatus, int numItems) { 2757c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!changePathRspNative(address, rspStatus, numItems)) { 2758e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "changePathRspNative failed!"); 2759c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2760e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2761e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27622fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2763e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void getItemAttrRsp(byte[] address, int rspStatus, ItemAttrRsp rspObj) { 2764e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (rspObj != null && rspStatus == AvrcpConstants.RSP_NO_ERROR) { 2765e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!getItemAttrRspNative(address, rspStatus, rspObj.mNumAttr, 2766c4fbd756e2645147470c486ae96f2253f5e13a52Jack He rspObj.mAttributesIds, rspObj.mAttributesArray)) { 2767e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getItemAttrRspNative failed!"); 2768c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2769e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } else { 2770e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getItemAttrRsp: rspObj is null or rspStatus is error:" + rspStatus); 2771c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (!getItemAttrRspNative(address, rspStatus, (byte) 0x00, null, null)) { 2772e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getItemAttrRspNative failed!"); 2773c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 2774e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2775e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2776e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27772fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2778e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void playItemRsp(byte[] address, int rspStatus) { 2779e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!playItemRspNative(address, rspStatus)) { 2780e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "playItemRspNative failed!"); 2781e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2782e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2783e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27842fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2785e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void getTotalNumOfItemsRsp(byte[] address, int rspStatus, int uidCounter, 2786e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int numItems) { 2787e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!getTotalNumOfItemsRspNative(address, rspStatus, sUIDCounter, numItems)) { 2788e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "getTotalNumOfItemsRspNative failed!"); 2789e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2790e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2791e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27922fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 279305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void addrPlayerChangedRsp(int type, int playerId, int uidCounter) { 2794e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspAddrPlayerChangedNative(type, playerId, sUIDCounter)) { 2795e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "registerNotificationRspAddrPlayerChangedNative failed!"); 2796e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2797e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2798e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 27992fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2800e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void avalPlayerChangedRsp(byte[] address, int type) { 2801e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspAvalPlayerChangedNative(type)) { 2802e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "registerNotificationRspAvalPlayerChangedNative failed!"); 2803e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2804e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2805e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 28062fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2807c960943641d79069f2f8177c0a3c378d8337b9c2Ajay Panicker public void uidsChangedRsp(int type) { 2808e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspUIDsChangedNative(type, sUIDCounter)) { 2809e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "registerNotificationRspUIDsChangedNative failed!"); 2810e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2811e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2812e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 28132fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2814e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void nowPlayingChangedRsp(int type) { 281505723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker if (mNowPlayingListChangedNT != AvrcpConstants.NOTIFICATION_TYPE_INTERIM) { 2816c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (DEBUG) { 2817c4fbd756e2645147470c486ae96f2253f5e13a52Jack He Log.d(TAG, "NowPlayingListChanged: Not registered or requesting."); 2818c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 281905723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker return; 282005723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker } 282105723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker 2822e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspNowPlayingChangedNative(type)) { 2823e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "registerNotificationRspNowPlayingChangedNative failed!"); 2824e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 282505723ee9e6619814876a6cce5004d11b38c3f648Ajay Panicker mNowPlayingListChangedNT = AvrcpConstants.NOTIFICATION_TYPE_CHANGED; 2826e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2827e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 28282fbb1d97d08d5d72fe824e543c714e56cd7be236Jack He @Override 2829e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public void trackChangedRsp(int type, byte[] uid) { 2830e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah if (!registerNotificationRspTrackChangeNative(type, uid)) { 2831e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah Log.e(TAG, "registerNotificationRspTrackChangeNative failed!"); 2832e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2833e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2834e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2835e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 2836e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah /* getters for some private variables */ 2837e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah public AvrcpBrowseManager getAvrcpBrowseManager() { 2838e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah return mAvrcpBrowseManager; 2839e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah } 2840e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 284105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen /* PASSTHROUGH COMMAND MANAGEMENT */ 284205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 284305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen void handlePassthroughCmd(int op, int state) { 284405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen int code = avrcpPassthroughToKeyCode(op); 284505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (code == KeyEvent.KEYCODE_UNKNOWN) { 284605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.w(TAG, "Ignoring passthrough of unknown key " + op + " state " + state); 284705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return; 284805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 284905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen int action = KeyEvent.ACTION_DOWN; 2850c4fbd756e2645147470c486ae96f2253f5e13a52Jack He if (state == AvrcpConstants.KEY_STATE_RELEASE) { 2851c4fbd756e2645147470c486ae96f2253f5e13a52Jack He action = KeyEvent.ACTION_UP; 2852c4fbd756e2645147470c486ae96f2253f5e13a52Jack He } 285305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen KeyEvent event = new KeyEvent(action, code); 285405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (!KeyEvent.isMediaKey(code)) { 285505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.w(TAG, "Passthrough non-media key " + op + " (code " + code + ") state " + state); 285605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 285785aee8a39e8ca855b1b42724bca710aa1bfa6a7fAjay Panicker 285805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mMediaSessionManager.dispatchMediaKeyEvent(event); 285905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen addKeyPending(event); 286005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 286105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 286205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private int avrcpPassthroughToKeyCode(int operation) { 286305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen switch (operation) { 286405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_UP: 286505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_UP; 286605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_DOWN: 286705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_DOWN; 286805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_LEFT: 286905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_LEFT; 287005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_RIGHT: 287105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_RIGHT; 287205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_UP: 287305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_UP_RIGHT; 287405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_RIGHT_DOWN: 287505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_DOWN_RIGHT; 287605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_LEFT_UP: 287705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_UP_LEFT; 287805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_LEFT_DOWN: 287905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_DPAD_DOWN_LEFT; 288005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_0: 288105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_0; 288205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_1: 288305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_1; 288405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_2: 288505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_2; 288605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_3: 288705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_3; 288805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_4: 288905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_4; 289005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_5: 289105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_5; 289205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_6: 289305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_6; 289405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_7: 289505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_7; 289605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_8: 289705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_8; 289805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_9: 289905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_9; 290005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_DOT: 290105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_DOT; 290205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_ENTER: 290305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_NUMPAD_ENTER; 290405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_CLEAR: 290505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_CLEAR; 290605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_CHAN_UP: 290705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_CHANNEL_UP; 290805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_CHAN_DOWN: 290905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_CHANNEL_DOWN; 291005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_PREV_CHAN: 291105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_LAST_CHANNEL; 291205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_INPUT_SEL: 291305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_TV_INPUT; 291405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_DISP_INFO: 291505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_INFO; 291605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_HELP: 291705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_HELP; 291805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_PAGE_UP: 291905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_PAGE_UP; 292005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_PAGE_DOWN: 292105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_PAGE_DOWN; 292205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_POWER: 292305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_POWER; 292405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_VOL_UP: 292505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_VOLUME_UP; 292605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_VOL_DOWN: 292705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_VOLUME_DOWN; 292805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_MUTE: 292905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MUTE; 29309bdbe9e309810d117c80328288a1819d39d8e7c8Andre Eisenbach case BluetoothAvrcp.PASSTHROUGH_ID_PLAY: 29319bdbe9e309810d117c80328288a1819d39d8e7c8Andre Eisenbach return KeyEvent.KEYCODE_MEDIA_PLAY; 293205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_STOP: 293305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_STOP; 29349bdbe9e309810d117c80328288a1819d39d8e7c8Andre Eisenbach case BluetoothAvrcp.PASSTHROUGH_ID_PAUSE: 29359bdbe9e309810d117c80328288a1819d39d8e7c8Andre Eisenbach return KeyEvent.KEYCODE_MEDIA_PAUSE; 293605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_RECORD: 293705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_RECORD; 293805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_REWIND: 293905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_REWIND; 294005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_FAST_FOR: 294105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_FAST_FORWARD; 294205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_EJECT: 294305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_EJECT; 294405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_FORWARD: 294505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_NEXT; 294605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_BACKWARD: 294705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_MEDIA_PREVIOUS; 294805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_F1: 294905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_F1; 295005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_F2: 295105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_F2; 295205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_F3: 295305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_F3; 295405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_F4: 295505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_F4; 295605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_F5: 295705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_F5; 295805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // Fallthrough for all unknown key mappings 295905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_SELECT: 296005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_ROOT_MENU: 296105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_SETUP_MENU: 296205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_CONT_MENU: 296305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_FAV_MENU: 296405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_EXIT: 296505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_SOUND_SEL: 296605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_ANGLE: 296705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_SUBPICT: 296805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen case BluetoothAvrcp.PASSTHROUGH_ID_VENDOR: 296905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen default: 297005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return KeyEvent.KEYCODE_UNKNOWN; 297105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 297205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 297305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 297405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private void addKeyPending(KeyEvent event) { 297578d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen mPassthroughPending.add(new MediaKeyLog(System.currentTimeMillis(), event)); 297605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 297705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 297805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private void recordKeyDispatched(KeyEvent event, String packageName) { 297905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen long time = System.currentTimeMillis(); 298005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Log.v(TAG, "recordKeyDispatched: " + event + " dispatched to " + packageName); 298178d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen setAddressedMediaSessionPackage(packageName); 298205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen synchronized (mPassthroughPending) { 298305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen Iterator<MediaKeyLog> pending = mPassthroughPending.iterator(); 298405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen while (pending.hasNext()) { 298505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen MediaKeyLog log = pending.next(); 298605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen if (log.addDispatch(time, event, packageName)) { 298705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mPassthroughDispatched++; 298805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen mPassthroughLogs.add(log); 298905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen pending.remove(); 299005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen return; 299105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 299205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 299378d53f7d7133cb5a32e1160e1c1a23f2e8174978Marie Janssen Log.w(TAG, "recordKeyDispatch: can't find matching log!"); 299405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 299505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 299605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 299705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen private final MediaSessionManager.Callback mButtonDispatchCallback = 299805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen new MediaSessionManager.Callback() { 299905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen @Override 300005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void onMediaKeyEventDispatched(KeyEvent event, MediaSession.Token token) { 300105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen // Get the package name 300205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen android.media.session.MediaController controller = 300305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen new android.media.session.MediaController(mContext, token); 300405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen String targetPackage = controller.getPackageName(); 300505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen recordKeyDispatched(event, targetPackage); 300605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 300705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 300805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen @Override 300905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void onMediaKeyEventDispatched(KeyEvent event, ComponentName receiver) { 301005df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen recordKeyDispatched(event, receiver.getPackageName()); 301105df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 301205df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 301305df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen @Override 301405df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void onAddressedPlayerChanged(MediaSession.Token token) { 301505df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen setActiveMediaSession(token); 301605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 301705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 301805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen @Override 301905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen public void onAddressedPlayerChanged(ComponentName receiver) { 302041527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen if (receiver == null) { 302141527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen // No active sessions, and no session to revive, give up. 302241527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen setAddressedMediaSessionPackage(null); 302341527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen return; 302441527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen } 302541527b2493a4ea59933c7cd4f8d1c761598509d8Marie Janssen // We can still get a passthrough which will revive this player. 302605df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen setAddressedMediaSessionPackage(receiver.getPackageName()); 302705df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen } 302805df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen }; 302905df242b454cbe62dab2bfaa07ab2b236ed00f67Marie Janssen 3030e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // Do not modify without updating the HAL bt_rc.h files. 3031e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 3032e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // match up with btrc_play_status_t enum of bt_rc.h 3033dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_STOPPED = 0; 3034dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_PLAYING = 1; 3035dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_PAUSED = 2; 3036dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_FWD_SEEK = 3; 3037dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_REV_SEEK = 4; 3038dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final byte PLAYSTATUS_ERROR = (byte) 255; 3039e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 3040e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // match up with btrc_media_attr_t enum of bt_rc.h 3041dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_TITLE = 1; 3042dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_ARTIST = 2; 3043dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_ALBUM = 3; 3044dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_TRACK_NUM = 4; 3045dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_NUM_TRACKS = 5; 3046dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_GENRE = 6; 3047dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int MEDIA_ATTR_PLAYING_TIME = 7; 3048e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah 3049e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah // match up with btrc_event_id_t enum of bt_rc.h 3050dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_PLAY_STATUS_CHANGED = 1; 3051dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_TRACK_CHANGED = 2; 3052dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_TRACK_REACHED_END = 3; 3053dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_TRACK_REACHED_START = 4; 3054dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_PLAY_POS_CHANGED = 5; 3055dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_BATT_STATUS_CHANGED = 6; 3056dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_SYSTEM_STATUS_CHANGED = 7; 3057dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_APP_SETTINGS_CHANGED = 8; 3058dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVENT_NOW_PLAYING_CONTENT_CHANGED = 9; 3059dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_AVBL_PLAYERS_CHANGED = 0xa; 3060dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVT_ADDR_PLAYER_CHANGED = 0xb; 3061dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He static final int EVENT_UIDS_CHANGED = 0x0c; 3062dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He 3063dbf5c4e1c9e57fa6e5cc96ee9f442da8aa391a5dJack He private static native void classInitNative(); 3064c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3065c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private native void initNative(); 3066c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3067c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private native void cleanupNative(); 3068c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3069e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean getPlayStatusRspNative(byte[] address, int playStatus, int songLen, 3070e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int songPos); 3071c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3072e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean getElementAttrRspNative(byte[] address, byte numAttr, int[] attrIds, 3073e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String[] textArray); 3074c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3075c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private native boolean registerNotificationRspPlayStatusNative(int type, int playStatus); 3076c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3077c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu private native boolean registerNotificationRspTrackChangeNative(int type, byte[] track); 3078c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3079aa1ffd5c6bd4f016c6ed452b3551e65872eaea8eZhihai Xu private native boolean registerNotificationRspPlayPosNative(int type, int playPos); 3080c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 308117675906064bb72fdcca75baa56cdf8bb8968d01John Du private native boolean setVolumeNative(int volume); 3082c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 30835c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta private native boolean sendPassThroughCommandNative(int keyCode, int keyState); 3084c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3085e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean setAddressedPlayerRspNative(byte[] address, int rspStatus); 3086c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3087e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean setBrowsedPlayerRspNative(byte[] address, int rspStatus, byte depth, 3088e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int numItems, String[] textArray); 3089c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3090e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean mediaPlayerListRspNative(byte[] address, int rsStatus, int uidCounter, 3091b7461b17cad5476a7a528cbf2a0b9c9706c6faefJack He byte itemType, int numItems, int[] playerIds, byte[] playerTypes, int[] playerSubTypes, 3092eef486e7e3145cc7b302ee1b00bbd317481cdabdMarie Janssen byte[] playStatusValues, short[] featureBitMaskValues, String[] textArray); 3093c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3094e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean getFolderItemsRspNative(byte[] address, int rspStatus, short uidCounter, 3095e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah byte scope, int numItems, byte[] folderTypes, byte[] playable, byte[] itemTypes, 3096b7461b17cad5476a7a528cbf2a0b9c9706c6faefJack He byte[] itemUidArray, String[] textArray, int[] attributesNum, int[] attributesIds, 3097e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah String[] attributesArray); 3098c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3099e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean changePathRspNative(byte[] address, int rspStatus, int numItems); 3100c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3101e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean getItemAttrRspNative(byte[] address, int rspStatus, byte numAttr, 3102e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int[] attrIds, String[] textArray); 3103c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3104e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean playItemRspNative(byte[] address, int rspStatus); 3105c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3106e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean getTotalNumOfItemsRspNative(byte[] address, int rspStatus, 3107e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int uidCounter, int numItems); 3108c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3109e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean searchRspNative(byte[] address, int rspStatus, int uidCounter, 3110e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah int numItems); 3111c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3112e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean addToNowPlayingRspNative(byte[] address, int rspStatus); 3113c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3114c4fbd756e2645147470c486ae96f2253f5e13a52Jack He private native boolean registerNotificationRspAddrPlayerChangedNative(int type, int playerId, 3115c4fbd756e2645147470c486ae96f2253f5e13a52Jack He int uidCounter); 3116c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3117e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean registerNotificationRspAvalPlayerChangedNative(int type); 3118c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3119e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean registerNotificationRspUIDsChangedNative(int type, int uidCounter); 3120c4fbd756e2645147470c486ae96f2253f5e13a52Jack He 3121e90c830b72f97189935e99e9e4f5a0c4f216ba72Avish Shah private native boolean registerNotificationRspNowPlayingChangedNative(int type); 31225c86abdc7875a8fae28c57e3e36a0a8eaae5cb04Hemant Gupta 3123c1c259c0ace7195240f1443c805995bfe8692a72Zhihai Xu} 3124