1fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie/* 2326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde* Copyright (C) 2014 Samsung System LSI 3fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Licensed under the Apache License, Version 2.0 (the "License"); 4fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* you may not use this file except in compliance with the License. 5fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* You may obtain a copy of the License at 6fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 7fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* http://www.apache.org/licenses/LICENSE-2.0 8fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* 9fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* Unless required by applicable law or agreed to in writing, software 10fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* distributed under the License is distributed on an "AS IS" BASIS, 11fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* See the License for the specific language governing permissions and 13fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie* limitations under the License. 14fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie*/ 15fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 16fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xiepackage com.android.bluetooth.map; 17fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 18326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.app.AlarmManager; 19326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.app.PendingIntent; 20fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.bluetooth.BluetoothAdapter; 21fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.bluetooth.BluetoothDevice; 22bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.BluetoothMap; 23fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.bluetooth.BluetoothProfile; 24fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.bluetooth.BluetoothUuid; 25bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.IBluetoothMap; 26bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.bluetooth.SdpMnsRecord; 27bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.BroadcastReceiver; 28fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Context; 29fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.content.Intent; 30bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.content.IntentFilter; 31326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.content.IntentFilter.MalformedMimeTypeException; 3260e306ba5c132d5408ccae3a290e7cace020a49fSeven Shenimport android.Manifest; 33fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.os.Handler; 341ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Guptaimport android.os.HandlerThread; 351ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Guptaimport android.os.Looper; 36fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.os.Message; 3770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulzimport android.os.ParcelUuid; 38bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.os.PowerManager; 39326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.os.RemoteException; 40bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport android.provider.Settings; 41fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.text.TextUtils; 42fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport android.util.Log; 43326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport android.util.SparseArray; 44fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 45fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.Utils; 46fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xieimport com.android.bluetooth.btservice.AdapterService; 4770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulzimport com.android.bluetooth.btservice.ProfileService; 48326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bondeimport com.android.bluetooth.btservice.ProfileService.IProfileServiceBinder; 49bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport com.android.bluetooth.R; 50bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 51bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.io.IOException; 52bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.ArrayList; 53bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.HashMap; 54bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.List; 55bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bondeimport java.util.Set; 56fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 5770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulzpublic class BluetoothMapService extends ProfileService { 58fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String TAG = "BluetoothMapService"; 59fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 60fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 61fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * To enable MAP DEBUG/VERBOSE logging - run below cmd in adb shell, and 62fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * restart com.android.bluetooth process. only enable DEBUG log: 63fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * "setprop log.tag.BluetoothMapService DEBUG"; enable both VERBOSE and 64fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * DEBUG log: "setprop log.tag.BluetoothMapService VERBOSE" 65fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 66fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 675a60e47497f21f64e6d79420dc4c56c1907df22akschulz public static final boolean DEBUG = true; //FIXME set to false; 68fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 69f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde public static final boolean VERBOSE = false; 70fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 71fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 72fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * Intent indicating timeout for user confirmation, which is sent to 73fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie * BluetoothMapActivity 74fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 75fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final String USER_CONFIRM_TIMEOUT_ACTION = 76326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde "com.android.bluetooth.map.USER_CONFIRM_TIMEOUT"; 77326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final int USER_CONFIRM_TIMEOUT_VALUE = 25000; 78fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 79326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** Intent indicating that the email settings activity should be opened*/ 805a60e47497f21f64e6d79420dc4c56c1907df22akschulz public static final String ACTION_SHOW_MAPS_SETTINGS = 815a60e47497f21f64e6d79420dc4c56c1907df22akschulz "android.btmap.intent.action.SHOW_MAPS_SETTINGS"; 82fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 83fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int MSG_SERVERSESSION_CLOSE = 5000; 84fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 85fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int MSG_SESSION_ESTABLISHED = 5001; 86fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 87fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public static final int MSG_SESSION_DISCONNECTED = 5002; 88fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 89326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int MSG_MAS_CONNECT = 5003; // Send at MAS connect, including the MAS_ID 90326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int MSG_MAS_CONNECT_CANCEL = 5004; // Send at auth. declined 91fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 92326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int MSG_ACQUIRE_WAKE_LOCK = 5005; 93c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu 94326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int MSG_RELEASE_WAKE_LOCK = 5006; 95c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu 96fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala public static final int MSG_MNS_SDP_SEARCH = 5007; 97fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala 98fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala public static final int MSG_OBSERVER_REGISTRATION = 5008; 99fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala 100fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 101fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 102fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; 103fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 104fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final int START_LISTENER = 1; 105fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 106fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static final int USER_TIMEOUT = 2; 107fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 10870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private static final int DISCONNECT_MAP = 3; 109fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 110326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final int SHUTDOWN = 4; 111326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 112c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu private static final int RELEASE_WAKE_LOCK_DELAY = 10000; 113c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu 114fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private PowerManager.WakeLock mWakeLock = null; 115fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 116326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final int UPDATE_MAS_INSTANCES = 5; 117fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 118326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int UPDATE_MAS_INSTANCES_ACCOUNT_ADDED = 0; 119326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int UPDATE_MAS_INSTANCES_ACCOUNT_REMOVED = 1; 120326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int UPDATE_MAS_INSTANCES_ACCOUNT_RENAMED = 2; 121326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public static final int UPDATE_MAS_INSTANCES_ACCOUNT_DISCONNECT = 3; 122fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 123326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final int MAS_ID_SMS_MMS = 0; 124fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 125326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private BluetoothAdapter mAdapter; 126fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 127fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private BluetoothMnsObexClient mBluetoothMnsObexClient = null; 128fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 129326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* mMasInstances: A list of the active MasInstances with the key being the MasId */ 130326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private SparseArray<BluetoothMapMasInstance> mMasInstances = 131326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new SparseArray<BluetoothMapMasInstance>(1); 132326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* mMasInstanceMap: A list of the active MasInstances with the key being the account */ 1335a60e47497f21f64e6d79420dc4c56c1907df22akschulz private HashMap<BluetoothMapAccountItem, BluetoothMapMasInstance> mMasInstanceMap = 1345a60e47497f21f64e6d79420dc4c56c1907df22akschulz new HashMap<BluetoothMapAccountItem, BluetoothMapMasInstance>(1); 135fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1364786e5fffff14d92b795084b4470b785de66dfd0ugo_yu private static BluetoothDevice mRemoteDevice = null; // The remote connected device - protect access 137fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1385a60e47497f21f64e6d79420dc4c56c1907df22akschulz private ArrayList<BluetoothMapAccountItem> mEnabledAccounts = null; 139fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private static String sRemoteDeviceName = null; 140fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 141fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private int mState; 1425a60e47497f21f64e6d79420dc4c56c1907df22akschulz private BluetoothMapAppObserver mAppObserver = null; 143326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private AlarmManager mAlarmManager = null; 144fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 145326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean mIsWaitingAuthorization = false; 146326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean mRemoveTimeoutMsg = false; 1475cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta private boolean mRegisteredMapReceiver = false; 148fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee private int mPermission = BluetoothDevice.ACCESS_UNKNOWN; 149326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean mAccountChanged = false; 150bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde private boolean mSdpSearchInitiated = false; 151bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde SdpMnsRecord mMnsRecord = null; 1521ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta private MapServiceMessageHandler mSessionStatusHandler; 1535cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta private boolean mStartError = true; 154326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 1554d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi private boolean mSmsCapable = true; 1564d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi 157326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // package and class name to which we send intent to check phone book access permission 158326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings"; 159326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private static final String ACCESS_AUTHORITY_CLASS = 160326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde "com.android.settings.bluetooth.BluetoothPermissionRequest"; 161fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 16270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private static final ParcelUuid[] MAP_UUIDS = { 16370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothUuid.MAP, 16470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothUuid.MNS, 16570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz }; 16670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 167fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public BluetoothMapService() { 168fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mState = BluetoothMap.STATE_DISCONNECTED; 169fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 170fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 1725a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1731ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta private synchronized void closeService() { 174326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "MAP Service closeService in"); 175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 176326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mBluetoothMnsObexClient != null) { 177326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mBluetoothMnsObexClient.shutdown(); 178326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mBluetoothMnsObexClient = null; 17970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1801ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (mMasInstances.size() > 0) { 1811ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta for (int i=0, c=mMasInstances.size(); i < c; i++) { 1821ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mMasInstances.valueAt(i).shutdown(); 1831ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 1841ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mMasInstances.clear(); 185fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 18670bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu 187326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = false; 188fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mPermission = BluetoothDevice.ACCESS_UNKNOWN; 189326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde setState(BluetoothMap.STATE_DISCONNECTED); 19070bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu 19170bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu if (mWakeLock != null) { 19270bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu mWakeLock.release(); 193f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "CloseService(): Release Wake Lock"); 19470bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu mWakeLock = null; 19570bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu } 1961ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta /* Only one SHUTDOWN message expected to closeService. 1971ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta * Hence, quit looper and Handler on first SHUTDOWN message*/ 1981ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (mSessionStatusHandler != null) { 1991ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta //Perform cleanup in Handler running on worker Thread 2001ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mSessionStatusHandler.removeCallbacksAndMessages(null); 2011ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Looper looper = mSessionStatusHandler.getLooper(); 2021ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (looper != null) { 2031ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta looper.quit(); 2041ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if(VERBOSE) Log.i(TAG, "Quit looper"); 2051ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 2061ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mSessionStatusHandler = null; 2071ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if(VERBOSE) Log.i(TAG, "Remove Handler"); 2081ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 209326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mRemoteDevice = null; 21070bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu 211326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (VERBOSE) Log.v(TAG, "MAP Service closeService out"); 212326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 21370bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu 214326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 215bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * Starts the RFComm listener threads for each MAS 216326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @throws IOException 217326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 218bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde private final void startRfcommSocketListeners(int masId) { 219bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde if(masId == -1) { 220bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 221bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mMasInstances.valueAt(i).startRfcommSocketListener(); 222bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 223bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } else { 224bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde BluetoothMapMasInstance masInst = mMasInstances.get(masId); // returns null for -1 225bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde if(masInst != null) { 226bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde masInst.startRfcommSocketListener(); 227bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } else { 228bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde Log.w(TAG, "startRfcommSocketListeners(): Invalid MasId: " + masId); 229bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 23070bfe3280ce158c39dbb25fe18386f0d10b490d3Zhihai Xu } 231fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 232fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 233326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 234326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Start a MAS instance for SMS/MMS and each e-mail account. 235326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 236326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private final void startObexServerSessions() { 237326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "Map Service START ObexServerSessions()"); 238fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 239fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // acquire the wakeLock before start Obex transaction thread 240fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (mWakeLock == null) { 241fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); 242fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 243fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie "StartingObexMapTransaction"); 244fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mWakeLock.setReferenceCounted(false); 245fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mWakeLock.acquire(); 246f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "startObexSessions(): Acquire Wake Lock"); 247fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 248fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 249326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mBluetoothMnsObexClient == null) { 250bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mBluetoothMnsObexClient = 251bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde new BluetoothMnsObexClient(mRemoteDevice, mMnsRecord, mSessionStatusHandler); 252326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 253326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 254326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean connected = false; 255326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 256326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 257326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mMasInstances.valueAt(i) 258326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde .startObexServerSession(mBluetoothMnsObexClient) == true) { 259326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde connected = true; 260326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 261326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (IOException e) { 262bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde Log.w(TAG,"IOException occured while starting an obexServerSession restarting" + 263bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde " the listener",e); 264326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.valueAt(i).restartObexServerSession(); 265326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (RemoteException e) { 266bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde Log.w(TAG,"RemoteException occured while starting an obexServerSession restarting" + 267bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde " the listener",e); 268326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.valueAt(i).restartObexServerSession(); 269326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 270326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 271326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(connected) { 272326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde setState(BluetoothMap.STATE_CONNECTED); 273fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 274c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu 275c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 276c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 277326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY); 278c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu 279f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "startObexServerSessions() success!"); 280fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 281fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 282326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public Handler getHandler() { 283326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return mSessionStatusHandler; 284fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 285fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 286fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie /** 287326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Restart a MAS instances. 288326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param masId use -1 to stop all instances 289fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie */ 290326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void stopObexServerSessions(int masId) { 291326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "MAP Service STOP ObexServerSessions()"); 292fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 293326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean lastMasInst = true; 294fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 295326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masId != -1) { 296326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 297326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = mMasInstances.valueAt(i); 298326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masInst.getMasId() != masId && masInst.isStarted()) { 299326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde lastMasInst = false; 300fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 301fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 302326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Else just close down it all 303fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 304326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Shutdown the MNS client - currently must happen before MAS close */ 305326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mBluetoothMnsObexClient != null && lastMasInst) { 306326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mBluetoothMnsObexClient.shutdown(); 307326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mBluetoothMnsObexClient = null; 308326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 30943b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 310326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = mMasInstances.get(masId); // returns null for -1 311326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masInst != null) { 312326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masInst.restartObexServerSession(); 3131ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } else if(masId == -1) { 314326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 315326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.valueAt(i).restartObexServerSession(); 316326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 317326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 318fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 319326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(lastMasInst) { 320326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde setState(BluetoothMap.STATE_DISCONNECTED); 321fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mPermission = BluetoothDevice.ACCESS_UNKNOWN; 322326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mRemoteDevice = null; 323326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mAccountChanged) { 324326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde updateMasInstances(UPDATE_MAS_INSTANCES_ACCOUNT_DISCONNECT); 325fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 326fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 327fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 328326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Release the wake lock at disconnect 329326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mWakeLock != null && lastMasInst) { 330326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mSessionStatusHandler.removeMessages(MSG_ACQUIRE_WAKE_LOCK); 331326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 332326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mWakeLock.release(); 333f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "stopObexServerSessions(): Release Wake Lock"); 334fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 335fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 336fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 3371ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta private final class MapServiceMessageHandler extends Handler { 3381ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta private MapServiceMessageHandler(Looper looper) { 3391ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta super(looper); 3401ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 341fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie @Override 342fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie public void handleMessage(Message msg) { 343fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (VERBOSE) Log.v(TAG, "Handler(): got msg=" + msg.what); 344fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 345fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie switch (msg.what) { 346326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde case UPDATE_MAS_INSTANCES: 347326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde updateMasInstancesHandler(); 348326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde break; 349fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case START_LISTENER: 350fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (mAdapter.isEnabled()) { 351bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde startRfcommSocketListeners(msg.arg1); 352fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 353fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 354326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde case MSG_MAS_CONNECT: 355326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde onConnectHandler(msg.arg1); 356326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde break; 357326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde case MSG_MAS_CONNECT_CANCEL: 358bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde /* TODO: We need to handle this by accepting the connection and reject at 359bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * OBEX level, by using ObexRejectServer - add timeout to handle clients not 360bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * closing the transport channel. 361bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde */ 362326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde stopObexServerSessions(-1); 363326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde break; 364fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case USER_TIMEOUT: 365fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (mIsWaitingAuthorization){ 366326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); 367326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS); 368326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 369326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 370326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); 371326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendBroadcast(intent); 372326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde cancelUserTimeoutAlarm(); 373326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = false; 374326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde stopObexServerSessions(-1); 375326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 376fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 377fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case MSG_SERVERSESSION_CLOSE: 378326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde stopObexServerSessions(msg.arg1); 379fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 380fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case MSG_SESSION_ESTABLISHED: 381fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 382fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie case MSG_SESSION_DISCONNECTED: 383fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie // handled elsewhere 384fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 38570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz case DISCONNECT_MAP: 38670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz disconnectMap((BluetoothDevice)msg.obj); 387fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 388326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde case SHUTDOWN: 389326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Ensure to call close from this handler to avoid starting new stuff 390326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde because of pending messages */ 391326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde closeService(); 392326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde break; 393c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu case MSG_ACQUIRE_WAKE_LOCK: 394f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "Acquire Wake Lock request message"); 395c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu if (mWakeLock == null) { 396c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu PowerManager pm = (PowerManager)getSystemService( 397c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu Context.POWER_SERVICE); 398c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 399c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu "StartingObexMapTransaction"); 400c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mWakeLock.setReferenceCounted(false); 401326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 402326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(!mWakeLock.isHeld()) { 403c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mWakeLock.acquire(); 404f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (DEBUG) Log.d(TAG, " Acquired Wake Lock by message"); 405c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu } 406c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK); 407c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mSessionStatusHandler.sendMessageDelayed(mSessionStatusHandler 408c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu .obtainMessage(MSG_RELEASE_WAKE_LOCK), RELEASE_WAKE_LOCK_DELAY); 409c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu break; 410c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu case MSG_RELEASE_WAKE_LOCK: 411f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "Release Wake Lock request message"); 412c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu if (mWakeLock != null) { 413c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu mWakeLock.release(); 414f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (DEBUG) Log.d(TAG, " Released Wake Lock by message"); 415c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu } 416c09b531ba47eee740485b0c6022981fc38ef1587Zhihai Xu break; 417fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala case MSG_MNS_SDP_SEARCH: 418fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (mRemoteDevice != null) { 419fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (DEBUG) Log.d(TAG,"MNS SDP Initiate Search .."); 420fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala mRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS); 421fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } else { 422fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala Log.w(TAG, "remoteDevice info not available"); 423fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 424fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala break; 425fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala case MSG_OBSERVER_REGISTRATION: 426fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (DEBUG) Log.d(TAG,"ContentObserver Registration MASID: " + msg.arg1 427fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala + " Enable: " + msg.arg2); 428fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala BluetoothMapMasInstance masInst = mMasInstances.get(msg.arg1); 4291682d51711c917a440be14a600eb8ab89ad36f61Ashwini Munigala if (masInst != null && masInst.mObserver != null) { 430fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala try { 431fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (msg.arg2 == BluetoothMapAppParams.NOTIFICATION_STATUS_YES) { 432fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala masInst.mObserver.registerObserver(); 433fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } else { 434fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala masInst.mObserver.unregisterObserver(); 435fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 436fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } catch (RemoteException e) { 437fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala Log.e(TAG,"ContentObserverRegistarion Failed: "+ e); 438fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 439fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 440fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala break; 441fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie default: 442fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie break; 443fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 444fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 445fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie }; 446fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 447326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void onConnectHandler(int masId) { 4485a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (mIsWaitingAuthorization == true || mRemoteDevice == null 449f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde || mSdpSearchInitiated == true) { 450326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return; 451326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 452326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = mMasInstances.get(masId); 453fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee // Need to ensure we are still allowed. 454fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (DEBUG) Log.d(TAG, "mPermission = " + mPermission); 455fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (mPermission == BluetoothDevice.ACCESS_ALLOWED) { 456326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try { 457f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "incoming connection accepted from: " 458fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + sRemoteDeviceName + " automatically as trusted device"); 459fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (mBluetoothMnsObexClient != null && masInst != null) { 460326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masInst.startObexServerSession(mBluetoothMnsObexClient); 461326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 462326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde startObexServerSessions(); 463326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 464326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (IOException ex) { 465326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.e(TAG, "catch IOException starting obex server session", ex); 466326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (RemoteException ex) { 467326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.e(TAG, "catch RemoteException starting obex server session", ex); 468326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 469326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 470326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 471fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee 472326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public int getState() { 47370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return mState; 47470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 47570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 4765cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta protected boolean isMapStarted() { 4775cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta return !mStartError; 4785cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } 4794786e5fffff14d92b795084b4470b785de66dfd0ugo_yu public static BluetoothDevice getRemoteDevice() { 48070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return mRemoteDevice; 48170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 482fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private void setState(int state) { 483fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie setState(state, BluetoothMap.RESULT_SUCCESS); 484fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 485fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 486fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie private synchronized void setState(int state, int result) { 487fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (state != mState) { 488fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (DEBUG) Log.d(TAG, "Map state " + mState + " -> " + state + ", result = " 489fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie + result); 490fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie int prevState = mState; 491fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mState = state; 49270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Intent intent = new Intent(BluetoothMap.ACTION_CONNECTION_STATE_CHANGED); 49370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState); 49470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz intent.putExtra(BluetoothProfile.EXTRA_STATE, mState); 495fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 496fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie sendBroadcast(intent, BLUETOOTH_PERM); 497fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie AdapterService s = AdapterService.getAdapterService(); 498fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (s != null) { 499fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie s.onProfileConnectionStateChanged(mRemoteDevice, BluetoothProfile.MAP, 500fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie mState, prevState); 501fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 502fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 503fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 504fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 50570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public static String getRemoteDeviceName() { 50670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return sRemoteDeviceName; 50770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 508fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 50970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean disconnect(BluetoothDevice device) { 510bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mSessionStatusHandler.sendMessage(mSessionStatusHandler 511bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde .obtainMessage(DISCONNECT_MAP, 0, 0, device)); 51270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return true; 51370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 514fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 51570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean disconnectMap(BluetoothDevice device) { 51670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz boolean result = false; 51770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "disconnectMap"); 5181ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (getRemoteDevice()!= null && getRemoteDevice().equals(device)) { 51970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz switch (mState) { 52070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz case BluetoothMap.STATE_CONNECTED: 521335b2b8f6f17c93a4c2b192c8e1b629e48b230b3PauloftheWest /* Disconnect all connections and restart all MAS instances */ 522335b2b8f6f17c93a4c2b192c8e1b629e48b230b3PauloftheWest stopObexServerSessions(-1); 52370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz result = true; 52470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz break; 52570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz default: 52670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz break; 52770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 52870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 52970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return result; 53070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 531fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 53270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public List<BluetoothDevice> getConnectedDevices() { 53370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); 53470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz synchronized(this) { 53570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (mState == BluetoothMap.STATE_CONNECTED && mRemoteDevice != null) { 53670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz devices.add(mRemoteDevice); 53770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 53870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 53970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return devices; 54070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 541fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 54270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 54370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz List<BluetoothDevice> deviceList = new ArrayList<BluetoothDevice>(); 54470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Set<BluetoothDevice> bondedDevices = mAdapter.getBondedDevices(); 54570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int connectionState; 54670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz synchronized (this) { 54770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz for (BluetoothDevice device : bondedDevices) { 54870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz ParcelUuid[] featureUuids = device.getUuids(); 54970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (!BluetoothUuid.containsAnyUuid(featureUuids, MAP_UUIDS)) { 55070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz continue; 55170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 55270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz connectionState = getConnectionState(device); 55370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz for(int i = 0; i < states.length; i++) { 55470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (connectionState == states[i]) { 55570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz deviceList.add(device); 55670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 55770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 55870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 55970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 56070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return deviceList; 56170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 562fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 56370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public int getConnectionState(BluetoothDevice device) { 56470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz synchronized(this) { 56570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (getState() == BluetoothMap.STATE_CONNECTED && getRemoteDevice().equals(device)) { 56670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return BluetoothProfile.STATE_CONNECTED; 56770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else { 56870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return BluetoothProfile.STATE_DISCONNECTED; 56970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 570fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 571fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 572fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 57370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean setPriority(BluetoothDevice device, int priority) { 57470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Settings.Global.putInt(getContentResolver(), 57570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Settings.Global.getBluetoothMapPriorityKey(device.getAddress()), 57670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz priority); 577f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "Saved priority " + device + " = " + priority); 57870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return true; 579fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 580fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 58170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public int getPriority(BluetoothDevice device) { 58270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int priority = Settings.Global.getInt(getContentResolver(), 58370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Settings.Global.getBluetoothMapPriorityKey(device.getAddress()), 58470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothProfile.PRIORITY_UNDEFINED); 58570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return priority; 586fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 587fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 58870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz @Override 58970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz protected IProfileServiceBinder initBinder() { 59070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return new BluetoothMapBinder(this); 59170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 592fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 59370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz @Override 59470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz protected boolean start() { 59570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "start()"); 5965cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (isMapStarted()) { 5975cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta Log.w(TAG, "start received for already started, ignoring"); 5985cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta return false; 5995cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } 6001ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta HandlerThread thread = new HandlerThread("BluetoothMapHandler"); 6011ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta thread.start(); 6021ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Looper looper = thread.getLooper(); 6031ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mSessionStatusHandler = new MapServiceMessageHandler(looper); 6041ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta 60570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz IntentFilter filter = new IntentFilter(); 60670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); 60770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); 60843b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); 609bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde filter.addAction(BluetoothDevice.ACTION_SDP_RECORD); 6105a60e47497f21f64e6d79420dc4c56c1907df22akschulz filter.addAction(ACTION_SHOW_MAPS_SETTINGS); 611326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde filter.addAction(USER_CONFIRM_TIMEOUT_ACTION); 612326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 613326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // We need two filters, since Type only applies to the ACTION_MESSAGE_SENT 614326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde IntentFilter filterMessageSent = new IntentFilter(); 615326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde filterMessageSent.addAction(BluetoothMapContentObserver.ACTION_MESSAGE_SENT); 616326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde try{ 617326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde filterMessageSent.addDataType("message/*"); 618326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } catch (MalformedMimeTypeException e) { 619326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.e(TAG, "Wrong mime type!!!", e); 620326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 6215cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (!mRegisteredMapReceiver) { 6225cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta try { 6235cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta registerReceiver(mMapReceiver, filter); 62460e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen // We need WRITE_SMS permission to handle messages in 62560e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen // actionMessageSentDisconnected() 62660e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen registerReceiver(mMapReceiver, filterMessageSent, 62760e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen Manifest.permission.WRITE_SMS, null); 6285cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta mRegisteredMapReceiver = true; 6295cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } catch (Exception e) { 6305cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta Log.e(TAG,"Unable to register map receiver",e); 6315cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } 63270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 63370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz mAdapter = BluetoothAdapter.getDefaultAdapter(); 6345a60e47497f21f64e6d79420dc4c56c1907df22akschulz mAppObserver = new BluetoothMapAppObserver(this, this); 635326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 636326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mEnabledAccounts = mAppObserver.getEnabledAccountItems(); 6374d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi 6384d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi mSmsCapable = getResources().getBoolean( 6394d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi com.android.internal.R.bool.config_sms_capable); 640326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Uses mEnabledAccounts, hence getEnabledAccountItems() must be called before this. 641326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde createMasInstances(); 642326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 64370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz // start RFCOMM listener 644bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde sendStartListenerMessage(-1); 6455cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta mStartError = false; 6465cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta return !mStartError; 64770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 648fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 649326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 650326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Call this to trigger an update of the MAS instance list. 651326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * No changes will be applied unless in disconnected state 652326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 653326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public void updateMasInstances(int action) { 654326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mSessionStatusHandler.obtainMessage (UPDATE_MAS_INSTANCES, 655326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde action, 0).sendToTarget(); 656326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 657326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 658326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 659326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Update the active MAS Instances according the difference between mEnabledDevices 660326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * and the current list of accounts. 661326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Will only make changes if state is disconnected. 662326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 663326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * How it works: 664326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 1) Build lists of account changes from last update of mEnabledAccounts. 665326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * newAccounts - accounts that have been enabled since mEnabledAccounts 666326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * was last updated. 667326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * removedAccounts - Accounts that is on mEnabledAccounts, but no longer 668326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * enabled. 669326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * enabledAccounts - A new list of all enabled accounts. 670326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 2) Stop and remove all MasInstances on the remove list 671326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 3) Add and start MAS instances for accounts on the new list. 672326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Called at: 673326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * - Each change in accounts 674326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * - Each disconnect - before MasInstances restart. 675326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * 676326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return true is any changes are made, false otherwise. 677326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 678326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private boolean updateMasInstancesHandler(){ 679f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (DEBUG) Log.d(TAG,"updateMasInstancesHandler() state = " + getState()); 680326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean changed = false; 681326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 682326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(getState() == BluetoothMap.STATE_DISCONNECTED) { 6835a60e47497f21f64e6d79420dc4c56c1907df22akschulz ArrayList<BluetoothMapAccountItem> newAccountList = 684bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mAppObserver.getEnabledAccountItems(); 6855a60e47497f21f64e6d79420dc4c56c1907df22akschulz ArrayList<BluetoothMapAccountItem> newAccounts = null; 6865a60e47497f21f64e6d79420dc4c56c1907df22akschulz ArrayList<BluetoothMapAccountItem> removedAccounts = null; 6875a60e47497f21f64e6d79420dc4c56c1907df22akschulz newAccounts = new ArrayList<BluetoothMapAccountItem>(); 688bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde removedAccounts = mEnabledAccounts; // reuse the current enabled list, to track removed 689bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde // accounts 6905a60e47497f21f64e6d79420dc4c56c1907df22akschulz for(BluetoothMapAccountItem account: newAccountList) { 691326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(!removedAccounts.remove(account)) { 692326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde newAccounts.add(account); 693326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 694326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 695326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 696326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(removedAccounts != null) { 697326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Remove all disabled/removed accounts */ 6985a60e47497f21f64e6d79420dc4c56c1907df22akschulz for(BluetoothMapAccountItem account : removedAccounts) { 699326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = mMasInstanceMap.remove(account); 700f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG," Removing account: " + account + " masInst = " + masInst); 701326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masInst != null) { 702326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masInst.shutdown(); 703326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.remove(masInst.getMasId()); 704326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde changed = true; 705326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 706326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 707326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 708326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 709326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(newAccounts != null) { 710326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Add any newly created accounts */ 7115a60e47497f21f64e6d79420dc4c56c1907df22akschulz for(BluetoothMapAccountItem account : newAccounts) { 712f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG," Adding account: " + account); 713326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int masId = getNextMasId(); 714326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance newInst = 715326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new BluetoothMapMasInstance(this, 716326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this, 717326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde account, 718326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masId, 719326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde false); 720326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.append(masId, newInst); 721326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstanceMap.put(account, newInst); 722326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde changed = true; 723326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Start the new instance */ 724326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mAdapter.isEnabled()) { 725326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde newInst.startRfcommSocketListener(); 726326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 727326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 728326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 729326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mEnabledAccounts = newAccountList; 730f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) { 731f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG," Enabled accounts:"); 7325a60e47497f21f64e6d79420dc4c56c1907df22akschulz for(BluetoothMapAccountItem account : mEnabledAccounts) { 733f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, " " + account); 734326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 735f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG," Active MAS instances:"); 736326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 737326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = mMasInstances.valueAt(i); 738f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, " " + masInst); 739326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 740326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 741326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mAccountChanged = false; 742326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else { 743326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mAccountChanged = true; 744326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 745326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return changed; 746326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 747326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 748326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 749326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Will return the next MasId to use. 750326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Will ensure the key returned is greater than the largest key in use. 751326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Unless the key 255 is in use, in which case the first free masId 752326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * will be returned. 753326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return 754326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 755326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private int getNextMasId() { 756326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Find the largest masId in use */ 757326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int largestMasId = 0; 758326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i=0, c=mMasInstances.size(); i < c; i++) { 759326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int masId = mMasInstances.keyAt(i); 760326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masId > largestMasId) { 761326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde largestMasId = masId; 762326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 763326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 764326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(largestMasId < 0xff) { 765326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return largestMasId + 1; 766326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 767326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* If 0xff is already in use, wrap and choose the first free 768326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * MasId. */ 769326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde for(int i = 1; i <= 0xff; i++) { 770326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mMasInstances.get(i) == null) { 771326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return i; 772326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 773326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 774326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return 0xff; // This will never happen, as we only allow 10 e-mail accounts to be enabled 775326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 776326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 777326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void createMasInstances() { 7784d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi int masId = mSmsCapable ? MAS_ID_SMS_MMS : -1; 7794d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi 7804d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi if (mSmsCapable) { 7814d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi // Add the SMS/MMS instance 7824d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi BluetoothMapMasInstance smsMmsInst = 7834d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi new BluetoothMapMasInstance(this, 7844d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi this, 7854d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi null, 7864d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi masId, 7874d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi true); 7884d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi mMasInstances.append(masId, smsMmsInst); 7894d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi mMasInstanceMap.put(null, smsMmsInst); 7904d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi } 791326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 792326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // get list of accounts already set to be visible through MAP 7935a60e47497f21f64e6d79420dc4c56c1907df22akschulz for(BluetoothMapAccountItem account : mEnabledAccounts) { 794326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masId++; // SMS/MMS is masId=0, increment before adding next 795326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance newInst = 796326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new BluetoothMapMasInstance(this, 797326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde this, 798326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde account, 799326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde masId, 800326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde false); 801326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstances.append(masId, newInst); 802326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mMasInstanceMap.put(account, newInst); 803326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 804326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 805326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 80670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz @Override 80770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz protected boolean stop() { 80870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "stop()"); 8095cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (mRegisteredMapReceiver) { 8105cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta try { 8115cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta mRegisteredMapReceiver = false; 8125cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta unregisterReceiver(mMapReceiver); 8135cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta mAppObserver.shutdown(); 8145cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } catch (Exception e) { 8155cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta Log.e(TAG,"Unable to unregister map receiver",e); 8165cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } 817fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 8185cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta //Stop MapProfile if already started. 8195cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta //TODO: Check if the profile state can be retreived from ProfileService or AdapterService. 8205cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (!isMapStarted()) { 8215cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (DEBUG) Log.d(TAG, "Service Not Available to STOP, ignoring"); 8225cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta return true; 8235cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } else { 8245cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta if (VERBOSE) Log.d(TAG, "Service Stoping()"); 8255cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta } 8261ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (mSessionStatusHandler != null) { 8271ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta sendShutdownMessage(); 8281ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 8295cd7c89d0e17a9176337a36a27792bab3dd76fe9Hemant Gupta mStartError = true; 83070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); 83170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return true; 83270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 83370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 83470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean cleanup() { 83570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "cleanup()"); 83670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); 8371ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta //Cleanup already handled in Stop(). 8381ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta //Move this extra check to Handler. 8391ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta sendShutdownMessage(); 84070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return true; 84170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 84270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 843326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /** 844326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * Called from each MAS instance when a connection is received. 845326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param remoteDevice The device connecting 846326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @param masInst a reference to the calling MAS instance. 847326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde * @return 848326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde */ 849326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde public boolean onConnect(BluetoothDevice remoteDevice, BluetoothMapMasInstance masInst) { 850fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean sendIntent = false; 851fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean cancelConnection = false; 852326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 853326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // As this can be called from each MasInstance, we need to lock access to member variables 854326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde synchronized(this) { 855fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (mRemoteDevice == null) { 856326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mRemoteDevice = remoteDevice; 857326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sRemoteDeviceName = mRemoteDevice.getName(); 858326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // In case getRemoteName failed and return null 859326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (TextUtils.isEmpty(sRemoteDeviceName)) { 860326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sRemoteDeviceName = getString(R.string.defaultname); 861326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 862326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 863fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mPermission = mRemoteDevice.getMessageAccessPermission(); 864fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (mPermission == BluetoothDevice.ACCESS_UNKNOWN) { 865326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendIntent = true; 866326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = true; 867326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde setUserTimeoutAlarm(); 868fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else if (mPermission == BluetoothDevice.ACCESS_REJECTED) { 869fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee cancelConnection = true; 8705a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if(mPermission == BluetoothDevice.ACCESS_ALLOWED) { 8715a60e47497f21f64e6d79420dc4c56c1907df22akschulz mRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS); 8725a60e47497f21f64e6d79420dc4c56c1907df22akschulz mSdpSearchInitiated = true; 873326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 874326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (!mRemoteDevice.equals(remoteDevice)) { 875326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Log.w(TAG, "Unexpected connection from a second Remote Device received. name: " + 876326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde ((remoteDevice==null)?"unknown":remoteDevice.getName())); 877326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return false; /* The connecting device is different from what is already 878326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde connected, reject the connection. */ 879326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Else second connection to same device, just continue 880326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 881326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 882fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (sendIntent) { 883fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee // This will trigger Settings app's dialog. 884fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REQUEST); 885326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS); 886326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 887326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); 888326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 889beb0497605ef61062d0565d85897f4c842845a8fAng Li sendOrderedBroadcast(intent, BLUETOOTH_ADMIN_PERM); 890326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 891f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "waiting for authorization for connection from: " 892326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde + sRemoteDeviceName); 893326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde //Queue USER_TIMEOUT to disconnect MAP OBEX session. If user doesn't 894326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde //accept or reject authorization request 895fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else if (cancelConnection) { 896fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee sendConnectCancelMessage(); 897fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } else if (mPermission == BluetoothDevice.ACCESS_ALLOWED) { 898326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Signal to the service that we have a incoming connection. */ 899326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendConnectMessage(masInst.getMasId()); 900326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 901326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde return true; 902326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde }; 903326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 904326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 905326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void setUserTimeoutAlarm(){ 906f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (DEBUG) Log.d(TAG,"SetUserTimeOutAlarm()"); 907326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mAlarmManager == null){ 908326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mAlarmManager =(AlarmManager) this.getSystemService (Context.ALARM_SERVICE); 909326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 910326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mRemoveTimeoutMsg = true; 911326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Intent timeoutIntent = 912326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new Intent(USER_CONFIRM_TIMEOUT_ACTION); 913326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, timeoutIntent, 0); 914bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 915bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde USER_CONFIRM_TIMEOUT_VALUE,pIntent); 916326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 917326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 918326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void cancelUserTimeoutAlarm(){ 919f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (DEBUG) Log.d(TAG,"cancelUserTimeOutAlarm()"); 9200f67816e838489474a0c3c57a8d856f6d51ba45fAshwini Munigala Intent timeoutIntent = new Intent(USER_CONFIRM_TIMEOUT_ACTION); 9210f67816e838489474a0c3c57a8d856f6d51ba45fAshwini Munigala PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, timeoutIntent, 0); 9220f67816e838489474a0c3c57a8d856f6d51ba45fAshwini Munigala pIntent.cancel(); 9230f67816e838489474a0c3c57a8d856f6d51ba45fAshwini Munigala 924326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); 9250f67816e838489474a0c3c57a8d856f6d51ba45fAshwini Munigala alarmManager.cancel(pIntent); 926326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mRemoveTimeoutMsg = false; 927326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 928326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 929bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde /** 930bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * Start the incoming connection listeners for a MAS ID 931bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * @param masId the MasID to start. Use -1 to start all listeners. 932bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde */ 933bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde public void sendStartListenerMessage(int masId) { 9341ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (mSessionStatusHandler != null && ! mSessionStatusHandler.hasMessages(START_LISTENER)) { 935bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde Message msg = mSessionStatusHandler.obtainMessage(START_LISTENER, masId, 0); 936bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde /* We add a small delay here to ensure the call returns true before this message is 937bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * handled. It seems wrong to add a delay, but the alternative is to build a lock 938bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * system to handle synchronization, which isn't nice either... */ 939bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mSessionStatusHandler.sendMessageDelayed(msg, 20); 9401ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } else if (mSessionStatusHandler != null) { 9411ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if(DEBUG) 9421ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Log.w(TAG, "mSessionStatusHandler START_LISTENER message already in Queue"); 9431ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 944bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 945bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 946326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void sendConnectMessage(int masId) { 947326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mSessionStatusHandler != null) { 948326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Message msg = mSessionStatusHandler.obtainMessage(MSG_MAS_CONNECT, masId, 0); 949bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde /* We add a small delay here to ensure onConnect returns true before this message is 950bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * handled. It seems wrong, but the alternative is to store a reference to the 951bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde * connection in this message, which isn't nice either... */ 952bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mSessionStatusHandler.sendMessageDelayed(msg, 20); 953326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Can only be null during shutdown 954326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 955326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void sendConnectTimeoutMessage() { 956326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "sendConnectTimeoutMessage()"); 957326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mSessionStatusHandler != null) { 958326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Message msg = mSessionStatusHandler.obtainMessage(USER_TIMEOUT); 959326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.sendToTarget(); 960326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Can only be null during shutdown 961326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 962326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void sendConnectCancelMessage() { 963326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(mSessionStatusHandler != null) { 964326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Message msg = mSessionStatusHandler.obtainMessage(MSG_MAS_CONNECT_CANCEL); 965326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde msg.sendToTarget(); 966326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } // Can only be null during shutdown 967326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 968326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 969326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde private void sendShutdownMessage() { 970326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* Any pending messages are no longer valid. 971326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde To speed up things, simply delete them. */ 972326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mRemoveTimeoutMsg) { 973326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde Intent timeoutIntent = 974326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde new Intent(USER_CONFIRM_TIMEOUT_ACTION); 975326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendBroadcast(timeoutIntent, BLUETOOTH_PERM); 976326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = false; 977326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde cancelUserTimeoutAlarm(); 978326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 9791ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (mSessionStatusHandler != null && !mSessionStatusHandler.hasMessages(SHUTDOWN)) { 9801ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta mSessionStatusHandler.removeCallbacksAndMessages(null); 9811ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta // Request release of all resources 9821ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Message msg = mSessionStatusHandler.obtainMessage(SHUTDOWN); 9831ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if( mSessionStatusHandler.sendMessage(msg) == false) { 9841ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta /* most likely caused by shutdown being called from multiple sources - e.g.BT off 9851ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta * signaled through intent and a service shutdown simultaneously. 9861ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta * Intended behavior not documented, hence we need to be able to handle all cases*/ 9871ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } else { 9881ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if(DEBUG) 9891ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Log.e(TAG, "mSessionStatusHandler.sendMessage() dispatched shutdown message"); 9901ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 9911ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } else if (mSessionStatusHandler != null) { 9921ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if(DEBUG) 9931ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta Log.w(TAG, "mSessionStatusHandler shutdown message already in Queue"); 9941ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta } 9951ff5a0a6b42eff4c5728f0327440c127f8d3bb1cHemant Gupta if (VERBOSE) Log.d(TAG, "sendShutdownMessage() Out"); 996326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 99743b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 99870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver(); 999fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 100070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private class MapBroadcastReceiver extends BroadcastReceiver { 100170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz @Override 100270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public void onReceive(Context context, Intent intent) { 100370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "onReceive"); 100470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz String action = intent.getAction(); 10055a60e47497f21f64e6d79420dc4c56c1907df22akschulz if (DEBUG) Log.d(TAG, "onReceive: " + action); 100670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 100770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 100870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothAdapter.ERROR); 100970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (state == BluetoothAdapter.STATE_TURNING_OFF) { 1010326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF"); 1011326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendShutdownMessage(); 101270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else if (state == BluetoothAdapter.STATE_ON) { 101370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "STATE_ON"); 1014bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde // start ServerSocket listener threads 1015bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde sendStartListenerMessage(-1); 101670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1017bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 1018326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde }else if (action.equals(USER_CONFIRM_TIMEOUT_ACTION)){ 1019326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (DEBUG) Log.d(TAG, "USER_CONFIRM_TIMEOUT ACTION Received."); 1020326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // send us self a message about the timeout. 1021326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendConnectTimeoutMessage(); 1022bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 102370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) { 1024bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 102570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz int requestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 102670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS); 1027bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde 102870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (DEBUG) Log.d(TAG, "Received ACTION_CONNECTION_ACCESS_REPLY:" + 1029326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde requestType + "isWaitingAuthorization:" + mIsWaitingAuthorization); 1030fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if ((!mIsWaitingAuthorization) 1031fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee || (requestType != BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS)) { 103270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz // this reply is not for us 103370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return; 103470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 103570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 1036326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = false; 1037326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if (mRemoveTimeoutMsg) { 103843b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta mSessionStatusHandler.removeMessages(USER_TIMEOUT); 1039326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde cancelUserTimeoutAlarm(); 1040326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde setState(BluetoothMap.STATE_DISCONNECTED); 104143b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta } 104270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 104370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (intent.getIntExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT, 1044fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.CONNECTION_ACCESS_NO) 1045fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee == BluetoothDevice.CONNECTION_ACCESS_YES) { 1046326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Bluetooth connection accepted by user 1047fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mPermission = BluetoothDevice.ACCESS_ALLOWED; 104870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { 1049fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean result = mRemoteDevice.setMessageAccessPermission( 1050fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.ACCESS_ALLOWED); 1051fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (DEBUG) { 1052fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.d(TAG, "setMessageAccessPermission(ACCESS_ALLOWED) result=" 1053fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + result); 1054fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 105570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 10565a60e47497f21f64e6d79420dc4c56c1907df22akschulz 1057bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mRemoteDevice.sdpSearch(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS); 1058bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mSdpSearchInitiated = true; 105970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } else { 1060326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // Auth. declined by user, serverSession should not be running, but 1061326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // call stop anyway to restart listener. 1062fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee mPermission = BluetoothDevice.ACCESS_REJECTED; 1063fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (intent.getBooleanExtra(BluetoothDevice.EXTRA_ALWAYS_ALLOWED, false)) { 1064fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee boolean result = mRemoteDevice.setMessageAccessPermission( 1065fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee BluetoothDevice.ACCESS_REJECTED); 1066fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee if (DEBUG) { 1067fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee Log.d(TAG, "setMessageAccessPermission(ACCESS_REJECTED) result=" 1068fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee + result); 1069fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 1070fc9bed1b79edf77082f5baa21aa68d791a102ea4Edward Jee } 1071326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde sendConnectCancelMessage(); 1072326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1073fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } else if (action.equals(BluetoothDevice.ACTION_SDP_RECORD)) { 1074fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (DEBUG) Log.d(TAG, "Received ACTION_SDP_RECORD."); 1075bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde ParcelUuid uuid = intent.getParcelableExtra(BluetoothDevice.EXTRA_UUID); 1076f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) { 1077f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, "Received UUID: " + uuid.toString()); 1078f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, "expected UUID: " + 1079f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS.toString()); 1080f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde } 1081fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (uuid.equals(BluetoothMnsObexClient.BLUETOOTH_UUID_OBEX_MNS)) { 1082bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mMnsRecord = intent.getParcelableExtra(BluetoothDevice.EXTRA_SDP_RECORD); 1083bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde int status = intent.getIntExtra(BluetoothDevice.EXTRA_SDP_SEARCH_STATUS, -1); 1084f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) { 1085f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, " -> MNS Record:" + mMnsRecord); 1086f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde Log.v(TAG, " -> status: " + status); 1087f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde } 1088fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (mBluetoothMnsObexClient != null && !mSdpSearchInitiated) { 1089fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala mBluetoothMnsObexClient.setMnsRecord(mMnsRecord); 1090fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 1091fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (status != -1 && mMnsRecord != null) { 1092fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala for (int i = 0, c = mMasInstances.size(); i < c; i++) { 1093bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mMasInstances.valueAt(i).setRemoteFeatureMask( 1094bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mMnsRecord.getSupportedFeatures()); 1095bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 1096bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 1097fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala if (mSdpSearchInitiated) { 1098fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala mSdpSearchInitiated = false; // done searching 1099fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala sendConnectMessage(-1); // -1 indicates all MAS instances 1100fc8dfd1e037cda063919d9160c9cdb604b9adfefAshwini Munigala } 1101bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde } 11025a60e47497f21f64e6d79420dc4c56c1907df22akschulz } else if (action.equals(ACTION_SHOW_MAPS_SETTINGS)) { 1103f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "Received ACTION_SHOW_MAPS_SETTINGS."); 1104326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde 11055a60e47497f21f64e6d79420dc4c56c1907df22akschulz Intent in = new Intent(context, BluetoothMapSettings.class); 1106326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); 1107326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde context.startActivity(in); 1108326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } else if (action.equals(BluetoothMapContentObserver.ACTION_MESSAGE_SENT)) { 1109326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde BluetoothMapMasInstance masInst = null; 1110326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde int result = getResultCode(); 1111326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde boolean handled = false; 11124d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi if(mSmsCapable && mMasInstances != null && 11134d2c98fcf1abc4b07dc2d4601952f30f5d008470rongbo.x.chi (masInst = mMasInstances.get(MAS_ID_SMS_MMS)) != null) { 1114326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde intent.putExtra(BluetoothMapContentObserver.EXTRA_MESSAGE_SENT_RESULT, result); 1115326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(masInst.handleSmsSendIntent(context, intent)) { 1116326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde // The intent was handled by the mas instance it self 1117326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde handled = true; 1118326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1119326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1120326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde if(handled == false) 1121326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde { 1122326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde /* We do not have a connection to a device, hence we need to move 1123326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde the SMS to the correct folder. */ 112460e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen try { 112560e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen BluetoothMapContentObserver 1126bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde .actionMessageSentDisconnected(context, intent, result); 112760e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen } catch(IllegalArgumentException e) { 112860e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen return; 112960e306ba5c132d5408ccae3a290e7cace020a49fSeven Shen } 113070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 113143b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) && 1132326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization) { 113343b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 113443b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 113543b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta if (mRemoteDevice == null || device == null) { 113643b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta Log.e(TAG, "Unexpected error!"); 113743b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta return; 113843b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta } 113943b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 1140f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG,"ACL disconnected for " + device); 114143b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 1142f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (mRemoteDevice.equals(device)) { 114343b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta // Send any pending timeout now, as ACL got disconnected. 114443b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta mSessionStatusHandler.removeMessages(USER_TIMEOUT); 114543b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta 114643b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta Intent timeoutIntent = 114743b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL); 114843b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta timeoutIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice); 114943b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta timeoutIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE, 115043b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta BluetoothDevice.REQUEST_TYPE_MESSAGE_ACCESS); 115143b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta sendBroadcast(timeoutIntent, BLUETOOTH_PERM); 1152326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde mIsWaitingAuthorization = false; 1153f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde cancelUserTimeoutAlarm(); 1154f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde mSessionStatusHandler.obtainMessage(MSG_SERVERSESSION_CLOSE, -1, 0) 1155f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde .sendToTarget(); 115643b941ed67f10876a3d730cc095ddb6589e9c1b6Hemant Gupta } 115770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 115870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 115970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz }; 116070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 116170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz //Binder object: Must be static class or memory leak may occur 116270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz /** 116370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * This class implements the IBluetoothMap interface - or actually it validates the 116470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz * preconditions for calling the actual functionality in the MapService, and calls it. 116570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz */ 116670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private static class BluetoothMapBinder extends IBluetoothMap.Stub 116770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz implements IProfileServiceBinder { 116870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private BluetoothMapService mService; 116970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 117070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz private BluetoothMapService getService() { 1171fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie if (!Utils.checkCaller()) { 117270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz Log.w(TAG,"MAP call not allowed for non-active user"); 1173fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return null; 1174fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1175fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 117670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (mService != null && mService.isAvailable()) { 1177bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde mService.enforceCallingOrSelfPermission(BLUETOOTH_PERM,"Need BLUETOOTH permission"); 117870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return mService; 1179fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 118070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return null; 1181fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1182fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 118370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapBinder(BluetoothMapService service) { 118470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "BluetoothMapBinder()"); 118570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz mService = service; 118670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1187fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 118870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean cleanup() { 118970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz mService = null; 119070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return true; 1191fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1192fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 119370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public int getState() { 119470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "getState()"); 119570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 119670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return BluetoothMap.STATE_DISCONNECTED; 119770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return getService().getState(); 119870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 119970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 120070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public BluetoothDevice getClient() { 120170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "getClient()"); 120270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 120370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return null; 1204f48c0b98b5d1823fbb0fc3e4eba7d5054d9385faCasper Bonde if (VERBOSE) Log.v(TAG, "getClient() - returning " + service.getRemoteDevice()); 120570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.getRemoteDevice(); 120670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 120770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 120870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean isConnected(BluetoothDevice device) { 120970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "isConnected()"); 121070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 121170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return false; 1212bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde return service.getState() == BluetoothMap.STATE_CONNECTED 1213bbb4110b455b3aa29106d5b4f0a37e1be8e09475Casper Bonde && service.getRemoteDevice().equals(device); 121470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1215fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 121670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean connect(BluetoothDevice device) { 121770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "connect()"); 121870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 121970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return false; 1220fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie return false; 1221fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1222fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 122370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean disconnect(BluetoothDevice device) { 122470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "disconnect()"); 122570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 122670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return false; 122770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.disconnect(device); 122870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1229fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 123070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public List<BluetoothDevice> getConnectedDevices() { 123170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "getConnectedDevices()"); 123270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 123370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return new ArrayList<BluetoothDevice>(0); 123470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.getConnectedDevices(); 123570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 1236fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie 123770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { 123870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "getDevicesMatchingConnectionStates()"); 123970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 124070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return new ArrayList<BluetoothDevice>(0); 124170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.getDevicesMatchingConnectionStates(states); 124270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 124370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 124470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public int getConnectionState(BluetoothDevice device) { 124570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (VERBOSE) Log.v(TAG, "getConnectionState()"); 124670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 124770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return BluetoothProfile.STATE_DISCONNECTED; 124870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.getConnectionState(device); 124970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 125070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 125170be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public boolean setPriority(BluetoothDevice device, int priority) { 125270be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 125370be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return false; 125470be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.setPriority(device, priority); 125570be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz } 125670be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz 125770be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz public int getPriority(BluetoothDevice device) { 125870be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz BluetoothMapService service = getService(); 125970be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz if (service == null) return BluetoothProfile.PRIORITY_UNDEFINED; 126070be005a18a35ec5fcb46152f0dfbe82156efa3aKim Schulz return service.getPriority(device); 1261fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie } 1262326b5e610063ac24c0ba467ac585bd4c7f618a67Casper Bonde } 1263838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood 1264838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood @Override 1265838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood public void dump(StringBuilder sb) { 1266838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood super.dump(sb); 1267838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mRemoteDevice: " + mRemoteDevice); 1268838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "sRemoteDeviceName: " + sRemoteDeviceName); 1269838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mState: " + mState); 1270838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mAppObserver: " + mAppObserver); 1271838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mIsWaitingAuthorization: " + mIsWaitingAuthorization); 1272838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mRemoveTimeoutMsg: " + mRemoveTimeoutMsg); 1273838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mPermission: " + mPermission); 1274838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mAccountChanged: " + mAccountChanged); 1275838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mBluetoothMnsObexClient: " + mBluetoothMnsObexClient); 1276838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mMasInstanceMap:"); 12775a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (BluetoothMapAccountItem key : mMasInstanceMap.keySet()) { 1278838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, " " + key + " : " + mMasInstanceMap.get(key)); 1279838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 1280838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, "mEnabledAccounts:"); 12815a60e47497f21f64e6d79420dc4c56c1907df22akschulz for (BluetoothMapAccountItem account : mEnabledAccounts) { 1282838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood println(sb, " " + account); 1283838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 1284838949d46a4cc054985a8cfd682004f8dd6d3bbbMike Lockwood } 1285fd6603b8bf9ed72dcc8bd59aaef3209251b6e17cMatthew Xie} 1286