summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Miller <jaggies@google.com>2010-06-08 14:27:42 -0700
committerJim Miller <jaggies@google.com>2010-06-08 15:47:52 -0700
commit284b62e1b8c3419bfd02c6fea5ba0a68146c06f8 (patch)
tree8eb35ad894780e15c7b79acb8fbe455e7c76e8e4
parentcb52cb52253c3832ccc7f5f1dbb4d8a0bd8178c0 (diff)
downloadframeworks_base-284b62e1b8c3419bfd02c6fea5ba0a68146c06f8.zip
frameworks_base-284b62e1b8c3419bfd02c6fea5ba0a68146c06f8.tar.gz
frameworks_base-284b62e1b8c3419bfd02c6fea5ba0a68146c06f8.tar.bz2
Fix 2737842: Disable KeguardManager API if device policy is enabled
This change adds notification to find out when the device policy has changed. When an admin adds or changes a policy, we get notified and reset the state of keyguard to be enabled. It also moves disabling keyguard into the TokenWatcher.acquired() method to avoid disabling keyguard when a policy doesn't permit it. This avoids reference counting issues in TokenWatcher and hence relieves the ordering issue. There is one remaining caveat. An application that uses KeyguardManager to disable keyguard will need to disable keyguard again after any policy change. Tested: Install and run app that disables keyguard with no admin. Result: keyguard is enabled/disabled as expected. Enable admin and set quality = "something" after installing & running app. Result: keyguard is enabled. Change admin password quality to "unspecified" and re-run app (per caveat). Result: keyguard is disabled. Change admin password quality to "something" again. Result: keyguard is enabled. Disable admin : Result: keyguard is enabled until app runs again (per caveat). Added minor cosmetic changes after review. Change-Id: I302f2b01446bf031f746b0f3e8b5fd7a6cc0e648
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java9
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java7
-rw-r--r--services/java/com/android/server/WindowManagerService.java98
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.");
}
}