diff options
Diffstat (limited to 'services')
3 files changed, 94 insertions, 34 deletions
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index bebd013..2651fd3 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -198,22 +198,26 @@ class BackupManagerService extends IBackupManager.Stub { public long token; public PackageInfo pkgInfo; public int pmToken; // in post-install restore, the PM's token for this transaction + public boolean needFullBackup; RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, - long _token, PackageInfo _pkg, int _pmToken) { + long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) { transport = _transport; observer = _obs; token = _token; pkgInfo = _pkg; pmToken = _pmToken; + needFullBackup = _needFullBackup; } - RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token) { + RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token, + boolean _needFullBackup) { transport = _transport; observer = _obs; token = _token; pkgInfo = null; pmToken = 0; + needFullBackup = _needFullBackup; } } @@ -323,7 +327,8 @@ class BackupManagerService extends IBackupManager.Stub { RestoreParams params = (RestoreParams)msg.obj; Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer); (new PerformRestoreTask(params.transport, params.observer, - params.token, params.pkgInfo, params.pmToken)).run(); + params.token, params.pkgInfo, params.pmToken, + params.needFullBackup)).run(); break; } @@ -1560,6 +1565,7 @@ class BackupManagerService extends IBackupManager.Stub { private PackageInfo mTargetPackage; private File mStateDir; private int mPmToken; + private boolean mNeedFullBackup; class RestoreRequest { public PackageInfo app; @@ -1572,12 +1578,14 @@ class BackupManagerService extends IBackupManager.Stub { } PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer, - long restoreSetToken, PackageInfo targetPackage, int pmToken) { + long restoreSetToken, PackageInfo targetPackage, int pmToken, + boolean needFullBackup) { mTransport = transport; mObserver = observer; mToken = restoreSetToken; mTargetPackage = targetPackage; mPmToken = pmToken; + mNeedFullBackup = needFullBackup; try { mStateDir = new File(mBaseStateDir, transport.transportDirName()); @@ -1655,7 +1663,8 @@ class BackupManagerService extends IBackupManager.Stub { // Pull the Package Manager metadata from the restore set first pmAgent = new PackageManagerBackupAgent( mPackageManager, agentPackages); - processOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(pmAgent.onBind())); + processOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(pmAgent.onBind()), + mNeedFullBackup); // Verify that the backup set includes metadata. If not, we can't do // signature/version verification etc, so we simply do not proceed with @@ -1752,7 +1761,8 @@ class BackupManagerService extends IBackupManager.Stub { // And then finally run the restore on this agent try { - processOneRestore(packageInfo, metaInfo.versionCode, agent); + processOneRestore(packageInfo, metaInfo.versionCode, agent, + mNeedFullBackup); ++count; } finally { // unbind and tidy up even on timeout or failure, just in case @@ -1822,7 +1832,8 @@ class BackupManagerService extends IBackupManager.Stub { } // Do the guts of a restore of one application, using mTransport.getRestoreData(). - void processOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent) { + void processOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent, + boolean needFullBackup) { // !!! TODO: actually run the restore through mTransport final String packageName = app.packageName; @@ -1901,6 +1912,14 @@ class BackupManagerService extends IBackupManager.Stub { try { if (newState != null) newState.close(); } catch (IOException e) {} backupData = newState = null; mCurrentOperations.delete(token); + + // If we know a priori that we'll need to perform a full post-restore backup + // pass, clear the new state file data. This means we're discarding work that + // was just done by the app's agent, but this way the agent doesn't need to + // take any special action based on global device state. + if (needFullBackup) { + newStateName.delete(); + } } } } @@ -2386,7 +2405,7 @@ class BackupManagerService extends IBackupManager.Stub { mWakelock.acquire(); Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); msg.obj = new RestoreParams(getTransport(mCurrentTransport), null, - restoreSet, pkg, token); + restoreSet, pkg, token, true); mBackupHandler.sendMessage(msg); } else { // Auto-restore disabled or no way to attempt a restore; just tell the Package @@ -2517,7 +2536,7 @@ class BackupManagerService extends IBackupManager.Stub { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); - msg.obj = new RestoreParams(mRestoreTransport, observer, token); + msg.obj = new RestoreParams(mRestoreTransport, observer, token, true); mBackupHandler.sendMessage(msg); Binder.restoreCallingIdentity(oldId); return 0; @@ -2582,7 +2601,7 @@ class BackupManagerService extends IBackupManager.Stub { long oldId = Binder.clearCallingIdentity(); mWakelock.acquire(); Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); - msg.obj = new RestoreParams(mRestoreTransport, observer, token, app, 0); + msg.obj = new RestoreParams(mRestoreTransport, observer, token, app, 0, false); mBackupHandler.sendMessage(msg); Binder.restoreCallingIdentity(oldId); return 0; diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java index 53a19f5..0dead1c 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/java/com/android/server/DevicePolicyManagerService.java @@ -407,17 +407,29 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { context.registerReceiver(mReceiver, filter); } + /** + * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration + * reminders. Clears alarm if no expirations are configured. + */ protected void setExpirationAlarmCheckLocked(Context context) { final long expiration = getPasswordExpirationLocked(null); final long now = System.currentTimeMillis(); final long timeToExpire = expiration - now; final long alarmTime; - if (timeToExpire > 0L && timeToExpire < MS_PER_DAY) { - // Next expiration is less than a day, set alarm for exact expiration time - alarmTime = now + timeToExpire; - } else { - // Check again in 24 hours... + if (expiration == 0) { + // No expirations are currently configured: Cancel alarm. + alarmTime = 0; + } else if (timeToExpire <= 0) { + // The password has already expired: Repeat every 24 hours. alarmTime = now + MS_PER_DAY; + } else { + // Selecting the next alarm time: Roll forward to the next 24 hour multiple before + // the expiration time. + long alarmInterval = timeToExpire % MS_PER_DAY; + if (alarmInterval == 0) { + alarmInterval = MS_PER_DAY; + } + alarmTime = now + alarmInterval; } long token = Binder.clearCallingIdentity(); @@ -427,7 +439,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION), PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); am.cancel(pi); - am.set(AlarmManager.RTC, alarmTime, pi); + if (alarmTime != 0) { + am.set(AlarmManager.RTC, alarmTime, pi); + } } finally { Binder.restoreCallingIdentity(token); } @@ -794,7 +808,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD) && admin.passwordExpirationTimeout > 0L && admin.passwordExpirationDate > 0L - && now > admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) { + && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) { sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING); } } @@ -1007,14 +1021,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + /** + * Return a single admin's expiration cycle time, or the min of all cycle times. + * Returns 0 if not configured. + */ public long getPasswordExpirationTimeout(ComponentName who) { synchronized (this) { - long timeout = 0L; if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who); - return admin != null ? admin.passwordExpirationTimeout : timeout; + return admin != null ? admin.passwordExpirationTimeout : 0L; } + long timeout = 0L; final int N = mAdminList.size(); for (int i = 0; i < N; i++) { ActiveAdmin admin = mAdminList.get(i); @@ -1027,13 +1045,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + /** + * Return a single admin's expiration date/time, or the min (soonest) for all admins. + * Returns 0 if not configured. + */ private long getPasswordExpirationLocked(ComponentName who) { - long timeout = 0L; if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who); - return admin != null ? admin.passwordExpirationDate : timeout; + return admin != null ? admin.passwordExpirationDate : 0L; } + long timeout = 0L; final int N = mAdminList.size(); for (int i = 0; i < N; i++) { ActiveAdmin admin = mAdminList.get(i); @@ -1606,6 +1628,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mFailedPasswordAttempts = 0; saveSettingsLocked(); updatePasswordExpirationsLocked(); + setExpirationAlarmCheckLocked(mContext); sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); } finally { @@ -1615,14 +1638,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + /** + * Called any time the device password is updated. Resets all password expiration clocks. + */ private void updatePasswordExpirationsLocked() { final int N = mAdminList.size(); if (N > 0) { for (int i=0; i<N; i++) { ActiveAdmin admin = mAdminList.get(i); if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) { - admin.passwordExpirationDate = System.currentTimeMillis() - + admin.passwordExpirationTimeout; + long timeout = admin.passwordExpirationTimeout; + long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L; + admin.passwordExpirationDate = expiration; } } saveSettingsLocked(); diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index c7bfdc8..95200fa 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -55,7 +55,6 @@ import android.os.IBinder; import android.os.IInterface; import android.os.Message; import android.os.Parcel; -import android.os.Parcelable; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ServiceManager; @@ -125,6 +124,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final String SUBTYPE_MODE_VOICE = "voice"; final Context mContext; + final Resources mRes; final Handler mHandler; final InputMethodSettings mSettings; final SettingsObserver mSettingsObserver; @@ -468,6 +468,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub public InputMethodManagerService(Context context, StatusBarManagerService statusBar) { mContext = context; + mRes = context.getResources(); mHandler = new Handler(this); mIWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); @@ -1214,11 +1215,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } mCurFocusedWindow = windowToken; + // Should we auto-show the IME even if the caller has not + // specified what should be done with it? + // We only do this automatically if the window can resize + // to accommodate the IME (so what the user sees will give + // them good context without input information being obscured + // by the IME) or if running on a large screen where there + // is more room for the target window + IME. + final boolean doAutoShow = + (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) + == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE + || mRes.getConfiguration().isLayoutSizeAtLeast( + Configuration.SCREENLAYOUT_SIZE_LARGE); + switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) { case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: - if (!isTextEditor || (softInputMode & - WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) - != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) { + if (!isTextEditor || !doAutoShow) { if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) { // There is no focus view, and this window will // be behind any soft input window, so hide the @@ -1226,13 +1238,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (DEBUG) Slog.v(TAG, "Unspecified window will hide input"); hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null); } - } else if (isTextEditor && (softInputMode & - WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) - == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE - && (softInputMode & - WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { + } else if (isTextEditor && doAutoShow && (softInputMode & + WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { // There is a focus view, and we are navigating forward // into the window, so show the input window for the user. + // We only do this automatically if the window an resize + // to accomodate the IME (so what the user sees will give + // them good context without input information being obscured + // by the IME) or if running on a large screen where there + // is more room for the target window + IME. if (DEBUG) Slog.v(TAG, "Unspecified window will show input"); showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null); } @@ -1544,7 +1558,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub map.clear(); PackageManager pm = mContext.getPackageManager(); - final Configuration config = mContext.getResources().getConfiguration(); + final Configuration config = mRes.getConfiguration(); final boolean haveHardKeyboard = config.keyboard == Configuration.KEYBOARD_QWERTY; String disabledSysImes = Settings.Secure.getString(mContext.getContentResolver(), Secure.DISABLED_SYSTEM_INPUT_METHODS); @@ -1944,7 +1958,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return null; } if (TextUtils.isEmpty(locale)) { - locale = mContext.getResources().getConfiguration().locale.toString(); + locale = mRes.getConfiguration().locale.toString(); } final String language = locale.substring(0, 2); boolean partialMatchFound = false; |