From 307941c0fdb03f316693142a0076345e9be52add Mon Sep 17 00:00:00 2001 From: Roman Birg Date: Mon, 10 Aug 2015 11:18:55 -0700 Subject: [PATCH] cmsdk: fix enabling/disabling keyguard We cannot create a new WindowManagerPolicy every time since the method isn't called from the main thread every time, which could lead to exceptions being thrown when trying to create PhoneWindowManager. Instead of creating a new policy, bind to the keyguard service on bind, and then pass it to the profile to operate on. Ref: NIGHTLIES-1640 Change-Id: I3ac58bfa534755eaa73890cc5ddf05987a7d0d8c Signed-off-by: Roman Birg --- .../internal/ProfileManagerService.java | 44 ++++++++++++++++++- src/java/cyanogenmod/app/Profile.java | 11 +++-- .../cyanogenmod/profiles/LockSettings.java | 38 ++++++++++------ 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java index 8b8bf4c9..e8affd19 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/ProfileManagerService.java @@ -16,6 +16,9 @@ package org.cyanogenmod.platform.internal; +import android.content.ComponentName; +import android.content.ServiceConnection; +import com.android.internal.policy.IKeyguardService; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserFactory; @@ -63,6 +66,9 @@ public class ProfileManagerService extends SystemService { public static final String PERMISSION_CHANGE_SETTINGS = "android.permission.WRITE_SETTINGS"; + public static final String KEYGUARD_PACKAGE = "com.android.systemui"; + public static final String KEYGUARD_CLASS = "com.android.systemui.keyguard.KeyguardService"; + /* package */ static final File PROFILE_FILE = new File(Environment.getSystemSecureDirectory(), "profiles.xml"); @@ -86,6 +92,30 @@ public class ProfileManagerService extends SystemService { private BackupManager mBackupManager; private ProfileTriggerHelper mTriggerHelper; + private Runnable mBindKeyguard = new Runnable() { + @Override + public void run() { + bindKeyguard(); + } + }; + private IKeyguardService mKeyguardService; + private final ServiceConnection mKeyguardConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (LOCAL_LOGV) Log.v(TAG, "*** Keyguard connected (yay!)"); + mKeyguardService = IKeyguardService.Stub.asInterface(service); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (LOCAL_LOGV) Log.v(TAG, "*** Keyguard disconnected, retrying connection soon."); + mKeyguardService = null; + // system UI died? retry connection in 5s + mHandler.removeCallbacks(mBindKeyguard); + mHandler.postDelayed(mBindKeyguard, 5000); + } + }; + private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -123,11 +153,23 @@ public class ProfileManagerService extends SystemService { mContext.registerReceiver(mIntentReceiver, filter); } + private void bindKeyguard() { + if (mKeyguardService == null) { + Intent intent = new Intent(); + intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS); + if (!mContext.bindServiceAsUser(intent, mKeyguardConnection, + Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) { + Log.e(TAG, "error binding to keyguard service"); + } + } + } + private void initialize() { initialize(false); } private void initialize(boolean skipFile) { + bindKeyguard(); mTriggerHelper = new ProfileTriggerHelper(mContext, mHandler, this); mProfiles = new HashMap(); mProfileNames = new HashMap(); @@ -588,7 +630,7 @@ public class ProfileManagerService extends SystemService { if (doInit) { if (LOCAL_LOGV) Log.v(TAG, "setActiveProfile(Profile, boolean) - Running init"); // Call profile's "doSelect" - mActiveProfile.doSelect(mContext); + mActiveProfile.doSelect(mContext, mKeyguardService); // Notify other applications of newly selected profile. Intent broadcast = new Intent(ProfileManager.INTENT_ACTION_PROFILE_SELECTED); diff --git a/src/java/cyanogenmod/app/Profile.java b/src/java/cyanogenmod/app/Profile.java index bd51ca2a..908110a5 100755 --- a/src/java/cyanogenmod/app/Profile.java +++ b/src/java/cyanogenmod/app/Profile.java @@ -26,6 +26,7 @@ import android.provider.Settings; import android.text.TextUtils; import android.util.Log; +import com.android.internal.policy.IKeyguardService; import cyanogenmod.os.Build; import cyanogenmod.profiles.AirplaneModeSettings; import cyanogenmod.profiles.BrightnessSettings; @@ -1168,7 +1169,7 @@ public final class Profile implements Parcelable, Comparable { } /** @hide */ - public void doSelect(Context context) { + public void doSelect(Context context, IKeyguardService keyguardService) { // Set stream volumes AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); for (StreamSettings sd : streams.values()) { @@ -1190,8 +1191,12 @@ public final class Profile implements Parcelable, Comparable { // Set brightness mBrightness.processOverride(context); - // Set lock screen mode - mScreenLockMode.processOverride(context); + if (keyguardService != null) { + // Set lock screen mode + mScreenLockMode.processOverride(context, keyguardService); + } else { + Log.e(TAG, "cannot process screen lock override without a keyguard service."); + } // Set expanded desktop // if (mExpandedDesktopMode != ExpandedDesktopMode.DEFAULT) { diff --git a/src/java/cyanogenmod/profiles/LockSettings.java b/src/java/cyanogenmod/profiles/LockSettings.java index 1d5cf33b..6c1599aa 100644 --- a/src/java/cyanogenmod/profiles/LockSettings.java +++ b/src/java/cyanogenmod/profiles/LockSettings.java @@ -20,7 +20,12 @@ import android.app.admin.DevicePolicyManager; import android.content.Context; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Log; import android.view.WindowManagerPolicy; +import android.view.WindowManagerPolicyControl; +import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.PolicyManager; import cyanogenmod.app.Profile; import cyanogenmod.os.Build; @@ -38,6 +43,8 @@ import cyanogenmod.os.Build; */ public final class LockSettings implements Parcelable { + private static final String TAG = LockSettings.class.getSimpleName(); + private int mValue; private boolean mDirty; @@ -101,24 +108,29 @@ public final class LockSettings implements Parcelable { } /** @hide */ - public void processOverride(Context context) { + public void processOverride(Context context, IKeyguardService keyguard) { + boolean enable; final DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); - final WindowManagerPolicy policy = PolicyManager.makeNewWindowManager(); - if (devicePolicyManager != null && devicePolicyManager.requireSecureKeyguard()) { - policy.enableKeyguard(true); - return; + enable = true; + } else { + switch (mValue) { + default: + case Profile.LockMode.DEFAULT: + case Profile.LockMode.INSECURE: + enable = true; + break; + case Profile.LockMode.DISABLE: + enable = false; + break; + } } - switch (mValue) { - case Profile.LockMode.DEFAULT: - case Profile.LockMode.INSECURE: - policy.enableKeyguard(true); - break; - case Profile.LockMode.DISABLE: - policy.enableKeyguard(false); - break; + try { + keyguard.setKeyguardEnabled(enable); + } catch (RemoteException e) { + Log.w(TAG, "unable to set keyguard enabled state to: " + enable, e); } }