Merge "Fix issue #23037899: Support for Battery Optimization permission + Dialog" into mnc-dev
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index e74334b..b9a9c24 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -148,7 +148,10 @@
private WifiManager mWfm;
private static String mWifiConfigFile;
+ // Chain of asynchronous operations used when rewriting the wifi supplicant config file
+ WifiDisableRunnable mWifiDisable = null;
WifiRestoreRunnable mWifiRestore = null;
+ int mRetainedWifiState; // used only during config file rewrite
// Class for capturing a network definition from the wifi supplicant config file
static class Network {
@@ -407,9 +410,47 @@
writeNewChecksums(stateChecksums, newState);
}
+ class WifiDisableRunnable implements Runnable {
+ final WifiRestoreRunnable mNextPhase;
+
+ public WifiDisableRunnable(WifiRestoreRunnable next) {
+ mNextPhase = next;
+ }
+
+ @Override
+ public void run() {
+ if (DEBUG_BACKUP) {
+ Log.v(TAG, "Disabling wifi during restore");
+ }
+ final ContentResolver cr = getContentResolver();
+ final int scanAlways = Settings.Global.getInt(cr,
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+ final int retainedWifiState = enableWifi(false);
+ if (scanAlways != 0) {
+ Settings.Global.putInt(cr,
+ Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
+ }
+
+ // Tell the final stage how to clean up after itself
+ mNextPhase.setPriorState(retainedWifiState, scanAlways);
+
+ // And run it after a modest pause to give broadcasts and content
+ // observers time an opportunity to run on this looper thread, so
+ // that the wifi stack actually goes all the way down.
+ new Handler(getMainLooper()).postDelayed(mNextPhase, 2500);
+ }
+ }
+
class WifiRestoreRunnable implements Runnable {
private byte[] restoredSupplicantData;
private byte[] restoredWifiConfigFile;
+ private int retainedWifiState; // provided by disable stage
+ private int scanAlways; // provided by disable stage
+
+ void setPriorState(int retainedState, int always) {
+ retainedWifiState = retainedState;
+ scanAlways = always;
+ }
void incorporateWifiSupplicant(BackupDataInput data) {
restoredSupplicantData = new byte[data.getDataSize()];
@@ -437,20 +478,8 @@
public void run() {
if (restoredSupplicantData != null || restoredWifiConfigFile != null) {
if (DEBUG_BACKUP) {
- Log.v(TAG, "Starting deferred restore of wifi data");
+ Log.v(TAG, "Applying restored wifi data");
}
- final ContentResolver cr = getContentResolver();
- final int scanAlways = Settings.Global.getInt(cr,
- Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
- final int retainedWifiState = enableWifi(false);
- if (scanAlways != 0) {
- Settings.Global.putInt(cr,
- Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0);
- }
- // !!! Give the wifi stack a moment to quiesce. We've observed the
- // response to disabling WIFI_SCAN_ALWAYS_AVAILABLE taking more
- // than 1500ms, so we wait a generous 2500 here before proceeding.
- try { Thread.sleep(2500); } catch (InterruptedException e) {}
if (restoredSupplicantData != null) {
restoreWifiSupplicant(FILE_WIFI_SUPPLICANT,
restoredSupplicantData, restoredSupplicantData.length);
@@ -465,7 +494,7 @@
}
// restore the previous WIFI state.
if (scanAlways != 0) {
- Settings.Global.putInt(cr,
+ Settings.Global.putInt(getContentResolver(),
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, scanAlways);
}
enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED ||
@@ -479,6 +508,7 @@
void initWifiRestoreIfNecessary() {
if (mWifiRestore == null) {
mWifiRestore = new WifiRestoreRunnable();
+ mWifiDisable = new WifiDisableRunnable(mWifiRestore);
}
}
@@ -518,13 +548,16 @@
}
// If we have wifi data to restore, post a runnable to perform the
- // bounce-and-update operation a little ways in the future.
+ // bounce-and-update operation a little ways in the future. The
+ // 'disable' runnable brings down the stack and remembers its state,
+ // and in turn schedules the 'restore' runnable to do the rewrite
+ // and cleanup operations.
if (mWifiRestore != null) {
long wifiBounceDelayMillis = Settings.Global.getLong(
getContentResolver(),
Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
WIFI_BOUNCE_DELAY_MILLIS);
- new Handler(getMainLooper()).postDelayed(mWifiRestore, wifiBounceDelayMillis);
+ new Handler(getMainLooper()).postDelayed(mWifiDisable, wifiBounceDelayMillis);
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 83e8db0..aab6374 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2604,7 +2604,8 @@
// Prune the list down to just the requested type.
visibleAccountTypes = new ArrayList<>();
visibleAccountTypes.add(type);
- } // else aggregate all the visible accounts (it won't matter if the list is empty).
+ } // else aggregate all the visible accounts (it won't matter if the
+ // list is empty).
long identityToken = clearCallingIdentity();
try {
@@ -3788,8 +3789,15 @@
private List<String> getTypesForCaller(
int callingUid, int userId, boolean isOtherwisePermitted) {
List<String> managedAccountTypes = new ArrayList<>();
+ long identityToken = Binder.clearCallingIdentity();
+ Collection<RegisteredServicesCache.ServiceInfo<AuthenticatorDescription>> serviceInfos;
+ try {
+ serviceInfos = mAuthenticatorCache.getAllServices(userId);
+ } finally {
+ Binder.restoreCallingIdentity(identityToken);
+ }
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> serviceInfo :
- mAuthenticatorCache.getAllServices(userId)) {
+ serviceInfos) {
final int sigChk = mPackageManager.checkSignatures(serviceInfo.uid, callingUid);
if (isOtherwisePermitted || sigChk == PackageManager.SIGNATURE_MATCH) {
managedAccountTypes.add(serviceInfo.type.type);
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 8e2ca18..92df851 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -108,6 +108,7 @@
private AlarmManager mAlarm;
private PendingIntent mIdleTriggerIntent;
boolean mIdle;
+ boolean mScreenOn;
public IdlenessTracker() {
mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
@@ -120,6 +121,7 @@
// At boot we presume that the user has just "interacted" with the
// device in some meaningful way.
mIdle = false;
+ mScreenOn = true;
}
public boolean isIdle() {
@@ -149,12 +151,14 @@
if (action.equals(Intent.ACTION_SCREEN_ON)
|| action.equals(Intent.ACTION_DREAMING_STOPPED)) {
- // possible transition to not-idle
+ if (DEBUG) {
+ Slog.v(TAG,"exiting idle : " + action);
+ }
+ mScreenOn = true;
+ //cancel the alarm
+ mAlarm.cancel(mIdleTriggerIntent);
if (mIdle) {
- if (DEBUG) {
- Slog.v(TAG, "exiting idle : " + action);
- }
- mAlarm.cancel(mIdleTriggerIntent);
+ // possible transition to not-idle
mIdle = false;
reportNewIdleState(mIdle);
}
@@ -169,11 +173,12 @@
Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+ when);
}
+ mScreenOn = false;
mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
when, IDLE_WINDOW_SLOP, mIdleTriggerIntent);
} else if (action.equals(ACTION_TRIGGER_IDLE)) {
- // idle time starts now
- if (!mIdle) {
+ // idle time starts now. Do not set mIdle if screen is on.
+ if (!mIdle && !mScreenOn) {
if (DEBUG) {
Slog.v(TAG, "Idle trigger fired @ " + SystemClock.elapsedRealtime());
}