AdapterService.java revision 75b64427d7ba22d0f1ca3049eb6dd4686f5f57c5
15e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux/* 25e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * Copyright (C) 2012 The Android Open Source Project 35e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * 45e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * Licensed under the Apache License, Version 2.0 (the "License"); 55e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * you may not use this file except in compliance with the License. 65e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * You may obtain a copy of the License at 75e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * 85e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * http://www.apache.org/licenses/LICENSE-2.0 95e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * 105e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * Unless required by applicable law or agreed to in writing, software 115e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * distributed under the License is distributed on an "AS IS" BASIS, 125e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * See the License for the specific language governing permissions and 145e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux * limitations under the License. 155e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux */ 165e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 175e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuxpackage com.android.bluetooth.btservice; 185e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 19ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieuximport android.app.ActivityManager; 205e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.app.AlarmManager; 215e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.app.PendingIntent; 225e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.app.Service; 234e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.bluetooth.BluetoothActivityEnergyInfo; 245e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.BluetoothAdapter; 255e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.BluetoothClass; 265e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.BluetoothDevice; 275e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.BluetoothProfile; 285e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.IBluetooth; 295e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.IBluetoothCallback; 305e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.IBluetoothSocketManager; 315e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.OobData; 325e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.bluetooth.UidTraffic; 335e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.content.BroadcastReceiver; 345e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.content.Context; 35ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieuximport android.content.Intent; 36ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieuximport android.content.IntentFilter; 375e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.content.SharedPreferences; 385e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.content.pm.PackageManager; 395e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.AsyncTask; 404e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.BatteryStats; 414e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.Binder; 424e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.Bundle; 434e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.Handler; 444e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.IBinder; 454e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.Looper; 465e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.Message; 475e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.ParcelUuid; 485e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.PowerManager; 49ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieuximport android.os.Process; 50ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieuximport android.os.RemoteCallbackList; 514e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.RemoteException; 525e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.ResultReceiver; 535e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.os.ServiceManager; 544e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.SystemClock; 554e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.UserHandle; 564e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.os.UserManager; 574e7ee09e878178873241846757b178535da3dd76James Lemieuximport android.provider.Settings; 585e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.text.TextUtils; 595e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.util.Base64; 605e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.util.Log; 615e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.util.Slog; 625e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport android.util.SparseArray; 635e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 645e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.bluetooth.Utils; 655e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.bluetooth.btservice.RemoteDevices.DeviceProperties; 665e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.bluetooth.gatt.GattService; 675e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.bluetooth.sdp.SdpManager; 685e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.internal.R; 695e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.internal.annotations.VisibleForTesting; 705e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.android.internal.app.IBatteryStats; 715e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 725e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport com.google.protobuf.micro.InvalidProtocolBufferMicroException; 735e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 745e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.io.FileDescriptor; 755e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.io.FileOutputStream; 765e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.io.IOException; 775e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.io.PrintWriter; 785e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.util.ArrayList; 795e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuximport java.util.Arrays; 80a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieuximport java.util.HashMap; 81a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux 825e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieuxpublic class AdapterService extends Service { 83a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private static final String TAG = "BluetoothAdapterService"; 84a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private static final boolean DBG = true; 855e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static final boolean VERBOSE = false; 865e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static final int MIN_ADVT_INSTANCES_FOR_MA = 5; 875e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static final int MIN_OFFLOADED_FILTERS = 10; 88a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private static final int MIN_OFFLOADED_SCAN_STORAGE_BYTES = 1024; 89a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux 905e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private final Object mEnergyInfoLock = new Object(); 91a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private int mStackReportedState; 92a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private long mTxTimeTotalMs; 93a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private long mRxTimeTotalMs; 94a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private long mIdleTimeTotalMs; 95a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private long mEnergyUsedTotalVoltAmpSecMicro; 96a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private final SparseArray<UidTraffic> mUidTraffic = new SparseArray<>(); 97a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux 98a0a870f57847639d3e28ea72ba7a6f45c1e1af90James Lemieux private final ArrayList<ProfileService> mRegisteredProfiles = new ArrayList<>(); 995e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private final ArrayList<ProfileService> mRunningProfiles = new ArrayList<>(); 1005e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 1015e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux public static final String ACTION_LOAD_ADAPTER_PROPERTIES = 1025e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux "com.android.bluetooth.btservice.action.LOAD_ADAPTER_PROPERTIES"; 1035e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux public static final String ACTION_SERVICE_STATE_CHANGED = 1045e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux "com.android.bluetooth.btservice.action.STATE_CHANGED"; 1055e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux public static final String EXTRA_ACTION = "action"; 106ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieux public static final int PROFILE_CONN_REJECTED = 2; 1075e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 1085e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static final String ACTION_ALARM_WAKEUP = 1095e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux "com.android.bluetooth.btservice.action.ALARM_WAKEUP"; 1105e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 1115e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux public static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN; 1125e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux public static final String BLUETOOTH_PRIVILEGED = 1135e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux android.Manifest.permission.BLUETOOTH_PRIVILEGED; 1145e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH; 1155e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux static final String LOCAL_MAC_ADDRESS_PERM = android.Manifest.permission.LOCAL_MAC_ADDRESS; 1165e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux static final String RECEIVE_MAP_PERM = android.Manifest.permission.RECEIVE_BLUETOOTH_MAP; 1175e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 118ff62e7fa903e3b6b11d0443543725c1351ab289dJames Lemieux private static final String PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE = 1195e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux "phonebook_access_permission"; 1204e7ee09e878178873241846757b178535da3dd76James Lemieux private static final String MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE = 1215e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux "message_access_permission"; 1225e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static final String SIM_ACCESS_PERMISSION_PREFERENCE_FILE = "sim_access_permission"; 1235e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 1244e7ee09e878178873241846757b178535da3dd76James Lemieux private static final String[] DEVICE_TYPE_NAMES = new String[]{ 1254e7ee09e878178873241846757b178535da3dd76James Lemieux "???", "BR/EDR", "LE", "DUAL" 1264e7ee09e878178873241846757b178535da3dd76James Lemieux }; 1274e7ee09e878178873241846757b178535da3dd76James Lemieux 1284e7ee09e878178873241846757b178535da3dd76James Lemieux private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30; 1294e7ee09e878178873241846757b178535da3dd76James Lemieux 1304e7ee09e878178873241846757b178535da3dd76James Lemieux static { 1314e7ee09e878178873241846757b178535da3dd76James Lemieux classInitNative(); 1325e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux } 1335e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux 1345e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private static AdapterService sAdapterService; 1354e7ee09e878178873241846757b178535da3dd76James Lemieux 1364e7ee09e878178873241846757b178535da3dd76James Lemieux public static synchronized AdapterService getAdapterService() { 1374e7ee09e878178873241846757b178535da3dd76James Lemieux Log.d(TAG, "getAdapterService() - returning " + sAdapterService); 1384e7ee09e878178873241846757b178535da3dd76James Lemieux return sAdapterService; 1394e7ee09e878178873241846757b178535da3dd76James Lemieux } 1404e7ee09e878178873241846757b178535da3dd76James Lemieux 1414e7ee09e878178873241846757b178535da3dd76James Lemieux private static synchronized void setAdapterService(AdapterService instance) { 1424e7ee09e878178873241846757b178535da3dd76James Lemieux Log.d(TAG, "setAdapterService() - trying to set service to " + instance); 1434e7ee09e878178873241846757b178535da3dd76James Lemieux if (instance == null) { 1444e7ee09e878178873241846757b178535da3dd76James Lemieux return; 1454e7ee09e878178873241846757b178535da3dd76James Lemieux } 1464e7ee09e878178873241846757b178535da3dd76James Lemieux sAdapterService = instance; 1474e7ee09e878178873241846757b178535da3dd76James Lemieux } 1484e7ee09e878178873241846757b178535da3dd76James Lemieux 1494e7ee09e878178873241846757b178535da3dd76James Lemieux private static synchronized void clearAdapterService(AdapterService current) { 1504e7ee09e878178873241846757b178535da3dd76James Lemieux if (sAdapterService == current) { 1514e7ee09e878178873241846757b178535da3dd76James Lemieux sAdapterService = null; 1524e7ee09e878178873241846757b178535da3dd76James Lemieux } 1534e7ee09e878178873241846757b178535da3dd76James Lemieux } 1544e7ee09e878178873241846757b178535da3dd76James Lemieux 1554e7ee09e878178873241846757b178535da3dd76James Lemieux private AdapterProperties mAdapterProperties; 1564e7ee09e878178873241846757b178535da3dd76James Lemieux private AdapterState mAdapterStateMachine; 1574e7ee09e878178873241846757b178535da3dd76James Lemieux private BondStateMachine mBondStateMachine; 1584e7ee09e878178873241846757b178535da3dd76James Lemieux private JniCallbacks mJniCallbacks; 1594e7ee09e878178873241846757b178535da3dd76James Lemieux private RemoteDevices mRemoteDevices; 1604e7ee09e878178873241846757b178535da3dd76James Lemieux 1614e7ee09e878178873241846757b178535da3dd76James Lemieux /* TODO: Consider to remove the search API from this class, if changed to use call-back */ 1624e7ee09e878178873241846757b178535da3dd76James Lemieux private SdpManager mSdpManager = null; 1634e7ee09e878178873241846757b178535da3dd76James Lemieux 1644e7ee09e878178873241846757b178535da3dd76James Lemieux private boolean mNativeAvailable; 1654e7ee09e878178873241846757b178535da3dd76James Lemieux private boolean mCleaningUp; 1664e7ee09e878178873241846757b178535da3dd76James Lemieux private final HashMap<String, Integer> mProfileServicesState = new HashMap<String, Integer>(); 1674e7ee09e878178873241846757b178535da3dd76James Lemieux //Only BluetoothManagerService should be registered 1684e7ee09e878178873241846757b178535da3dd76James Lemieux private RemoteCallbackList<IBluetoothCallback> mCallbacks; 1694e7ee09e878178873241846757b178535da3dd76James Lemieux private int mCurrentRequestId; 1704e7ee09e878178873241846757b178535da3dd76James Lemieux private boolean mQuietmode = false; 1714e7ee09e878178873241846757b178535da3dd76James Lemieux 1724e7ee09e878178873241846757b178535da3dd76James Lemieux private AlarmManager mAlarmManager; 1734e7ee09e878178873241846757b178535da3dd76James Lemieux private PendingIntent mPendingAlarm; 1744e7ee09e878178873241846757b178535da3dd76James Lemieux private IBatteryStats mBatteryStats; 1754e7ee09e878178873241846757b178535da3dd76James Lemieux private PowerManager mPowerManager; 1764e7ee09e878178873241846757b178535da3dd76James Lemieux private PowerManager.WakeLock mWakeLock; 1775e0c5c4846f73565bf07542f64bea8208002f55cJames Lemieux private String mWakeLockName; 178 private UserManager mUserManager; 179 180 private ProfileObserver mProfileObserver; 181 private PhonePolicy mPhonePolicy; 182 private ActiveDeviceManager mActiveDeviceManager; 183 184 /** 185 * Register a {@link ProfileService} with AdapterService. 186 * 187 * @param profile the service being added. 188 */ 189 public void addProfile(ProfileService profile) { 190 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_REGISTERED, profile); 191 mHandler.sendMessage(m); 192 } 193 194 /** 195 * Unregister a ProfileService with AdapterService. 196 * 197 * @param profile the service being removed. 198 */ 199 public void removeProfile(ProfileService profile) { 200 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_UNREGISTERED, profile); 201 mHandler.sendMessage(m); 202 } 203 204 /** 205 * Notify AdapterService that a ProfileService has started or stopped. 206 * 207 * @param profile the service being removed. 208 * @param state {@link BluetoothAdapter#STATE_ON} or {@link BluetoothAdapter#STATE_OFF} 209 */ 210 public void onProfileServiceStateChanged(ProfileService profile, int state) { 211 if (state != BluetoothAdapter.STATE_ON && state != BluetoothAdapter.STATE_OFF) { 212 throw new IllegalArgumentException(BluetoothAdapter.nameForState(state)); 213 } 214 Message m = mHandler.obtainMessage(MESSAGE_PROFILE_SERVICE_STATE_CHANGED); 215 m.obj = profile; 216 m.arg1 = state; 217 mHandler.sendMessage(m); 218 } 219 220 private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1; 221 private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2; 222 private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3; 223 224 class AdapterServiceHandler extends Handler { 225 @Override 226 public void handleMessage(Message msg) { 227 debugLog("handleMessage() - Message: " + msg.what); 228 229 switch (msg.what) { 230 case MESSAGE_PROFILE_SERVICE_STATE_CHANGED: 231 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED"); 232 processProfileServiceStateChanged((ProfileService) msg.obj, msg.arg1); 233 break; 234 case MESSAGE_PROFILE_SERVICE_REGISTERED: 235 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED"); 236 registerProfileService((ProfileService) msg.obj); 237 break; 238 case MESSAGE_PROFILE_SERVICE_UNREGISTERED: 239 debugLog("handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED"); 240 unregisterProfileService((ProfileService) msg.obj); 241 break; 242 } 243 } 244 245 private void registerProfileService(ProfileService profile) { 246 if (mRegisteredProfiles.contains(profile)) { 247 Log.e(TAG, profile.getName() + " already registered."); 248 return; 249 } 250 mRegisteredProfiles.add(profile); 251 } 252 253 private void unregisterProfileService(ProfileService profile) { 254 if (!mRegisteredProfiles.contains(profile)) { 255 Log.e(TAG, profile.getName() + " not registered (UNREGISTERED)."); 256 return; 257 } 258 mRegisteredProfiles.remove(profile); 259 } 260 261 private void processProfileServiceStateChanged(ProfileService profile, int state) { 262 switch (state) { 263 case BluetoothAdapter.STATE_ON: 264 if (!mRegisteredProfiles.contains(profile)) { 265 Log.e(TAG, profile.getName() + " not registered (STATE_ON)."); 266 return; 267 } 268 if (mRunningProfiles.contains(profile)) { 269 Log.e(TAG, profile.getName() + " already running."); 270 return; 271 } 272 mRunningProfiles.add(profile); 273 if (GattService.class.getSimpleName().equals(profile.getName())) { 274 mAdapterStateMachine.sendMessage( 275 mAdapterStateMachine.obtainMessage(AdapterState.BLE_STARTED)); 276 } 277 if (mRegisteredProfiles.size() == Config.getSupportedProfiles().length 278 && mRegisteredProfiles.size() == mRunningProfiles.size()) { 279 mAdapterStateMachine.sendMessage( 280 mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STARTED)); 281 } 282 break; 283 case BluetoothAdapter.STATE_OFF: 284 if (!mRegisteredProfiles.contains(profile)) { 285 Log.e(TAG, profile.getName() + " not registered (STATE_OFF)."); 286 return; 287 } 288 if (!mRunningProfiles.contains(profile)) { 289 Log.e(TAG, profile.getName() + " not running."); 290 return; 291 } 292 mRunningProfiles.remove(profile); 293 // If the last profile was removed, or only GATT is left, send BREDR_STOPPED. 294 if ((mRunningProfiles.size() == 0) || (mRunningProfiles.size() == 1 295 && (GattService.class.getSimpleName() 296 .equals(mRunningProfiles.get(0).getName())))) { 297 mAdapterStateMachine.sendMessage( 298 mAdapterStateMachine.obtainMessage(AdapterState.BREDR_STOPPED)); 299 } 300 if (mRunningProfiles.size() == 0) { 301 mAdapterStateMachine.sendMessage( 302 mAdapterStateMachine.obtainMessage(AdapterState.BLE_STOPPED)); 303 } 304 break; 305 default: 306 Log.e(TAG, "Unhandled profile state: " + state); 307 } 308 } 309 } 310 311 private final AdapterServiceHandler mHandler = new AdapterServiceHandler(); 312 313 private void updateInteropDatabase() { 314 interopDatabaseClearNative(); 315 316 String interopString = Settings.Global.getString(getContentResolver(), 317 Settings.Global.BLUETOOTH_INTEROPERABILITY_LIST); 318 if (interopString == null) { 319 return; 320 } 321 Log.d(TAG, "updateInteropDatabase: [" + interopString + "]"); 322 323 String[] entries = interopString.split(";"); 324 for (String entry : entries) { 325 String[] tokens = entry.split(","); 326 if (tokens.length != 2) { 327 continue; 328 } 329 330 // Get feature 331 int feature = 0; 332 try { 333 feature = Integer.parseInt(tokens[1]); 334 } catch (NumberFormatException e) { 335 Log.e(TAG, "updateInteropDatabase: Invalid feature '" + tokens[1] + "'"); 336 continue; 337 } 338 339 // Get address bytes and length 340 int length = (tokens[0].length() + 1) / 3; 341 if (length < 1 || length > 6) { 342 Log.e(TAG, "updateInteropDatabase: Malformed address string '" + tokens[0] + "'"); 343 continue; 344 } 345 346 byte[] addr = new byte[6]; 347 int offset = 0; 348 for (int i = 0; i < tokens[0].length(); ) { 349 if (tokens[0].charAt(i) == ':') { 350 i += 1; 351 } else { 352 try { 353 addr[offset++] = (byte) Integer.parseInt(tokens[0].substring(i, i + 2), 16); 354 } catch (NumberFormatException e) { 355 offset = 0; 356 break; 357 } 358 i += 2; 359 } 360 } 361 362 // Check if address was parsed ok, otherwise, move on... 363 if (offset == 0) { 364 continue; 365 } 366 367 // Add entry 368 interopDatabaseAddNative(feature, addr, length); 369 } 370 } 371 372 @Override 373 public void onCreate() { 374 super.onCreate(); 375 debugLog("onCreate()"); 376 mRemoteDevices = new RemoteDevices(this, Looper.getMainLooper()); 377 mRemoteDevices.init(); 378 mBinder = new AdapterServiceBinder(this); 379 mAdapterProperties = new AdapterProperties(this); 380 mAdapterStateMachine = AdapterState.make(this, mAdapterProperties); 381 mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties); 382 initNative(); 383 mNativeAvailable = true; 384 mCallbacks = new RemoteCallbackList<IBluetoothCallback>(); 385 //Load the name and address 386 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR); 387 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME); 388 getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_CLASS_OF_DEVICE); 389 mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 390 mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); 391 mUserManager = (UserManager) getSystemService(Context.USER_SERVICE); 392 mBatteryStats = IBatteryStats.Stub.asInterface( 393 ServiceManager.getService(BatteryStats.SERVICE_NAME)); 394 395 mSdpManager = SdpManager.init(this); 396 registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP)); 397 mProfileObserver = new ProfileObserver(getApplicationContext(), this, new Handler()); 398 mProfileObserver.start(); 399 400 // Phone policy is specific to phone implementations and hence if a device wants to exclude 401 // it out then it can be disabled by using the flag below. 402 if (getResources().getBoolean(com.android.bluetooth.R.bool.enable_phone_policy)) { 403 Log.i(TAG, "Phone policy enabled"); 404 mPhonePolicy = new PhonePolicy(this, new ServiceFactory()); 405 mPhonePolicy.start(); 406 } else { 407 Log.i(TAG, "Phone policy disabled"); 408 } 409 410 mActiveDeviceManager = new ActiveDeviceManager(this, new ServiceFactory()); 411 mActiveDeviceManager.start(); 412 413 setAdapterService(this); 414 415 // First call to getSharedPreferences will result in a file read into 416 // memory cache. Call it here asynchronously to avoid potential ANR 417 // in the future 418 new AsyncTask<Void, Void, Void>() { 419 @Override 420 protected Void doInBackground(Void... params) { 421 getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 422 Context.MODE_PRIVATE); 423 getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 424 Context.MODE_PRIVATE); 425 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE); 426 return null; 427 } 428 }.execute(); 429 430 try { 431 int systemUiUid = getApplicationContext().getPackageManager().getPackageUidAsUser( 432 "com.android.systemui", PackageManager.MATCH_SYSTEM_ONLY, 433 UserHandle.USER_SYSTEM); 434 Utils.setSystemUiUid(systemUiUid); 435 setSystemUiUidNative(systemUiUid); 436 } catch (PackageManager.NameNotFoundException e) { 437 // Some platforms, such as wearables do not have a system ui. 438 Log.w(TAG, "Unable to resolve SystemUI's UID.", e); 439 } 440 441 IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 442 getApplicationContext().registerReceiverAsUser(sUserSwitchedReceiver, UserHandle.ALL, 443 filter, null, null); 444 int fuid = ActivityManager.getCurrentUser(); 445 Utils.setForegroundUserId(fuid); 446 setForegroundUserIdNative(fuid); 447 } 448 449 @Override 450 public IBinder onBind(Intent intent) { 451 debugLog("onBind()"); 452 return mBinder; 453 } 454 455 @Override 456 public boolean onUnbind(Intent intent) { 457 debugLog("onUnbind() - calling cleanup"); 458 cleanup(); 459 return super.onUnbind(intent); 460 } 461 462 @Override 463 public void onDestroy() { 464 debugLog("onDestroy()"); 465 mProfileObserver.stop(); 466 if (!isMock()) { 467 // TODO(b/27859763) 468 Log.i(TAG, "Force exit to cleanup internal state in Bluetooth stack"); 469 System.exit(0); 470 } 471 } 472 473 public static final BroadcastReceiver sUserSwitchedReceiver = new BroadcastReceiver() { 474 @Override 475 public void onReceive(Context context, Intent intent) { 476 if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) { 477 int fuid = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); 478 Utils.setForegroundUserId(fuid); 479 setForegroundUserIdNative(fuid); 480 } 481 } 482 }; 483 484 void bleOnProcessStart() { 485 debugLog("bleOnProcessStart()"); 486 487 if (getResources().getBoolean( 488 R.bool.config_bluetooth_reload_supported_profiles_when_enabled)) { 489 Config.init(getApplicationContext()); 490 } 491 492 // Reset |mRemoteDevices| whenever BLE is turned off then on 493 // This is to replace the fact that |mRemoteDevices| was 494 // reinitialized in previous code. 495 // 496 // TODO(apanicke): The reason is unclear but 497 // I believe it is to clear the variable every time BLE was 498 // turned off then on. The same effect can be achieved by 499 // calling cleanup but this may not be necessary at all 500 // We should figure out why this is needed later 501 mRemoteDevices.reset(); 502 mAdapterProperties.init(mRemoteDevices); 503 504 debugLog("bleOnProcessStart() - Make Bond State Machine"); 505 mBondStateMachine = BondStateMachine.make(this, mAdapterProperties, mRemoteDevices); 506 507 mJniCallbacks.init(mBondStateMachine, mRemoteDevices); 508 509 try { 510 mBatteryStats.noteResetBleScan(); 511 } catch (RemoteException e) { 512 Log.w(TAG, "RemoteException trying to send a reset to BatteryStats"); 513 } 514 515 //Start Gatt service 516 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_ON); 517 } 518 519 /** 520 * Sets the Bluetooth CoD value of the local adapter if there exists a config value for it. 521 */ 522 void setBluetoothClassFromConfig() { 523 int bluetoothClassConfig = retrieveBluetoothClassConfig(); 524 if (bluetoothClassConfig != 0) { 525 mAdapterProperties.setBluetoothClass(new BluetoothClass(bluetoothClassConfig)); 526 } 527 } 528 529 private int retrieveBluetoothClassConfig() { 530 return Settings.Global.getInt( 531 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, 0); 532 } 533 534 private boolean storeBluetoothClassConfig(int bluetoothClass) { 535 boolean result = Settings.Global.putInt( 536 getContentResolver(), Settings.Global.BLUETOOTH_CLASS_OF_DEVICE, bluetoothClass); 537 538 if (!result) { 539 Log.e(TAG, "Error storing BluetoothClass config - " + bluetoothClass); 540 } 541 542 return result; 543 } 544 545 void startCoreServices() { 546 debugLog("startCoreServices()"); 547 Class[] supportedProfileServices = Config.getSupportedProfiles(); 548 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_ON); 549 } 550 551 void startBluetoothDisable() { 552 mAdapterStateMachine.sendMessage( 553 mAdapterStateMachine.obtainMessage(AdapterState.BEGIN_DISABLE)); 554 } 555 556 void stopProfileServices() { 557 Class[] supportedProfileServices = Config.getSupportedProfiles(); 558 if (mRunningProfiles.size() == 0) { 559 debugLog("stopProfileServices() - No profiles services to stop or already stopped."); 560 return; 561 } 562 setAllProfileServiceStates(supportedProfileServices, BluetoothAdapter.STATE_OFF); 563 } 564 565 boolean stopGattProfileService() { 566 setProfileServiceState(GattService.class, BluetoothAdapter.STATE_OFF); 567 return true; 568 } 569 570 void updateAdapterState(int prevState, int newState) { 571 if (mCallbacks != null) { 572 int n = mCallbacks.beginBroadcast(); 573 debugLog("updateAdapterState() - Broadcasting state " + BluetoothAdapter.nameForState( 574 newState) + " to " + n + " receivers."); 575 for (int i = 0; i < n; i++) { 576 try { 577 mCallbacks.getBroadcastItem(i).onBluetoothStateChange(prevState, newState); 578 } catch (RemoteException e) { 579 debugLog("updateAdapterState() - Callback #" + i + " failed (" + e + ")"); 580 } 581 } 582 mCallbacks.finishBroadcast(); 583 } 584 } 585 586 void cleanup() { 587 debugLog("cleanup()"); 588 if (mCleaningUp) { 589 errorLog("cleanup() - Service already starting to cleanup, ignoring request..."); 590 return; 591 } 592 593 clearAdapterService(this); 594 595 mCleaningUp = true; 596 597 unregisterReceiver(mAlarmBroadcastReceiver); 598 599 if (mPendingAlarm != null) { 600 mAlarmManager.cancel(mPendingAlarm); 601 mPendingAlarm = null; 602 } 603 604 // This wake lock release may also be called concurrently by 605 // {@link #releaseWakeLock(String lockName)}, so a synchronization is needed here. 606 synchronized (this) { 607 if (mWakeLock != null) { 608 if (mWakeLock.isHeld()) { 609 mWakeLock.release(); 610 } 611 mWakeLock = null; 612 } 613 } 614 615 if (mAdapterStateMachine != null) { 616 mAdapterStateMachine.doQuit(); 617 } 618 619 if (mBondStateMachine != null) { 620 mBondStateMachine.doQuit(); 621 } 622 623 if (mRemoteDevices != null) { 624 mRemoteDevices.cleanup(); 625 } 626 627 if (mSdpManager != null) { 628 mSdpManager.cleanup(); 629 mSdpManager = null; 630 } 631 632 if (mNativeAvailable) { 633 debugLog("cleanup() - Cleaning up adapter native"); 634 cleanupNative(); 635 mNativeAvailable = false; 636 } 637 638 if (mAdapterProperties != null) { 639 mAdapterProperties.cleanup(); 640 } 641 642 if (mJniCallbacks != null) { 643 mJniCallbacks.cleanup(); 644 } 645 646 if (mPhonePolicy != null) { 647 mPhonePolicy.cleanup(); 648 } 649 650 if (mActiveDeviceManager != null) { 651 mActiveDeviceManager.cleanup(); 652 } 653 654 if (mProfileServicesState != null) { 655 mProfileServicesState.clear(); 656 } 657 658 if (mBinder != null) { 659 mBinder.cleanup(); 660 mBinder = null; //Do not remove. Otherwise Binder leak! 661 } 662 663 if (mCallbacks != null) { 664 mCallbacks.kill(); 665 } 666 } 667 668 private void setProfileServiceState(Class service, int state) { 669 Intent intent = new Intent(this, service); 670 intent.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED); 671 intent.putExtra(BluetoothAdapter.EXTRA_STATE, state); 672 startService(intent); 673 } 674 675 private void setAllProfileServiceStates(Class[] services, int state) { 676 for (Class service : services) { 677 if (GattService.class.getSimpleName().equals(service.getSimpleName())) { 678 continue; 679 } 680 setProfileServiceState(service, state); 681 } 682 } 683 684 private boolean isAvailable() { 685 return !mCleaningUp; 686 } 687 688 /** 689 * Handlers for incoming service calls 690 */ 691 private AdapterServiceBinder mBinder; 692 693 /** 694 * The Binder implementation must be declared to be a static class, with 695 * the AdapterService instance passed in the constructor. Furthermore, 696 * when the AdapterService shuts down, the reference to the AdapterService 697 * must be explicitly removed. 698 * 699 * Otherwise, a memory leak can occur from repeated starting/stopping the 700 * service...Please refer to android.os.Binder for further details on 701 * why an inner instance class should be avoided. 702 * 703 */ 704 private static class AdapterServiceBinder extends IBluetooth.Stub { 705 private AdapterService mService; 706 707 AdapterServiceBinder(AdapterService svc) { 708 mService = svc; 709 } 710 711 public void cleanup() { 712 mService = null; 713 } 714 715 public AdapterService getService() { 716 if (mService != null && mService.isAvailable()) { 717 return mService; 718 } 719 return null; 720 } 721 722 @Override 723 public boolean isEnabled() { 724 // don't check caller, may be called from system UI 725 AdapterService service = getService(); 726 if (service == null) { 727 return false; 728 } 729 return service.isEnabled(); 730 } 731 732 @Override 733 public int getState() { 734 // don't check caller, may be called from system UI 735 AdapterService service = getService(); 736 if (service == null) { 737 return BluetoothAdapter.STATE_OFF; 738 } 739 return service.getState(); 740 } 741 742 @Override 743 public boolean enable() { 744 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) { 745 Log.w(TAG, "enable() - Not allowed for non-active user and non system user"); 746 return false; 747 } 748 AdapterService service = getService(); 749 if (service == null) { 750 return false; 751 } 752 return service.enable(); 753 } 754 755 @Override 756 public boolean enableNoAutoConnect() { 757 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) { 758 Log.w(TAG, "enableNoAuto() - Not allowed for non-active user and non system user"); 759 return false; 760 } 761 762 AdapterService service = getService(); 763 if (service == null) { 764 return false; 765 } 766 return service.enableNoAutoConnect(); 767 } 768 769 @Override 770 public boolean disable() { 771 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) { 772 Log.w(TAG, "disable() - Not allowed for non-active user and non system user"); 773 return false; 774 } 775 776 AdapterService service = getService(); 777 if (service == null) { 778 return false; 779 } 780 return service.disable(); 781 } 782 783 @Override 784 public String getAddress() { 785 if ((Binder.getCallingUid() != Process.SYSTEM_UID) 786 && (!Utils.checkCallerAllowManagedProfiles(mService))) { 787 Log.w(TAG, "getAddress() - Not allowed for non-active user and non system user"); 788 return null; 789 } 790 791 AdapterService service = getService(); 792 if (service == null) { 793 return null; 794 } 795 return service.getAddress(); 796 } 797 798 @Override 799 public ParcelUuid[] getUuids() { 800 if (!Utils.checkCaller()) { 801 Log.w(TAG, "getUuids() - Not allowed for non-active user"); 802 return new ParcelUuid[0]; 803 } 804 805 AdapterService service = getService(); 806 if (service == null) { 807 return new ParcelUuid[0]; 808 } 809 return service.getUuids(); 810 } 811 812 @Override 813 public String getName() { 814 if ((Binder.getCallingUid() != Process.SYSTEM_UID) && (!Utils.checkCaller())) { 815 Log.w(TAG, "getName() - Not allowed for non-active user and non system user"); 816 return null; 817 } 818 819 AdapterService service = getService(); 820 if (service == null) { 821 return null; 822 } 823 return service.getName(); 824 } 825 826 @Override 827 public boolean setName(String name) { 828 if (!Utils.checkCaller()) { 829 Log.w(TAG, "setName() - Not allowed for non-active user"); 830 return false; 831 } 832 833 AdapterService service = getService(); 834 if (service == null) { 835 return false; 836 } 837 return service.setName(name); 838 } 839 840 public BluetoothClass getBluetoothClass() { 841 if (!Utils.checkCaller()) { 842 Log.w(TAG, "getBluetoothClass() - Not allowed for non-active user"); 843 return null; 844 } 845 846 AdapterService service = getService(); 847 if (service == null) return null; 848 return service.getBluetoothClass(); 849 } 850 851 public boolean setBluetoothClass(BluetoothClass bluetoothClass) { 852 if (!Utils.checkCaller()) { 853 Log.w(TAG, "setBluetoothClass() - Not allowed for non-active user"); 854 return false; 855 } 856 857 AdapterService service = getService(); 858 if (service == null) { 859 return false; 860 } 861 return service.setBluetoothClass(bluetoothClass); 862 } 863 864 @Override 865 public int getScanMode() { 866 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 867 Log.w(TAG, "getScanMode() - Not allowed for non-active user"); 868 return BluetoothAdapter.SCAN_MODE_NONE; 869 } 870 871 AdapterService service = getService(); 872 if (service == null) { 873 return BluetoothAdapter.SCAN_MODE_NONE; 874 } 875 return service.getScanMode(); 876 } 877 878 @Override 879 public boolean setScanMode(int mode, int duration) { 880 if (!Utils.checkCaller()) { 881 Log.w(TAG, "setScanMode() - Not allowed for non-active user"); 882 return false; 883 } 884 885 AdapterService service = getService(); 886 if (service == null) { 887 return false; 888 } 889 return service.setScanMode(mode, duration); 890 } 891 892 @Override 893 public int getDiscoverableTimeout() { 894 if (!Utils.checkCaller()) { 895 Log.w(TAG, "getDiscoverableTimeout() - Not allowed for non-active user"); 896 return 0; 897 } 898 899 AdapterService service = getService(); 900 if (service == null) { 901 return 0; 902 } 903 return service.getDiscoverableTimeout(); 904 } 905 906 @Override 907 public boolean setDiscoverableTimeout(int timeout) { 908 if (!Utils.checkCaller()) { 909 Log.w(TAG, "setDiscoverableTimeout() - Not allowed for non-active user"); 910 return false; 911 } 912 913 AdapterService service = getService(); 914 if (service == null) { 915 return false; 916 } 917 return service.setDiscoverableTimeout(timeout); 918 } 919 920 @Override 921 public boolean startDiscovery() { 922 if (!Utils.checkCaller()) { 923 Log.w(TAG, "startDiscovery() - Not allowed for non-active user"); 924 return false; 925 } 926 927 AdapterService service = getService(); 928 if (service == null) { 929 return false; 930 } 931 return service.startDiscovery(); 932 } 933 934 @Override 935 public boolean cancelDiscovery() { 936 if (!Utils.checkCaller()) { 937 Log.w(TAG, "cancelDiscovery() - Not allowed for non-active user"); 938 return false; 939 } 940 941 AdapterService service = getService(); 942 if (service == null) { 943 return false; 944 } 945 return service.cancelDiscovery(); 946 } 947 948 @Override 949 public boolean isDiscovering() { 950 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 951 Log.w(TAG, "isDiscovering() - Not allowed for non-active user"); 952 return false; 953 } 954 955 AdapterService service = getService(); 956 if (service == null) { 957 return false; 958 } 959 return service.isDiscovering(); 960 } 961 962 @Override 963 public long getDiscoveryEndMillis() { 964 if (!Utils.checkCaller()) { 965 Log.w(TAG, "getDiscoveryEndMillis() - Not allowed for non-active user"); 966 return -1; 967 } 968 969 AdapterService service = getService(); 970 if (service == null) { 971 return -1; 972 } 973 return service.getDiscoveryEndMillis(); 974 } 975 976 @Override 977 public BluetoothDevice[] getBondedDevices() { 978 // don't check caller, may be called from system UI 979 AdapterService service = getService(); 980 if (service == null) { 981 return new BluetoothDevice[0]; 982 } 983 return service.getBondedDevices(); 984 } 985 986 @Override 987 public int getAdapterConnectionState() { 988 // don't check caller, may be called from system UI 989 AdapterService service = getService(); 990 if (service == null) { 991 return BluetoothAdapter.STATE_DISCONNECTED; 992 } 993 return service.getAdapterConnectionState(); 994 } 995 996 @Override 997 public int getProfileConnectionState(int profile) { 998 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 999 Log.w(TAG, "getProfileConnectionState- Not allowed for non-active user"); 1000 return BluetoothProfile.STATE_DISCONNECTED; 1001 } 1002 1003 AdapterService service = getService(); 1004 if (service == null) { 1005 return BluetoothProfile.STATE_DISCONNECTED; 1006 } 1007 return service.getProfileConnectionState(profile); 1008 } 1009 1010 @Override 1011 public boolean createBond(BluetoothDevice device, int transport) { 1012 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1013 Log.w(TAG, "createBond() - Not allowed for non-active user"); 1014 return false; 1015 } 1016 1017 AdapterService service = getService(); 1018 if (service == null) { 1019 return false; 1020 } 1021 return service.createBond(device, transport, null); 1022 } 1023 1024 @Override 1025 public boolean createBondOutOfBand(BluetoothDevice device, int transport, OobData oobData) { 1026 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1027 Log.w(TAG, "createBondOutOfBand() - Not allowed for non-active user"); 1028 return false; 1029 } 1030 1031 AdapterService service = getService(); 1032 if (service == null) { 1033 return false; 1034 } 1035 return service.createBond(device, transport, oobData); 1036 } 1037 1038 @Override 1039 public boolean cancelBondProcess(BluetoothDevice device) { 1040 if (!Utils.checkCaller()) { 1041 Log.w(TAG, "cancelBondProcess() - Not allowed for non-active user"); 1042 return false; 1043 } 1044 1045 AdapterService service = getService(); 1046 if (service == null) { 1047 return false; 1048 } 1049 return service.cancelBondProcess(device); 1050 } 1051 1052 @Override 1053 public boolean removeBond(BluetoothDevice device) { 1054 if (!Utils.checkCaller()) { 1055 Log.w(TAG, "removeBond() - Not allowed for non-active user"); 1056 return false; 1057 } 1058 1059 AdapterService service = getService(); 1060 if (service == null) { 1061 return false; 1062 } 1063 return service.removeBond(device); 1064 } 1065 1066 @Override 1067 public int getBondState(BluetoothDevice device) { 1068 // don't check caller, may be called from system UI 1069 AdapterService service = getService(); 1070 if (service == null) { 1071 return BluetoothDevice.BOND_NONE; 1072 } 1073 return service.getBondState(device); 1074 } 1075 1076 @Override 1077 public boolean isBondingInitiatedLocally(BluetoothDevice device) { 1078 // don't check caller, may be called from system UI 1079 AdapterService service = getService(); 1080 if (service == null) { 1081 return false; 1082 } 1083 return service.isBondingInitiatedLocally(device); 1084 } 1085 1086 @Override 1087 public long getSupportedProfiles() { 1088 AdapterService service = getService(); 1089 if (service == null) { 1090 return 0; 1091 } 1092 return service.getSupportedProfiles(); 1093 } 1094 1095 @Override 1096 public int getConnectionState(BluetoothDevice device) { 1097 AdapterService service = getService(); 1098 if (service == null) { 1099 return 0; 1100 } 1101 return service.getConnectionState(device); 1102 } 1103 1104 @Override 1105 public String getRemoteName(BluetoothDevice device) { 1106 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1107 Log.w(TAG, "getRemoteName() - Not allowed for non-active user"); 1108 return null; 1109 } 1110 1111 AdapterService service = getService(); 1112 if (service == null) { 1113 return null; 1114 } 1115 return service.getRemoteName(device); 1116 } 1117 1118 @Override 1119 public int getRemoteType(BluetoothDevice device) { 1120 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1121 Log.w(TAG, "getRemoteType() - Not allowed for non-active user"); 1122 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1123 } 1124 1125 AdapterService service = getService(); 1126 if (service == null) { 1127 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1128 } 1129 return service.getRemoteType(device); 1130 } 1131 1132 @Override 1133 public String getRemoteAlias(BluetoothDevice device) { 1134 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1135 Log.w(TAG, "getRemoteAlias() - Not allowed for non-active user"); 1136 return null; 1137 } 1138 1139 AdapterService service = getService(); 1140 if (service == null) { 1141 return null; 1142 } 1143 return service.getRemoteAlias(device); 1144 } 1145 1146 @Override 1147 public boolean setRemoteAlias(BluetoothDevice device, String name) { 1148 if (!Utils.checkCaller()) { 1149 Log.w(TAG, "setRemoteAlias() - Not allowed for non-active user"); 1150 return false; 1151 } 1152 1153 AdapterService service = getService(); 1154 if (service == null) { 1155 return false; 1156 } 1157 return service.setRemoteAlias(device, name); 1158 } 1159 1160 @Override 1161 public int getRemoteClass(BluetoothDevice device) { 1162 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1163 Log.w(TAG, "getRemoteClass() - Not allowed for non-active user"); 1164 return 0; 1165 } 1166 1167 AdapterService service = getService(); 1168 if (service == null) { 1169 return 0; 1170 } 1171 return service.getRemoteClass(device); 1172 } 1173 1174 @Override 1175 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1176 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1177 Log.w(TAG, "getRemoteUuids() - Not allowed for non-active user"); 1178 return new ParcelUuid[0]; 1179 } 1180 1181 AdapterService service = getService(); 1182 if (service == null) { 1183 return new ParcelUuid[0]; 1184 } 1185 return service.getRemoteUuids(device); 1186 } 1187 1188 @Override 1189 public boolean fetchRemoteUuids(BluetoothDevice device) { 1190 if (!Utils.checkCallerAllowManagedProfiles(mService)) { 1191 Log.w(TAG, "fetchRemoteUuids() - Not allowed for non-active user"); 1192 return false; 1193 } 1194 1195 AdapterService service = getService(); 1196 if (service == null) { 1197 return false; 1198 } 1199 return service.fetchRemoteUuids(device); 1200 } 1201 1202 1203 @Override 1204 public boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1205 if (!Utils.checkCaller()) { 1206 Log.w(TAG, "setPin() - Not allowed for non-active user"); 1207 return false; 1208 } 1209 1210 AdapterService service = getService(); 1211 if (service == null) { 1212 return false; 1213 } 1214 return service.setPin(device, accept, len, pinCode); 1215 } 1216 1217 @Override 1218 public boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1219 if (!Utils.checkCaller()) { 1220 Log.w(TAG, "setPasskey() - Not allowed for non-active user"); 1221 return false; 1222 } 1223 1224 AdapterService service = getService(); 1225 if (service == null) { 1226 return false; 1227 } 1228 return service.setPasskey(device, accept, len, passkey); 1229 } 1230 1231 @Override 1232 public boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1233 if (!Utils.checkCaller()) { 1234 Log.w(TAG, "setPairingConfirmation() - Not allowed for non-active user"); 1235 return false; 1236 } 1237 1238 AdapterService service = getService(); 1239 if (service == null) { 1240 return false; 1241 } 1242 return service.setPairingConfirmation(device, accept); 1243 } 1244 1245 @Override 1246 public int getPhonebookAccessPermission(BluetoothDevice device) { 1247 if (!Utils.checkCaller()) { 1248 Log.w(TAG, "getPhonebookAccessPermission() - Not allowed for non-active user"); 1249 return BluetoothDevice.ACCESS_UNKNOWN; 1250 } 1251 1252 AdapterService service = getService(); 1253 if (service == null) { 1254 return BluetoothDevice.ACCESS_UNKNOWN; 1255 } 1256 return service.getPhonebookAccessPermission(device); 1257 } 1258 1259 @Override 1260 public boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1261 if (!Utils.checkCaller()) { 1262 Log.w(TAG, "setPhonebookAccessPermission() - Not allowed for non-active user"); 1263 return false; 1264 } 1265 1266 AdapterService service = getService(); 1267 if (service == null) { 1268 return false; 1269 } 1270 return service.setPhonebookAccessPermission(device, value); 1271 } 1272 1273 @Override 1274 public int getMessageAccessPermission(BluetoothDevice device) { 1275 if (!Utils.checkCaller()) { 1276 Log.w(TAG, "getMessageAccessPermission() - Not allowed for non-active user"); 1277 return BluetoothDevice.ACCESS_UNKNOWN; 1278 } 1279 1280 AdapterService service = getService(); 1281 if (service == null) { 1282 return BluetoothDevice.ACCESS_UNKNOWN; 1283 } 1284 return service.getMessageAccessPermission(device); 1285 } 1286 1287 @Override 1288 public boolean setMessageAccessPermission(BluetoothDevice device, int value) { 1289 if (!Utils.checkCaller()) { 1290 Log.w(TAG, "setMessageAccessPermission() - Not allowed for non-active user"); 1291 return false; 1292 } 1293 1294 AdapterService service = getService(); 1295 if (service == null) { 1296 return false; 1297 } 1298 return service.setMessageAccessPermission(device, value); 1299 } 1300 1301 @Override 1302 public int getSimAccessPermission(BluetoothDevice device) { 1303 if (!Utils.checkCaller()) { 1304 Log.w(TAG, "getSimAccessPermission() - Not allowed for non-active user"); 1305 return BluetoothDevice.ACCESS_UNKNOWN; 1306 } 1307 1308 AdapterService service = getService(); 1309 if (service == null) { 1310 return BluetoothDevice.ACCESS_UNKNOWN; 1311 } 1312 return service.getSimAccessPermission(device); 1313 } 1314 1315 @Override 1316 public boolean setSimAccessPermission(BluetoothDevice device, int value) { 1317 if (!Utils.checkCaller()) { 1318 Log.w(TAG, "setSimAccessPermission() - Not allowed for non-active user"); 1319 return false; 1320 } 1321 1322 AdapterService service = getService(); 1323 if (service == null) { 1324 return false; 1325 } 1326 return service.setSimAccessPermission(device, value); 1327 } 1328 1329 @Override 1330 public void sendConnectionStateChange(BluetoothDevice device, int profile, int state, 1331 int prevState) { 1332 AdapterService service = getService(); 1333 if (service == null) { 1334 return; 1335 } 1336 service.sendConnectionStateChange(device, profile, state, prevState); 1337 } 1338 1339 @Override 1340 public IBluetoothSocketManager getSocketManager() { 1341 AdapterService service = getService(); 1342 if (service == null) { 1343 return null; 1344 } 1345 return service.getSocketManager(); 1346 } 1347 1348 @Override 1349 public boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1350 if (!Utils.checkCaller()) { 1351 Log.w(TAG, "sdpSea(): not allowed for non-active user"); 1352 return false; 1353 } 1354 1355 AdapterService service = getService(); 1356 if (service == null) { 1357 return false; 1358 } 1359 return service.sdpSearch(device, uuid); 1360 } 1361 1362 @Override 1363 public int getBatteryLevel(BluetoothDevice device) { 1364 if (!Utils.checkCaller()) { 1365 Log.w(TAG, "getBatteryLevel(): not allowed for non-active user"); 1366 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 1367 } 1368 1369 AdapterService service = getService(); 1370 if (service == null) { 1371 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 1372 } 1373 return service.getBatteryLevel(device); 1374 } 1375 1376 @Override 1377 public int getMaxConnectedAudioDevices() { 1378 // don't check caller, may be called from system UI 1379 AdapterService service = getService(); 1380 if (service == null) { 1381 return AdapterProperties.MIN_CONNECTED_AUDIO_DEVICES; 1382 } 1383 return service.getMaxConnectedAudioDevices(); 1384 } 1385 1386 @Override 1387 public boolean factoryReset() { 1388 AdapterService service = getService(); 1389 if (service == null) { 1390 return false; 1391 } 1392 service.disable(); 1393 return service.factoryReset(); 1394 1395 } 1396 1397 @Override 1398 public void registerCallback(IBluetoothCallback cb) { 1399 AdapterService service = getService(); 1400 if (service == null) { 1401 return; 1402 } 1403 service.registerCallback(cb); 1404 } 1405 1406 @Override 1407 public void unregisterCallback(IBluetoothCallback cb) { 1408 AdapterService service = getService(); 1409 if (service == null) { 1410 return; 1411 } 1412 service.unregisterCallback(cb); 1413 } 1414 1415 @Override 1416 public boolean isMultiAdvertisementSupported() { 1417 AdapterService service = getService(); 1418 if (service == null) { 1419 return false; 1420 } 1421 return service.isMultiAdvertisementSupported(); 1422 } 1423 1424 @Override 1425 public boolean isOffloadedFilteringSupported() { 1426 AdapterService service = getService(); 1427 if (service == null) { 1428 return false; 1429 } 1430 int val = service.getNumOfOffloadedScanFilterSupported(); 1431 return (val >= MIN_OFFLOADED_FILTERS); 1432 } 1433 1434 @Override 1435 public boolean isOffloadedScanBatchingSupported() { 1436 AdapterService service = getService(); 1437 if (service == null) { 1438 return false; 1439 } 1440 int val = service.getOffloadedScanResultStorage(); 1441 return (val >= MIN_OFFLOADED_SCAN_STORAGE_BYTES); 1442 } 1443 1444 @Override 1445 public boolean isLe2MPhySupported() { 1446 AdapterService service = getService(); 1447 if (service == null) { 1448 return false; 1449 } 1450 return service.isLe2MPhySupported(); 1451 } 1452 1453 @Override 1454 public boolean isLeCodedPhySupported() { 1455 AdapterService service = getService(); 1456 if (service == null) { 1457 return false; 1458 } 1459 return service.isLeCodedPhySupported(); 1460 } 1461 1462 @Override 1463 public boolean isLeExtendedAdvertisingSupported() { 1464 AdapterService service = getService(); 1465 if (service == null) { 1466 return false; 1467 } 1468 return service.isLeExtendedAdvertisingSupported(); 1469 } 1470 1471 @Override 1472 public boolean isLePeriodicAdvertisingSupported() { 1473 AdapterService service = getService(); 1474 if (service == null) { 1475 return false; 1476 } 1477 return service.isLePeriodicAdvertisingSupported(); 1478 } 1479 1480 @Override 1481 public int getLeMaximumAdvertisingDataLength() { 1482 AdapterService service = getService(); 1483 if (service == null) { 1484 return 0; 1485 } 1486 return service.getLeMaximumAdvertisingDataLength(); 1487 } 1488 1489 @Override 1490 public boolean isActivityAndEnergyReportingSupported() { 1491 AdapterService service = getService(); 1492 if (service == null) { 1493 return false; 1494 } 1495 return service.isActivityAndEnergyReportingSupported(); 1496 } 1497 1498 @Override 1499 public BluetoothActivityEnergyInfo reportActivityInfo() { 1500 AdapterService service = getService(); 1501 if (service == null) { 1502 return null; 1503 } 1504 return service.reportActivityInfo(); 1505 } 1506 1507 @Override 1508 public void requestActivityInfo(ResultReceiver result) { 1509 Bundle bundle = new Bundle(); 1510 bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, reportActivityInfo()); 1511 result.send(0, bundle); 1512 } 1513 1514 @Override 1515 public void onLeServiceUp() { 1516 AdapterService service = getService(); 1517 if (service == null) { 1518 return; 1519 } 1520 service.onLeServiceUp(); 1521 } 1522 1523 @Override 1524 public void onBrEdrDown() { 1525 AdapterService service = getService(); 1526 if (service == null) { 1527 return; 1528 } 1529 service.onBrEdrDown(); 1530 } 1531 1532 @Override 1533 public void dump(FileDescriptor fd, String[] args) { 1534 PrintWriter writer = new PrintWriter(new FileOutputStream(fd)); 1535 AdapterService service = getService(); 1536 if (service == null) { 1537 return; 1538 } 1539 service.dump(fd, writer, args); 1540 writer.close(); 1541 } 1542 } 1543 1544 ; 1545 1546 // ----API Methods-------- 1547 1548 public boolean isEnabled() { 1549 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1550 return mAdapterProperties.getState() == BluetoothAdapter.STATE_ON; 1551 } 1552 1553 public int getState() { 1554 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1555 if (mAdapterProperties != null) { 1556 return mAdapterProperties.getState(); 1557 } 1558 return BluetoothAdapter.STATE_OFF; 1559 } 1560 1561 public boolean enable() { 1562 return enable(false); 1563 } 1564 1565 public boolean enableNoAutoConnect() { 1566 return enable(true); 1567 } 1568 1569 public synchronized boolean enable(boolean quietMode) { 1570 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1571 1572 // Enforce the user restriction for disallowing Bluetooth if it was set. 1573 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_BLUETOOTH, UserHandle.SYSTEM)) { 1574 debugLog("enable() called when Bluetooth was disallowed"); 1575 return false; 1576 } 1577 1578 debugLog("enable() - Enable called with quiet mode status = " + quietMode); 1579 mQuietmode = quietMode; 1580 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_ON); 1581 mAdapterStateMachine.sendMessage(m); 1582 return true; 1583 } 1584 1585 boolean disable() { 1586 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1587 1588 debugLog("disable() called..."); 1589 Message m = mAdapterStateMachine.obtainMessage(AdapterState.BLE_TURN_OFF); 1590 mAdapterStateMachine.sendMessage(m); 1591 return true; 1592 } 1593 1594 String getAddress() { 1595 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1596 enforceCallingOrSelfPermission(LOCAL_MAC_ADDRESS_PERM, "Need LOCAL_MAC_ADDRESS permission"); 1597 1598 String addrString = null; 1599 byte[] address = mAdapterProperties.getAddress(); 1600 return Utils.getAddressStringFromByte(address); 1601 } 1602 1603 ParcelUuid[] getUuids() { 1604 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1605 1606 return mAdapterProperties.getUuids(); 1607 } 1608 1609 public String getName() { 1610 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1611 1612 try { 1613 return mAdapterProperties.getName(); 1614 } catch (Throwable t) { 1615 debugLog("getName() - Unexpected exception (" + t + ")"); 1616 } 1617 return null; 1618 } 1619 1620 boolean setName(String name) { 1621 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1622 1623 return mAdapterProperties.setName(name); 1624 } 1625 1626 BluetoothClass getBluetoothClass() { 1627 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1628 1629 return mAdapterProperties.getBluetoothClass(); 1630 } 1631 1632 /** 1633 * Sets the Bluetooth CoD on the local adapter and also modifies the storage config for it. 1634 * 1635 * <p>Once set, this value persists across reboots. 1636 */ 1637 boolean setBluetoothClass(BluetoothClass bluetoothClass) { 1638 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1639 "Need BLUETOOTH PRIVILEGED permission"); 1640 debugLog("setBluetoothClass() to " + bluetoothClass); 1641 boolean result = mAdapterProperties.setBluetoothClass(bluetoothClass); 1642 if (!result) { 1643 Log.e(TAG, "setBluetoothClass() to " + bluetoothClass + " failed"); 1644 } 1645 1646 return result && storeBluetoothClassConfig(bluetoothClass.getClassOfDevice()); 1647 } 1648 1649 int getScanMode() { 1650 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1651 1652 return mAdapterProperties.getScanMode(); 1653 } 1654 1655 boolean setScanMode(int mode, int duration) { 1656 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1657 1658 setDiscoverableTimeout(duration); 1659 1660 int newMode = convertScanModeToHal(mode); 1661 return mAdapterProperties.setScanMode(newMode); 1662 } 1663 1664 int getDiscoverableTimeout() { 1665 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1666 1667 return mAdapterProperties.getDiscoverableTimeout(); 1668 } 1669 1670 boolean setDiscoverableTimeout(int timeout) { 1671 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1672 1673 return mAdapterProperties.setDiscoverableTimeout(timeout); 1674 } 1675 1676 boolean startDiscovery() { 1677 debugLog("startDiscovery"); 1678 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1679 1680 return startDiscoveryNative(); 1681 } 1682 1683 boolean cancelDiscovery() { 1684 debugLog("cancelDiscovery"); 1685 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1686 1687 return cancelDiscoveryNative(); 1688 } 1689 1690 boolean isDiscovering() { 1691 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1692 1693 return mAdapterProperties.isDiscovering(); 1694 } 1695 1696 long getDiscoveryEndMillis() { 1697 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1698 1699 return mAdapterProperties.discoveryEndMillis(); 1700 } 1701 1702 /** 1703 * Same as API method {@link BluetoothAdapter#getBondedDevices()} 1704 * 1705 * @return array of bonded {@link BluetoothDevice} or null on error 1706 */ 1707 public BluetoothDevice[] getBondedDevices() { 1708 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1709 return mAdapterProperties.getBondedDevices(); 1710 } 1711 1712 int getAdapterConnectionState() { 1713 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1714 return mAdapterProperties.getConnectionState(); 1715 } 1716 1717 int getProfileConnectionState(int profile) { 1718 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1719 1720 return mAdapterProperties.getProfileConnectionState(profile); 1721 } 1722 1723 boolean sdpSearch(BluetoothDevice device, ParcelUuid uuid) { 1724 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1725 if (mSdpManager != null) { 1726 mSdpManager.sdpSearch(device, uuid); 1727 return true; 1728 } else { 1729 return false; 1730 } 1731 } 1732 1733 boolean createBond(BluetoothDevice device, int transport, OobData oobData) { 1734 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1735 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1736 if (deviceProp != null && deviceProp.getBondState() != BluetoothDevice.BOND_NONE) { 1737 return false; 1738 } 1739 1740 mRemoteDevices.setBondingInitiatedLocally(Utils.getByteAddress(device)); 1741 1742 // Pairing is unreliable while scanning, so cancel discovery 1743 // Note, remove this when native stack improves 1744 cancelDiscoveryNative(); 1745 1746 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.CREATE_BOND); 1747 msg.obj = device; 1748 msg.arg1 = transport; 1749 1750 if (oobData != null) { 1751 Bundle oobDataBundle = new Bundle(); 1752 oobDataBundle.putParcelable(BondStateMachine.OOBDATA, oobData); 1753 msg.setData(oobDataBundle); 1754 } 1755 mBondStateMachine.sendMessage(msg); 1756 return true; 1757 } 1758 1759 public boolean isQuietModeEnabled() { 1760 debugLog("isQuetModeEnabled() - Enabled = " + mQuietmode); 1761 return mQuietmode; 1762 } 1763 1764 public void updateUuids() { 1765 debugLog("updateUuids() - Updating UUIDs for bonded devices"); 1766 BluetoothDevice[] bondedDevices = getBondedDevices(); 1767 if (bondedDevices == null) { 1768 return; 1769 } 1770 1771 for (BluetoothDevice device : bondedDevices) { 1772 mRemoteDevices.updateUuids(device); 1773 } 1774 } 1775 1776 boolean cancelBondProcess(BluetoothDevice device) { 1777 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1778 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1779 1780 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1781 if (deviceProp != null) { 1782 deviceProp.setBondingInitiatedLocally(false); 1783 } 1784 1785 return cancelBondNative(addr); 1786 } 1787 1788 boolean removeBond(BluetoothDevice device) { 1789 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1790 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1791 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDED) { 1792 return false; 1793 } 1794 deviceProp.setBondingInitiatedLocally(false); 1795 1796 Message msg = mBondStateMachine.obtainMessage(BondStateMachine.REMOVE_BOND); 1797 msg.obj = device; 1798 mBondStateMachine.sendMessage(msg); 1799 return true; 1800 } 1801 1802 /** 1803 * Get the bond state of a particular {@link BluetoothDevice} 1804 * 1805 * @param device remote device of interest 1806 * @return bond state <p>Possible values are 1807 * {@link BluetoothDevice#BOND_NONE}, 1808 * {@link BluetoothDevice#BOND_BONDING}, 1809 * {@link BluetoothDevice#BOND_BONDED}. 1810 */ 1811 @VisibleForTesting 1812 public int getBondState(BluetoothDevice device) { 1813 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1814 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1815 if (deviceProp == null) { 1816 return BluetoothDevice.BOND_NONE; 1817 } 1818 return deviceProp.getBondState(); 1819 } 1820 1821 boolean isBondingInitiatedLocally(BluetoothDevice device) { 1822 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1823 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1824 if (deviceProp == null) { 1825 return false; 1826 } 1827 return deviceProp.isBondingInitiatedLocally(); 1828 } 1829 1830 long getSupportedProfiles() { 1831 return Config.getSupportedProfilesBitMask(); 1832 } 1833 1834 int getConnectionState(BluetoothDevice device) { 1835 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1836 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1837 return getConnectionStateNative(addr); 1838 } 1839 1840 /** 1841 * Same as API method {@link BluetoothDevice#getName()} 1842 * 1843 * @param device remote device of interest 1844 * @return remote device name 1845 */ 1846 public String getRemoteName(BluetoothDevice device) { 1847 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1848 if (mRemoteDevices == null) { 1849 return null; 1850 } 1851 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1852 if (deviceProp == null) { 1853 return null; 1854 } 1855 return deviceProp.getName(); 1856 } 1857 1858 int getRemoteType(BluetoothDevice device) { 1859 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1860 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1861 if (deviceProp == null) { 1862 return BluetoothDevice.DEVICE_TYPE_UNKNOWN; 1863 } 1864 return deviceProp.getDeviceType(); 1865 } 1866 1867 String getRemoteAlias(BluetoothDevice device) { 1868 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1869 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1870 if (deviceProp == null) { 1871 return null; 1872 } 1873 return deviceProp.getAlias(); 1874 } 1875 1876 boolean setRemoteAlias(BluetoothDevice device, String name) { 1877 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1878 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1879 if (deviceProp == null) { 1880 return false; 1881 } 1882 deviceProp.setAlias(device, name); 1883 return true; 1884 } 1885 1886 int getRemoteClass(BluetoothDevice device) { 1887 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1888 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1889 if (deviceProp == null) { 1890 return 0; 1891 } 1892 1893 return deviceProp.getBluetoothClass(); 1894 } 1895 1896 /** 1897 * Get UUIDs for service supported by a remote device 1898 * 1899 * @param device the remote device that we want to get UUIDs from 1900 * @return 1901 */ 1902 @VisibleForTesting 1903 public ParcelUuid[] getRemoteUuids(BluetoothDevice device) { 1904 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1905 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1906 if (deviceProp == null) { 1907 return null; 1908 } 1909 return deviceProp.getUuids(); 1910 } 1911 1912 boolean fetchRemoteUuids(BluetoothDevice device) { 1913 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1914 mRemoteDevices.fetchUuids(device); 1915 return true; 1916 } 1917 1918 int getBatteryLevel(BluetoothDevice device) { 1919 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1920 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1921 if (deviceProp == null) { 1922 return BluetoothDevice.BATTERY_LEVEL_UNKNOWN; 1923 } 1924 return deviceProp.getBatteryLevel(); 1925 } 1926 1927 boolean setPin(BluetoothDevice device, boolean accept, int len, byte[] pinCode) { 1928 enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM, "Need BLUETOOTH ADMIN permission"); 1929 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1930 // Only allow setting a pin in bonding state, or bonded state in case of security upgrade. 1931 if (deviceProp == null || (deviceProp.getBondState() != BluetoothDevice.BOND_BONDING 1932 && deviceProp.getBondState() != BluetoothDevice.BOND_BONDED)) { 1933 return false; 1934 } 1935 1936 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1937 return pinReplyNative(addr, accept, len, pinCode); 1938 } 1939 1940 boolean setPasskey(BluetoothDevice device, boolean accept, int len, byte[] passkey) { 1941 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1942 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1943 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1944 return false; 1945 } 1946 1947 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1948 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_ENTRY, accept, 1949 Utils.byteArrayToInt(passkey)); 1950 } 1951 1952 boolean setPairingConfirmation(BluetoothDevice device, boolean accept) { 1953 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1954 "Need BLUETOOTH PRIVILEGED permission"); 1955 DeviceProperties deviceProp = mRemoteDevices.getDeviceProperties(device); 1956 if (deviceProp == null || deviceProp.getBondState() != BluetoothDevice.BOND_BONDING) { 1957 return false; 1958 } 1959 1960 byte[] addr = Utils.getBytesFromAddress(device.getAddress()); 1961 return sspReplyNative(addr, AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION, accept, 1962 0); 1963 } 1964 1965 int getPhonebookAccessPermission(BluetoothDevice device) { 1966 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1967 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1968 Context.MODE_PRIVATE); 1969 if (!pref.contains(device.getAddress())) { 1970 return BluetoothDevice.ACCESS_UNKNOWN; 1971 } 1972 return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED 1973 : BluetoothDevice.ACCESS_REJECTED; 1974 } 1975 1976 boolean setPhonebookAccessPermission(BluetoothDevice device, int value) { 1977 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 1978 "Need BLUETOOTH PRIVILEGED permission"); 1979 SharedPreferences pref = getSharedPreferences(PHONEBOOK_ACCESS_PERMISSION_PREFERENCE_FILE, 1980 Context.MODE_PRIVATE); 1981 SharedPreferences.Editor editor = pref.edit(); 1982 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 1983 editor.remove(device.getAddress()); 1984 } else { 1985 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 1986 } 1987 editor.apply(); 1988 return true; 1989 } 1990 1991 int getMessageAccessPermission(BluetoothDevice device) { 1992 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 1993 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 1994 Context.MODE_PRIVATE); 1995 if (!pref.contains(device.getAddress())) { 1996 return BluetoothDevice.ACCESS_UNKNOWN; 1997 } 1998 return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED 1999 : BluetoothDevice.ACCESS_REJECTED; 2000 } 2001 2002 boolean setMessageAccessPermission(BluetoothDevice device, int value) { 2003 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 2004 "Need BLUETOOTH PRIVILEGED permission"); 2005 SharedPreferences pref = getSharedPreferences(MESSAGE_ACCESS_PERMISSION_PREFERENCE_FILE, 2006 Context.MODE_PRIVATE); 2007 SharedPreferences.Editor editor = pref.edit(); 2008 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 2009 editor.remove(device.getAddress()); 2010 } else { 2011 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 2012 } 2013 editor.apply(); 2014 return true; 2015 } 2016 2017 int getSimAccessPermission(BluetoothDevice device) { 2018 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2019 SharedPreferences pref = 2020 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE); 2021 if (!pref.contains(device.getAddress())) { 2022 return BluetoothDevice.ACCESS_UNKNOWN; 2023 } 2024 return pref.getBoolean(device.getAddress(), false) ? BluetoothDevice.ACCESS_ALLOWED 2025 : BluetoothDevice.ACCESS_REJECTED; 2026 } 2027 2028 boolean setSimAccessPermission(BluetoothDevice device, int value) { 2029 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, 2030 "Need BLUETOOTH PRIVILEGED permission"); 2031 SharedPreferences pref = 2032 getSharedPreferences(SIM_ACCESS_PERMISSION_PREFERENCE_FILE, Context.MODE_PRIVATE); 2033 SharedPreferences.Editor editor = pref.edit(); 2034 if (value == BluetoothDevice.ACCESS_UNKNOWN) { 2035 editor.remove(device.getAddress()); 2036 } else { 2037 editor.putBoolean(device.getAddress(), value == BluetoothDevice.ACCESS_ALLOWED); 2038 } 2039 editor.apply(); 2040 return true; 2041 } 2042 2043 void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) { 2044 // TODO(BT) permission check? 2045 // Since this is a binder call check if Bluetooth is on still 2046 if (getState() == BluetoothAdapter.STATE_OFF) { 2047 return; 2048 } 2049 2050 mAdapterProperties.sendConnectionStateChange(device, profile, state, prevState); 2051 2052 } 2053 2054 IBluetoothSocketManager getSocketManager() { 2055 android.os.IBinder obj = getSocketManagerNative(); 2056 if (obj == null) { 2057 return null; 2058 } 2059 2060 return IBluetoothSocketManager.Stub.asInterface(obj); 2061 } 2062 2063 boolean factoryReset() { 2064 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 2065 return factoryResetNative(); 2066 } 2067 2068 void registerCallback(IBluetoothCallback cb) { 2069 mCallbacks.register(cb); 2070 } 2071 2072 void unregisterCallback(IBluetoothCallback cb) { 2073 mCallbacks.unregister(cb); 2074 } 2075 2076 public int getNumOfAdvertisementInstancesSupported() { 2077 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2078 return mAdapterProperties.getNumOfAdvertisementInstancesSupported(); 2079 } 2080 2081 public boolean isMultiAdvertisementSupported() { 2082 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2083 return getNumOfAdvertisementInstancesSupported() >= MIN_ADVT_INSTANCES_FOR_MA; 2084 } 2085 2086 public boolean isRpaOffloadSupported() { 2087 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2088 return mAdapterProperties.isRpaOffloadSupported(); 2089 } 2090 2091 public int getNumOfOffloadedIrkSupported() { 2092 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2093 return mAdapterProperties.getNumOfOffloadedIrkSupported(); 2094 } 2095 2096 public int getNumOfOffloadedScanFilterSupported() { 2097 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2098 return mAdapterProperties.getNumOfOffloadedScanFilterSupported(); 2099 } 2100 2101 public int getOffloadedScanResultStorage() { 2102 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2103 return mAdapterProperties.getOffloadedScanResultStorage(); 2104 } 2105 2106 private boolean isActivityAndEnergyReportingSupported() { 2107 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 2108 return mAdapterProperties.isActivityAndEnergyReportingSupported(); 2109 } 2110 2111 public boolean isLe2MPhySupported() { 2112 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2113 return mAdapterProperties.isLe2MPhySupported(); 2114 } 2115 2116 public boolean isLeCodedPhySupported() { 2117 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2118 return mAdapterProperties.isLeCodedPhySupported(); 2119 } 2120 2121 public boolean isLeExtendedAdvertisingSupported() { 2122 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2123 return mAdapterProperties.isLeExtendedAdvertisingSupported(); 2124 } 2125 2126 public boolean isLePeriodicAdvertisingSupported() { 2127 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2128 return mAdapterProperties.isLePeriodicAdvertisingSupported(); 2129 } 2130 2131 public int getLeMaximumAdvertisingDataLength() { 2132 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2133 return mAdapterProperties.getLeMaximumAdvertisingDataLength(); 2134 } 2135 2136 /** 2137 * Get the maximum number of connected audio devices. 2138 * 2139 * @return the maximum number of connected audio devices 2140 */ 2141 public int getMaxConnectedAudioDevices() { 2142 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2143 return mAdapterProperties.getMaxConnectedAudioDevices(); 2144 } 2145 2146 private BluetoothActivityEnergyInfo reportActivityInfo() { 2147 enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED, "Need BLUETOOTH permission"); 2148 if (mAdapterProperties.getState() != BluetoothAdapter.STATE_ON 2149 || !mAdapterProperties.isActivityAndEnergyReportingSupported()) { 2150 return null; 2151 } 2152 2153 // Pull the data. The callback will notify mEnergyInfoLock. 2154 readEnergyInfo(); 2155 2156 synchronized (mEnergyInfoLock) { 2157 try { 2158 mEnergyInfoLock.wait(CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS); 2159 } catch (InterruptedException e) { 2160 // Just continue, the energy data may be stale but we won't miss anything next time 2161 // we query. 2162 } 2163 2164 final BluetoothActivityEnergyInfo info = 2165 new BluetoothActivityEnergyInfo(SystemClock.elapsedRealtime(), 2166 mStackReportedState, mTxTimeTotalMs, mRxTimeTotalMs, mIdleTimeTotalMs, 2167 mEnergyUsedTotalVoltAmpSecMicro); 2168 2169 // Count the number of entries that have byte counts > 0 2170 int arrayLen = 0; 2171 for (int i = 0; i < mUidTraffic.size(); i++) { 2172 final UidTraffic traffic = mUidTraffic.valueAt(i); 2173 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 2174 arrayLen++; 2175 } 2176 } 2177 2178 // Copy the traffic objects whose byte counts are > 0 and reset the originals. 2179 final UidTraffic[] result = arrayLen > 0 ? new UidTraffic[arrayLen] : null; 2180 int putIdx = 0; 2181 for (int i = 0; i < mUidTraffic.size(); i++) { 2182 final UidTraffic traffic = mUidTraffic.valueAt(i); 2183 if (traffic.getTxBytes() != 0 || traffic.getRxBytes() != 0) { 2184 result[putIdx++] = traffic.clone(); 2185 traffic.setRxBytes(0); 2186 traffic.setTxBytes(0); 2187 } 2188 } 2189 2190 info.setUidTraffic(result); 2191 2192 // Read on clear values; a record of data is created with 2193 // timstamp and new samples are collected until read again 2194 mStackReportedState = 0; 2195 mTxTimeTotalMs = 0; 2196 mRxTimeTotalMs = 0; 2197 mIdleTimeTotalMs = 0; 2198 mEnergyUsedTotalVoltAmpSecMicro = 0; 2199 return info; 2200 } 2201 } 2202 2203 public int getTotalNumOfTrackableAdvertisements() { 2204 enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); 2205 return mAdapterProperties.getTotalNumOfTrackableAdvertisements(); 2206 } 2207 2208 public void onLeServiceUp() { 2209 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_ON); 2210 mAdapterStateMachine.sendMessage(m); 2211 } 2212 2213 public void onBrEdrDown() { 2214 Message m = mAdapterStateMachine.obtainMessage(AdapterState.USER_TURN_OFF); 2215 mAdapterStateMachine.sendMessage(m); 2216 } 2217 2218 private static int convertScanModeToHal(int mode) { 2219 switch (mode) { 2220 case BluetoothAdapter.SCAN_MODE_NONE: 2221 return AbstractionLayer.BT_SCAN_MODE_NONE; 2222 case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 2223 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE; 2224 case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 2225 return AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE; 2226 } 2227 // errorLog("Incorrect scan mode in convertScanModeToHal"); 2228 return -1; 2229 } 2230 2231 static int convertScanModeFromHal(int mode) { 2232 switch (mode) { 2233 case AbstractionLayer.BT_SCAN_MODE_NONE: 2234 return BluetoothAdapter.SCAN_MODE_NONE; 2235 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE: 2236 return BluetoothAdapter.SCAN_MODE_CONNECTABLE; 2237 case AbstractionLayer.BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE: 2238 return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE; 2239 } 2240 //errorLog("Incorrect scan mode in convertScanModeFromHal"); 2241 return -1; 2242 } 2243 2244 // This function is called from JNI. It allows native code to set a single wake 2245 // alarm. If an alarm is already pending and a new request comes in, the alarm 2246 // will be rescheduled (i.e. the previously set alarm will be cancelled). 2247 private boolean setWakeAlarm(long delayMillis, boolean shouldWake) { 2248 synchronized (this) { 2249 if (mPendingAlarm != null) { 2250 mAlarmManager.cancel(mPendingAlarm); 2251 } 2252 2253 long wakeupTime = SystemClock.elapsedRealtime() + delayMillis; 2254 int type = shouldWake ? AlarmManager.ELAPSED_REALTIME_WAKEUP 2255 : AlarmManager.ELAPSED_REALTIME; 2256 2257 Intent intent = new Intent(ACTION_ALARM_WAKEUP); 2258 mPendingAlarm = 2259 PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); 2260 mAlarmManager.setExact(type, wakeupTime, mPendingAlarm); 2261 return true; 2262 } 2263 } 2264 2265 // This function is called from JNI. It allows native code to acquire a single wake lock. 2266 // If the wake lock is already held, this function returns success. Although this function 2267 // only supports acquiring a single wake lock at a time right now, it will eventually be 2268 // extended to allow acquiring an arbitrary number of wake locks. The current interface 2269 // takes |lockName| as a parameter in anticipation of that implementation. 2270 private boolean acquireWakeLock(String lockName) { 2271 synchronized (this) { 2272 if (mWakeLock == null) { 2273 mWakeLockName = lockName; 2274 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, lockName); 2275 } 2276 2277 if (!mWakeLock.isHeld()) { 2278 mWakeLock.acquire(); 2279 } 2280 } 2281 return true; 2282 } 2283 2284 // This function is called from JNI. It allows native code to release a wake lock acquired 2285 // by |acquireWakeLock|. If the wake lock is not held, this function returns failure. 2286 // Note that the release() call is also invoked by {@link #cleanup()} so a synchronization is 2287 // needed here. See the comment for |acquireWakeLock| for an explanation of the interface. 2288 private boolean releaseWakeLock(String lockName) { 2289 synchronized (this) { 2290 if (mWakeLock == null) { 2291 errorLog("Repeated wake lock release; aborting release: " + lockName); 2292 return false; 2293 } 2294 2295 if (mWakeLock.isHeld()) { 2296 mWakeLock.release(); 2297 } 2298 } 2299 return true; 2300 } 2301 2302 private void energyInfoCallback(int status, int ctrlState, long txTime, long rxTime, 2303 long idleTime, long energyUsed, UidTraffic[] data) throws RemoteException { 2304 if (ctrlState >= BluetoothActivityEnergyInfo.BT_STACK_STATE_INVALID 2305 && ctrlState <= BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_IDLE) { 2306 // Energy is product of mA, V and ms. If the chipset doesn't 2307 // report it, we have to compute it from time 2308 if (energyUsed == 0) { 2309 try { 2310 final long txMah = Math.multiplyExact(txTime, getTxCurrentMa()); 2311 final long rxMah = Math.multiplyExact(rxTime, getRxCurrentMa()); 2312 final long idleMah = Math.multiplyExact(idleTime, getIdleCurrentMa()); 2313 energyUsed = (long) (Math.addExact(Math.addExact(txMah, rxMah), idleMah) 2314 * getOperatingVolt()); 2315 } catch (ArithmeticException e) { 2316 Slog.wtf(TAG, "overflow in bluetooth energy callback", e); 2317 // Energy is already 0 if the exception was thrown. 2318 } 2319 } 2320 2321 synchronized (mEnergyInfoLock) { 2322 mStackReportedState = ctrlState; 2323 long totalTxTimeMs; 2324 long totalRxTimeMs; 2325 long totalIdleTimeMs; 2326 long totalEnergy; 2327 try { 2328 totalTxTimeMs = Math.addExact(mTxTimeTotalMs, txTime); 2329 totalRxTimeMs = Math.addExact(mRxTimeTotalMs, rxTime); 2330 totalIdleTimeMs = Math.addExact(mIdleTimeTotalMs, idleTime); 2331 totalEnergy = Math.addExact(mEnergyUsedTotalVoltAmpSecMicro, energyUsed); 2332 } catch (ArithmeticException e) { 2333 // This could be because we accumulated a lot of time, or we got a very strange 2334 // value from the controller (more likely). Discard this data. 2335 Slog.wtf(TAG, "overflow in bluetooth energy callback", e); 2336 totalTxTimeMs = mTxTimeTotalMs; 2337 totalRxTimeMs = mRxTimeTotalMs; 2338 totalIdleTimeMs = mIdleTimeTotalMs; 2339 totalEnergy = mEnergyUsedTotalVoltAmpSecMicro; 2340 } 2341 2342 mTxTimeTotalMs = totalTxTimeMs; 2343 mRxTimeTotalMs = totalRxTimeMs; 2344 mIdleTimeTotalMs = totalIdleTimeMs; 2345 mEnergyUsedTotalVoltAmpSecMicro = totalEnergy; 2346 2347 for (UidTraffic traffic : data) { 2348 UidTraffic existingTraffic = mUidTraffic.get(traffic.getUid()); 2349 if (existingTraffic == null) { 2350 mUidTraffic.put(traffic.getUid(), traffic); 2351 } else { 2352 existingTraffic.addRxBytes(traffic.getRxBytes()); 2353 existingTraffic.addTxBytes(traffic.getTxBytes()); 2354 } 2355 } 2356 mEnergyInfoLock.notifyAll(); 2357 } 2358 } 2359 2360 verboseLog("energyInfoCallback() status = " + status + "txTime = " + txTime + "rxTime = " 2361 + rxTime + "idleTime = " + idleTime + "energyUsed = " + energyUsed + "ctrlState = " 2362 + ctrlState + "traffic = " + Arrays.toString(data)); 2363 } 2364 2365 private int getIdleCurrentMa() { 2366 return getResources().getInteger(R.integer.config_bluetooth_idle_cur_ma); 2367 } 2368 2369 private int getTxCurrentMa() { 2370 return getResources().getInteger(R.integer.config_bluetooth_tx_cur_ma); 2371 } 2372 2373 private int getRxCurrentMa() { 2374 return getResources().getInteger(R.integer.config_bluetooth_rx_cur_ma); 2375 } 2376 2377 private double getOperatingVolt() { 2378 return getResources().getInteger(R.integer.config_bluetooth_operating_voltage_mv) / 1000.0; 2379 } 2380 2381 @Override 2382 protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) { 2383 enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG); 2384 2385 if (args.length == 0) { 2386 writer.println("Skipping dump in APP SERVICES, see bluetooth_manager section."); 2387 writer.println("Use --print argument for dumpsys direct from AdapterService."); 2388 return; 2389 } 2390 2391 verboseLog("dumpsys arguments, check for protobuf output: " + TextUtils.join(" ", args)); 2392 if (args[0].equals("--proto-bin")) { 2393 dumpMetrics(fd); 2394 return; 2395 } 2396 2397 writer.println("Bonded devices:"); 2398 for (BluetoothDevice device : getBondedDevices()) { 2399 writer.println( 2400 " " + device.getAddress() + " [" + DEVICE_TYPE_NAMES[device.getType()] + "] " 2401 + device.getName()); 2402 } 2403 2404 StringBuilder sb = new StringBuilder(); 2405 for (ProfileService profile : mRegisteredProfiles) { 2406 profile.dump(sb); 2407 } 2408 2409 writer.write(sb.toString()); 2410 writer.flush(); 2411 2412 dumpNative(fd, args); 2413 } 2414 2415 private void dumpMetrics(FileDescriptor fd) { 2416 BluetoothProto.BluetoothLog metrics = new BluetoothProto.BluetoothLog(); 2417 metrics.setNumBondedDevices(getBondedDevices().length); 2418 for (ProfileService profile : mRegisteredProfiles) { 2419 profile.dumpProto(metrics); 2420 } 2421 byte[] nativeMetricsBytes = dumpMetricsNative(); 2422 debugLog("dumpMetrics: native metrics size is " + nativeMetricsBytes.length); 2423 if (nativeMetricsBytes.length > 0) { 2424 try { 2425 metrics.mergeFrom(nativeMetricsBytes); 2426 } catch (InvalidProtocolBufferMicroException ex) { 2427 Log.w(TAG, "dumpMetrics: problem parsing metrics protobuf, " + ex.getMessage()); 2428 return; 2429 } 2430 } 2431 byte[] metricsBytes = Base64.encode(metrics.toByteArray(), Base64.DEFAULT); 2432 debugLog("dumpMetrics: combined metrics size is " + metricsBytes.length); 2433 try (FileOutputStream protoOut = new FileOutputStream(fd)) { 2434 protoOut.write(metricsBytes); 2435 } catch (IOException e) { 2436 errorLog("dumpMetrics: error writing combined protobuf to fd, " + e.getMessage()); 2437 } 2438 } 2439 2440 private void debugLog(String msg) { 2441 if (DBG) { 2442 Log.d(TAG, msg); 2443 } 2444 } 2445 2446 private void verboseLog(String msg) { 2447 if (VERBOSE) { 2448 Log.v(TAG, msg); 2449 } 2450 } 2451 2452 private void errorLog(String msg) { 2453 Log.e(TAG, msg); 2454 } 2455 2456 private final BroadcastReceiver mAlarmBroadcastReceiver = new BroadcastReceiver() { 2457 @Override 2458 public void onReceive(Context context, Intent intent) { 2459 synchronized (AdapterService.this) { 2460 mPendingAlarm = null; 2461 alarmFiredNative(); 2462 } 2463 } 2464 }; 2465 2466 private static native void classInitNative(); 2467 2468 native boolean initNative(); 2469 2470 native void cleanupNative(); 2471 2472 /*package*/ 2473 native boolean enableNative(boolean startRestricted); 2474 2475 /*package*/ 2476 native boolean disableNative(); 2477 2478 /*package*/ 2479 native boolean setAdapterPropertyNative(int type, byte[] val); 2480 2481 /*package*/ 2482 native boolean getAdapterPropertiesNative(); 2483 2484 /*package*/ 2485 native boolean getAdapterPropertyNative(int type); 2486 2487 /*package*/ 2488 native boolean setAdapterPropertyNative(int type); 2489 2490 /*package*/ 2491 native boolean setDevicePropertyNative(byte[] address, int type, byte[] val); 2492 2493 /*package*/ 2494 native boolean getDevicePropertyNative(byte[] address, int type); 2495 2496 /*package*/ 2497 native boolean createBondNative(byte[] address, int transport); 2498 2499 /*package*/ 2500 native boolean createBondOutOfBandNative(byte[] address, int transport, OobData oobData); 2501 2502 /*package*/ 2503 native boolean removeBondNative(byte[] address); 2504 2505 /*package*/ 2506 native boolean cancelBondNative(byte[] address); 2507 2508 /*package*/ 2509 native boolean sdpSearchNative(byte[] address, byte[] uuid); 2510 2511 /*package*/ 2512 native int getConnectionStateNative(byte[] address); 2513 2514 private native boolean startDiscoveryNative(); 2515 2516 private native boolean cancelDiscoveryNative(); 2517 2518 private native boolean pinReplyNative(byte[] address, boolean accept, int len, byte[] pin); 2519 2520 private native boolean sspReplyNative(byte[] address, int type, boolean accept, int passkey); 2521 2522 /*package*/ 2523 native boolean getRemoteServicesNative(byte[] address); 2524 2525 /*package*/ 2526 native boolean getRemoteMasInstancesNative(byte[] address); 2527 2528 private native int readEnergyInfo(); 2529 2530 private native IBinder getSocketManagerNative(); 2531 2532 private native void setSystemUiUidNative(int systemUiUid); 2533 2534 private static native void setForegroundUserIdNative(int foregroundUserId); 2535 2536 /*package*/ 2537 native boolean factoryResetNative(); 2538 2539 private native void alarmFiredNative(); 2540 2541 private native void dumpNative(FileDescriptor fd, String[] arguments); 2542 2543 private native byte[] dumpMetricsNative(); 2544 2545 private native void interopDatabaseClearNative(); 2546 2547 private native void interopDatabaseAddNative(int feature, byte[] address, int length); 2548 2549 // Returns if this is a mock object. This is currently used in testing so that we may not call 2550 // System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up 2551 // calling finalize() which in turn calls System.exit() and the process crashes. 2552 // 2553 // Mock this in your testing framework to return true to avoid the mentioned behavior. In 2554 // production this has no effect. 2555 public boolean isMock() { 2556 return false; 2557 } 2558} 2559