Merge "DO NOT MERGE Institute limit on PhoneStateListener" into qt-qpr1-dev
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 31bbd16..3b620b3 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1195,9 +1195,11 @@
public boolean factoryReset() {
try {
mServiceLock.readLock().lock();
- if (mService != null) {
- return mService.factoryReset();
+ if (mService != null && mService.factoryReset()
+ && mManagerService != null && mManagerService.onFactoryReset()) {
+ return true;
}
+ Log.e(TAG, "factoryReset(): Setting persist.bluetooth.factoryreset to retry later");
SystemProperties.set("persist.bluetooth.factoryreset", "true");
} catch (RemoteException e) {
Log.e(TAG, "", e);
diff --git a/core/proto/android/bluetooth/enums.proto b/core/proto/android/bluetooth/enums.proto
index b4f3d1e..22f2498 100644
--- a/core/proto/android/bluetooth/enums.proto
+++ b/core/proto/android/bluetooth/enums.proto
@@ -40,6 +40,7 @@
ENABLE_DISABLE_REASON_CRASH = 7;
ENABLE_DISABLE_REASON_USER_SWITCH = 8;
ENABLE_DISABLE_REASON_RESTORE_USER_SETTING = 9;
+ ENABLE_DISABLE_REASON_FACTORY_RESET = 10;
}
enum DirectionEnum {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 188d654..f88032a 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -73,11 +73,14 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -257,6 +260,47 @@
}
};
+ public boolean onFactoryReset() {
+ // Wait for stable state if bluetooth is temporary state.
+ int state = getState();
+ if (state == BluetoothAdapter.STATE_BLE_TURNING_ON
+ || state == BluetoothAdapter.STATE_TURNING_ON
+ || state == BluetoothAdapter.STATE_TURNING_OFF) {
+ if (!waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_ON)))) {
+ return false;
+ }
+ }
+
+ // Clear registered LE apps to force shut-off Bluetooth
+ clearBleApps();
+ state = getState();
+ try {
+ mBluetoothLock.readLock().lock();
+ if (mBluetooth == null) {
+ return false;
+ }
+ if (state == BluetoothAdapter.STATE_BLE_ON) {
+ addActiveLog(
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
+ mContext.getPackageName(), false);
+ mBluetooth.onBrEdrDown();
+ return true;
+ } else if (state == BluetoothAdapter.STATE_ON) {
+ addActiveLog(
+ BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET,
+ mContext.getPackageName(), false);
+ mBluetooth.disable();
+ return true;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to shutdown Bluetooth", e);
+ } finally {
+ mBluetoothLock.readLock().unlock();
+ }
+ return false;
+ }
+
private final ContentObserver mAirplaneModeObserver = new ContentObserver(null) {
@Override
public void onChange(boolean unused) {
@@ -1627,7 +1671,9 @@
// the previous Bluetooth process has exited. The
// waiting period has three components:
// (a) Wait until the local state is STATE_OFF. This
- // is accomplished by "waitForOnOff(false, true)".
+ // is accomplished by
+ // "waitForState(new HashSet<Integer>(
+ // Arrays.asList(BluetoothAdapter.STATE_OFF)))".
// (b) Wait until the STATE_OFF state is updated to
// all components.
// (c) Wait until the Bluetooth process exits, and
@@ -1637,7 +1683,8 @@
// message. On slower devices, that delay needs to be
// on the order of (2 * SERVICE_RESTART_TIME_MS).
//
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
@@ -1650,10 +1697,16 @@
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
if (mEnable && mBluetooth != null) {
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
mEnable = false;
handleDisable();
- waitForOnOff(false, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF,
+ BluetoothAdapter.STATE_TURNING_ON,
+ BluetoothAdapter.STATE_TURNING_OFF,
+ BluetoothAdapter.STATE_BLE_TURNING_ON,
+ BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_BLE_TURNING_OFF)));
} else {
mEnable = false;
handleDisable();
@@ -1782,9 +1835,15 @@
}
if (!mEnable) {
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
handleDisable();
- waitForOnOff(false, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF,
+ BluetoothAdapter.STATE_TURNING_ON,
+ BluetoothAdapter.STATE_TURNING_OFF,
+ BluetoothAdapter.STATE_BLE_TURNING_ON,
+ BluetoothAdapter.STATE_BLE_ON,
+ BluetoothAdapter.STATE_BLE_TURNING_OFF)));
}
break;
}
@@ -1816,7 +1875,8 @@
== BluetoothAdapter.STATE_OFF)) {
if (mEnable) {
Slog.d(TAG, "Entering STATE_OFF but mEnabled is true; restarting.");
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
Message restartMsg =
mHandler.obtainMessage(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mHandler.sendMessageDelayed(restartMsg, 2 * SERVICE_RESTART_TIME_MS);
@@ -1939,7 +1999,8 @@
mState = BluetoothAdapter.STATE_TURNING_ON;
}
- waitForOnOff(true, false);
+ waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_ON)));
if (mState == BluetoothAdapter.STATE_TURNING_ON) {
bluetoothStateChangeHandler(mState, BluetoothAdapter.STATE_ON);
@@ -1954,7 +2015,9 @@
bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
BluetoothAdapter.STATE_TURNING_OFF);
- boolean didDisableTimeout = !waitForOnOff(false, true);
+ boolean didDisableTimeout =
+ !waitForState(new HashSet<Integer>(Arrays.asList(
+ BluetoothAdapter.STATE_OFF)));
bluetoothStateChangeHandler(BluetoothAdapter.STATE_TURNING_OFF,
BluetoothAdapter.STATE_OFF);
@@ -2206,12 +2269,7 @@
}
}
- /**
- * if on is true, wait for state become ON
- * if off is true, wait for state become OFF
- * if both on and off are false, wait for state not ON
- */
- private boolean waitForOnOff(boolean on, boolean off) {
+ private boolean waitForState(Set<Integer> states) {
int i = 0;
while (i < 10) {
try {
@@ -2219,18 +2277,8 @@
if (mBluetooth == null) {
break;
}
- if (on) {
- if (mBluetooth.getState() == BluetoothAdapter.STATE_ON) {
- return true;
- }
- } else if (off) {
- if (mBluetooth.getState() == BluetoothAdapter.STATE_OFF) {
- return true;
- }
- } else {
- if (mBluetooth.getState() != BluetoothAdapter.STATE_ON) {
- return true;
- }
+ if (states.contains(mBluetooth.getState())) {
+ return true;
}
} catch (RemoteException e) {
Slog.e(TAG, "getState()", e);
@@ -2238,14 +2286,10 @@
} finally {
mBluetoothLock.readLock().unlock();
}
- if (on || off) {
- SystemClock.sleep(300);
- } else {
- SystemClock.sleep(50);
- }
+ SystemClock.sleep(300);
i++;
}
- Slog.e(TAG, "waitForOnOff time out");
+ Slog.e(TAG, "waitForState " + states + " time out");
return false;
}
@@ -2306,7 +2350,7 @@
mContext.getPackageName(), false);
handleDisable();
- waitForOnOff(false, true);
+ waitForState(new HashSet<Integer>(Arrays.asList(BluetoothAdapter.STATE_OFF)));
sendBluetoothServiceDownCallback();
@@ -2468,6 +2512,8 @@
return "USER_SWITCH";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_RESTORE_USER_SETTING:
return "RESTORE_USER_SETTING";
+ case BluetoothProtoEnums.ENABLE_DISABLE_REASON_FACTORY_RESET:
+ return "FACTORY_RESET";
case BluetoothProtoEnums.ENABLE_DISABLE_REASON_UNSPECIFIED:
default: return "UNKNOWN[" + reason + "]";
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 2e4fe55..f9a955e 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2426,7 +2426,7 @@
* most important plan. Any additional plans are secondary and
* may not be displayed or used by decision making logic.
* The list of all plans must meet the requirements defined in
- * {@link SubscriptionPlan.Builder#setNetworkTypes(int[])}.
+ * SubscriptionPlan.Builder#setNetworkTypes(int[]).
* @throws SecurityException if the caller doesn't meet the requirements
* outlined above.
* @throws IllegalArgumentException if plans don't meet the requirements