diff options
3 files changed, 77 insertions, 37 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 35e7ee6..296d70a4 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -78,6 +78,15 @@ public class DevicePolicyManager { = "android.app.action.ADD_DEVICE_ADMIN"; /** + * Activity action: send when any policy admin changes a policy. + * This is generally used to find out when a new policy is in effect. + * + * @hide + */ + public static final String ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED + = "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED"; + + /** * The ComponentName of the administrator component. * * @see #ACTION_ADD_DEVICE_ADMIN diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java index 7fb7db0..19d146d 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/java/com/android/server/DevicePolicyManagerService.java @@ -367,6 +367,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.endDocument(); stream.close(); journal.commit(); + sendChangedNotification(); } catch (IOException e) { try { if (stream != null) { @@ -379,6 +380,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private void sendChangedNotification() { + Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); + intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mContext.sendBroadcast(intent); + } + private void loadSettingsLocked() { JournaledFile journal = makeJournaledFile(); FileInputStream stream = null; diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index e13f0af..a8dad88 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -55,7 +55,10 @@ import android.Manifest; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.app.admin.DevicePolicyManager; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.CompatibilityInfo; @@ -235,11 +238,20 @@ public class WindowManagerService extends IWindowManager.Stub */ private boolean mKeyguardDisabled = false; + private static final int ALLOW_DISABLE_YES = 1; + private static final int ALLOW_DISABLE_NO = 0; + private static final int ALLOW_DISABLE_UNKNOWN = -1; // check with DevicePolicyManager + private int mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; // sync'd by mKeyguardTokenWatcher + final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher( new Handler(), "WindowManagerService.mKeyguardTokenWatcher") { public void acquired() { - mPolicy.enableKeyguard(false); - mKeyguardDisabled = true; + if (shouldAllowDisableKeyguard()) { + mPolicy.enableKeyguard(false); + mKeyguardDisabled = true; + } else { + Log.v(TAG, "Not disabling keyguard since device policy is enforced"); + } } public void released() { mPolicy.enableKeyguard(true); @@ -250,6 +262,18 @@ public class WindowManagerService extends IWindowManager.Stub } }; + final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mPolicy.enableKeyguard(true); + synchronized(mKeyguardTokenWatcher) { + // lazily evaluate this next time we're asked to disable keyguard + mAllowDisableKeyguard = ALLOW_DISABLE_UNKNOWN; + mKeyguardDisabled = false; + } + } + }; + final Context mContext; final boolean mHaveInputMethods; @@ -610,6 +634,11 @@ public class WindowManagerService extends IWindowManager.Stub mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(), Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale); + // Track changes to DevicePolicyManager state so we can enable/disable keyguard. + IntentFilter filter = new IntentFilter(); + filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); + mContext.registerReceiver(mBroadcastReceiver, filter); + int max_events_per_sec = 35; try { max_events_per_sec = Integer.parseInt(SystemProperties @@ -4173,17 +4202,20 @@ public class WindowManagerService extends IWindowManager.Stub // Misc IWindowSession methods // ------------------------------------------------------------- - private boolean allowDisableKeyguard() + private boolean shouldAllowDisableKeyguard() { - // We fail safe if this gets called before the service has started. - boolean allow = false; - DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( - Context.DEVICE_POLICY_SERVICE); - if (dpm != null) { - allow = dpm.getPasswordQuality(null) - == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; + // We fail safe and prevent disabling keyguard in the unlikely event this gets + // called before DevicePolicyManagerService has started. + if (mAllowDisableKeyguard == ALLOW_DISABLE_UNKNOWN) { + DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService( + Context.DEVICE_POLICY_SERVICE); + if (dpm != null) { + mAllowDisableKeyguard = dpm.getPasswordQuality(null) + == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED ? + ALLOW_DISABLE_YES : ALLOW_DISABLE_NO; + } } - return allow; + return mAllowDisableKeyguard == ALLOW_DISABLE_YES; } public void disableKeyguard(IBinder token, String tag) { @@ -4192,12 +4224,8 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires DISABLE_KEYGUARD permission"); } - if (allowDisableKeyguard()) { - synchronized (mKeyguardTokenWatcher) { - mKeyguardTokenWatcher.acquire(token, tag); - } - } else { - Log.w(TAG, tag + ": disableKeyguard() ignored while DevicePolicyAmin is enabled."); + synchronized (mKeyguardTokenWatcher) { + mKeyguardTokenWatcher.acquire(token, tag); } } @@ -4207,29 +4235,25 @@ public class WindowManagerService extends IWindowManager.Stub throw new SecurityException("Requires DISABLE_KEYGUARD permission"); } - if (allowDisableKeyguard()) { - synchronized (mKeyguardTokenWatcher) { - mKeyguardTokenWatcher.release(token); - - if (!mKeyguardTokenWatcher.isAcquired()) { - // If we are the last one to reenable the keyguard wait until - // we have actaully finished reenabling until returning. - // It is possible that reenableKeyguard() can be called before - // the previous disableKeyguard() is handled, in which case - // neither mKeyguardTokenWatcher.acquired() or released() would - // be called. In that case mKeyguardDisabled will be false here - // and we have nothing to wait for. - while (mKeyguardDisabled) { - try { - mKeyguardTokenWatcher.wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } + synchronized (mKeyguardTokenWatcher) { + mKeyguardTokenWatcher.release(token); + + if (!mKeyguardTokenWatcher.isAcquired()) { + // If we are the last one to reenable the keyguard wait until + // we have actually finished reenabling until returning. + // It is possible that reenableKeyguard() can be called before + // the previous disableKeyguard() is handled, in which case + // neither mKeyguardTokenWatcher.acquired() or released() would + // be called. In that case mKeyguardDisabled will be false here + // and we have nothing to wait for. + while (mKeyguardDisabled) { + try { + mKeyguardTokenWatcher.wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } } - } else { - Log.w(TAG, "reenableKeyguard() ignored while DevicePolicyAmin is enabled."); } } |