Make IKeyguardService interface asynchronous
Add a state callback so lockscreen reports back whenever its state
relevant for PhoneWindowManager changed, instead of synchronously
calling into SysUI which can lead to deadlocks. Directly use
LockPatternUtils for isSecure, and optimize the number of calls to
this method to optimize layout performance.
Bug: 17677097
Change-Id: I5d491fc8884d4f84d9562626b9ea0d5eaa5166fc
diff --git a/Android.mk b/Android.mk
index 327a371..ce72a85 100644
--- a/Android.mk
+++ b/Android.mk
@@ -273,6 +273,7 @@
core/java/com/android/internal/policy/IKeyguardShowCallback.aidl \
core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
core/java/com/android/internal/policy/IKeyguardService.aidl \
+ core/java/com/android/internal/policy/IKeyguardStateCallback.aidl \
core/java/com/android/internal/os/IDropBoxManagerService.aidl \
core/java/com/android/internal/os/IParcelFileDescriptorFactory.aidl \
core/java/com/android/internal/os/IResultReceiver.aidl \
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index 64f3bea..f93b1a1 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -15,47 +15,34 @@
*/
package com.android.internal.policy;
-import android.view.MotionEvent;
-
import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import android.os.Bundle;
-interface IKeyguardService {
- boolean isShowing();
- boolean isSecure();
- boolean isShowingAndNotOccluded();
- boolean isInputRestricted();
- boolean isDismissable();
- oneway void verifyUnlock(IKeyguardExitCallback callback);
- oneway void keyguardDone(boolean authenticated, boolean wakeup);
-
+oneway interface IKeyguardService {
/**
* Sets the Keyguard as occluded when a window dismisses the Keyguard with flag
* FLAG_SHOW_ON_LOCK_SCREEN.
*
* @param isOccluded Whether the Keyguard is occluded by another window.
- * @return See IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_*. This is needed because
- * PhoneWindowManager needs to set these flags immediately and can't wait for the
- * Keyguard thread to pick it up. In the hidden case, PhoneWindowManager is solely
- * responsible to make sure that the flags are unset.
*/
- int setOccluded(boolean isOccluded);
+ void setOccluded(boolean isOccluded);
- oneway void dismiss();
- oneway void onDreamingStarted();
- oneway void onDreamingStopped();
- oneway void onScreenTurnedOff(int reason);
- oneway void onScreenTurnedOn(IKeyguardShowCallback callback);
- oneway void setKeyguardEnabled(boolean enabled);
- oneway void onSystemReady();
- oneway void doKeyguardTimeout(in Bundle options);
- oneway void setCurrentUser(int userId);
- oneway void showAssistant();
- oneway void dispatch(in MotionEvent event);
- oneway void launchCamera();
- oneway void onBootCompleted();
+ void addStateMonitorCallback(IKeyguardStateCallback callback);
+ void verifyUnlock(IKeyguardExitCallback callback);
+ void keyguardDone(boolean authenticated, boolean wakeup);
+ void dismiss();
+ void onDreamingStarted();
+ void onDreamingStopped();
+ void onScreenTurnedOff(int reason);
+ void onScreenTurnedOn(IKeyguardShowCallback callback);
+ void setKeyguardEnabled(boolean enabled);
+ void onSystemReady();
+ void doKeyguardTimeout(in Bundle options);
+ void setCurrentUser(int userId);
+ void onBootCompleted();
/**
* Notifies that the activity behind has now been drawn and it's safe to remove the wallpaper
@@ -64,11 +51,11 @@
* @param startTime the start time of the animation in uptime milliseconds
* @param fadeoutDuration the duration of the exit animation, in milliseconds
*/
- oneway void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
+ void startKeyguardExitAnimation(long startTime, long fadeoutDuration);
/**
* Notifies the Keyguard that the activity that was starting has now been drawn and it's safe
* to start the keyguard dismiss sequence.
*/
- oneway void onActivityDrawn();
+ void onActivityDrawn();
}
diff --git a/core/java/com/android/internal/policy/IKeyguardServiceConstants.java b/core/java/com/android/internal/policy/IKeyguardServiceConstants.java
deleted file mode 100644
index b88174a..0000000
--- a/core/java/com/android/internal/policy/IKeyguardServiceConstants.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.internal.policy;
-
-/**
- * @hide
- */
-public class IKeyguardServiceConstants {
-
- /**
- * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
- * Don't change the keyguard window flags.
- */
- public static final int KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_NONE = 0;
-
- /**
- * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
- * Set the keyguard window flags to FLAG_SHOW_WALLPAPER and PRIVATE_FLAG_KEYGUARD.
- */
- public static final int KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_SET_FLAGS = 1;
-
- /**
- * Constant for {@link com.android.internal.policy.IKeyguardService#setHidden(boolean)}:
- * Unset the keyguard window flags to FLAG_SHOW_WALLPAPER and PRIVATE_FLAG_KEYGUARD.
- */
- public static final int KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_UNSET_FLAGS = 2;
-}
diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
new file mode 100644
index 0000000..db3b40b
--- /dev/null
+++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.policy;
+
+interface IKeyguardStateCallback {
+ void onShowingStateChanged(boolean showing);
+ void onSimSecureStateChanged(boolean simSecure);
+ void onInputRestrictedStateChanged(boolean inputRestricted);
+}
\ No newline at end of file
diff --git a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
index 0c9dbc4..ab69a0c 100644
--- a/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/ViewMediatorCallback.java
@@ -71,4 +71,10 @@
* Play the "device trusted" sound.
*/
void playTrustedSound();
+
+ /**
+ * @return true if and only if Keyguard is showing or if Keyguard is disabled by an external app
+ * (legacy API)
+ */
+ boolean isInputRestricted();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 98d4112..73fa2ed 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -24,12 +24,11 @@
import android.os.IBinder;
import android.os.Process;
import android.util.Log;
-import android.view.MotionEvent;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardServiceConstants;
import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardStateCallback;
import com.android.systemui.SystemUIApplication;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -66,143 +65,85 @@
private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {
- private boolean mIsOccluded;
-
- @Override
- public boolean isShowing() {
- return mKeyguardViewMediator.isShowing();
+ @Override // Binder interface
+ public void addStateMonitorCallback(IKeyguardStateCallback callback) {
+ checkPermission();
+ mKeyguardViewMediator.addStateMonitorCallback(callback);
}
- @Override
- public boolean isSecure() {
- return mKeyguardViewMediator.isSecure();
- }
-
- @Override
- public boolean isShowingAndNotOccluded() {
- return mKeyguardViewMediator.isShowingAndNotOccluded();
- }
-
- @Override
- public boolean isInputRestricted() {
- return mKeyguardViewMediator.isInputRestricted();
- }
-
- @Override
+ @Override // Binder interface
public void verifyUnlock(IKeyguardExitCallback callback) {
checkPermission();
mKeyguardViewMediator.verifyUnlock(callback);
}
- @Override
+ @Override // Binder interface
public void keyguardDone(boolean authenticated, boolean wakeup) {
checkPermission();
mKeyguardViewMediator.keyguardDone(authenticated, wakeup);
}
- @Override
- public int setOccluded(boolean isOccluded) {
+ @Override // Binder interface
+ public void setOccluded(boolean isOccluded) {
checkPermission();
- synchronized (this) {
- int result;
- if (isOccluded && mKeyguardViewMediator.isShowing()
- && !mIsOccluded) {
- result = IKeyguardServiceConstants
- .KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_UNSET_FLAGS;
- } else if (!isOccluded && mKeyguardViewMediator.isShowing()
- && mIsOccluded) {
- result = IKeyguardServiceConstants
- .KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_SET_FLAGS;
- } else {
- result = IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_NONE;
- }
- if (mIsOccluded != isOccluded) {
- mKeyguardViewMediator.setOccluded(isOccluded);
-
- // Cache the value so we always have a fresh view in whether Keyguard is occluded.
- // If we would just call mKeyguardViewMediator.isOccluded(), this might be stale
- // because that value gets updated in another thread.
- mIsOccluded = isOccluded;
- }
- return result;
- }
+ mKeyguardViewMediator.setOccluded(isOccluded);
}
- @Override
+ @Override // Binder interface
public void dismiss() {
checkPermission();
mKeyguardViewMediator.dismiss();
}
- @Override
+ @Override // Binder interface
public void onDreamingStarted() {
checkPermission();
mKeyguardViewMediator.onDreamingStarted();
}
- @Override
+ @Override // Binder interface
public void onDreamingStopped() {
checkPermission();
mKeyguardViewMediator.onDreamingStopped();
}
- @Override
+ @Override // Binder interface
public void onScreenTurnedOff(int reason) {
checkPermission();
mKeyguardViewMediator.onScreenTurnedOff(reason);
}
- @Override
+ @Override // Binder interface
public void onScreenTurnedOn(IKeyguardShowCallback callback) {
checkPermission();
mKeyguardViewMediator.onScreenTurnedOn(callback);
}
- @Override
+ @Override // Binder interface
public void setKeyguardEnabled(boolean enabled) {
checkPermission();
mKeyguardViewMediator.setKeyguardEnabled(enabled);
}
- @Override
- public boolean isDismissable() {
- return mKeyguardViewMediator.isDismissable();
- }
-
- @Override
+ @Override // Binder interface
public void onSystemReady() {
checkPermission();
mKeyguardViewMediator.onSystemReady();
}
- @Override
+ @Override // Binder interface
public void doKeyguardTimeout(Bundle options) {
checkPermission();
mKeyguardViewMediator.doKeyguardTimeout(options);
}
- @Override
+ @Override // Binder interface
public void setCurrentUser(int userId) {
checkPermission();
mKeyguardViewMediator.setCurrentUser(userId);
}
@Override
- public void showAssistant() {
- checkPermission();
- }
-
- @Override
- public void dispatch(MotionEvent event) {
- checkPermission();
- }
-
- @Override
- public void launchCamera() {
- checkPermission();
- }
-
- @Override
public void onBootCompleted() {
checkPermission();
mKeyguardViewMediator.onBootCompleted();
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d8f8727..4e034ae 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -56,6 +56,7 @@
import android.view.animation.AnimationUtils;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardConstants;
@@ -70,6 +71,8 @@
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowManager;
+import java.util.ArrayList;
+
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
@@ -224,6 +227,9 @@
// answer whether the input should be restricted)
private boolean mShowing;
+ /** Cached value of #isInputRestricted */
+ private boolean mInputRestricted;
+
// true if the keyguard is hidden by another window
private boolean mOccluded = false;
@@ -293,6 +299,8 @@
*/
private KeyguardDisplayManager mKeyguardDisplayManager;
+ private final ArrayList<IKeyguardStateCallback> mKeyguardStateCallbacks = new ArrayList<>();
+
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@Override
@@ -360,6 +368,7 @@
@Override
public void onDeviceProvisioned() {
sendUserPresentBroadcast();
+ updateInputRestricted();
}
@Override
@@ -370,6 +379,16 @@
+ ",state=" + simState + ")");
}
+ try {
+ int size = mKeyguardStateCallbacks.size();
+ boolean simPinSecure = mUpdateMonitor.isSimPinSecure();
+ for (int i = 0; i < size; i++) {
+ mKeyguardStateCallbacks.get(i).onSimSecureStateChanged(simPinSecure);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onSimSecureStateChanged", e);
+ }
+
switch (simState) {
case NOT_READY:
case ABSENT:
@@ -377,7 +396,7 @@
// gone through setup wizard
synchronized (this) {
if (shouldWaitForProvisioning()) {
- if (!isShowing()) {
+ if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
+ " we need to show the keyguard since the "
+ "device isn't provisioned yet.");
@@ -391,7 +410,7 @@
case PIN_REQUIRED:
case PUK_REQUIRED:
synchronized (this) {
- if (!isShowing()) {
+ if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG,
"INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
+ "showing; need to show keyguard so user can enter sim pin");
@@ -403,7 +422,7 @@
break;
case PERM_DISABLED:
synchronized (this) {
- if (!isShowing()) {
+ if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
+ "keygaurd isn't showing.");
doKeyguardLocked(null);
@@ -416,7 +435,7 @@
break;
case READY:
synchronized (this) {
- if (isShowing()) {
+ if (mShowing) {
resetStateLocked();
}
}
@@ -488,13 +507,18 @@
public void playTrustedSound() {
KeyguardViewMediator.this.playTrustedSound();
}
+
+ @Override
+ public boolean isInputRestricted() {
+ return KeyguardViewMediator.this.isInputRestricted();
+ }
};
public void userActivity() {
mPM.userActivity(SystemClock.uptimeMillis(), false);
}
- private void setup() {
+ private void setupLocked() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWM = WindowManagerGlobal.getWindowManagerService();
mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
@@ -514,7 +538,7 @@
mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure...
- mShowing = !shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled();
+ setShowingLocked(!shouldWaitForProvisioning() && !mLockPatternUtils.isLockScreenDisabled());
mTrustManager.reportKeyguardShowingChanged();
mStatusBarKeyguardViewManager = new StatusBarKeyguardViewManager(mContext,
@@ -556,7 +580,9 @@
@Override
public void start() {
- setup();
+ synchronized (this) {
+ setupLocked();
+ }
putComponent(KeyguardViewMediator.class, this);
}
@@ -760,12 +786,14 @@
if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, "
+ "disabling status bar expansion");
mNeedToReshowWhenReenabled = true;
+ updateInputRestrictedLocked();
hideLocked();
} else if (enabled && mNeedToReshowWhenReenabled) {
// reenabled after previously hidden, reshow
if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling "
+ "status bar expansion");
mNeedToReshowWhenReenabled = false;
+ updateInputRestrictedLocked();
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting");
@@ -837,17 +865,6 @@
}
/**
- * Is the keyguard currently showing?
- */
- public boolean isShowing() {
- return mShowing;
- }
-
- public boolean isOccluded() {
- return mOccluded;
- }
-
- /**
* Is the keyguard currently showing and not being force hidden?
*/
public boolean isShowingAndNotOccluded() {
@@ -897,6 +914,26 @@
return mShowing || mNeedToReshowWhenReenabled || shouldWaitForProvisioning();
}
+ private void updateInputRestricted() {
+ synchronized (this) {
+ updateInputRestrictedLocked();
+ }
+ }
+ private void updateInputRestrictedLocked() {
+ boolean inputRestricted = isInputRestricted();
+ if (mInputRestricted != inputRestricted) {
+ mInputRestricted = inputRestricted;
+ try {
+ int size = mKeyguardStateCallbacks.size();
+ for (int i = 0; i < size; i++) {
+ mKeyguardStateCallbacks.get(i).onInputRestrictedStateChanged(inputRestricted);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onDeviceProvisioned", e);
+ }
+ }
+ }
+
/**
* Enable the keyguard if the settings are appropriate.
*/
@@ -947,7 +984,7 @@
if (mLockPatternUtils.checkVoldPassword()) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
- setShowing(false);
+ setShowingLocked(false);
hideLocked();
return;
}
@@ -1168,6 +1205,7 @@
// the keyguard when they've released the lock
mExternallyEnabled = true;
mNeedToReshowWhenReenabled = false;
+ updateInputRestricted();
}
}
@@ -1263,9 +1301,9 @@
if (DEBUG) Log.d(TAG, "handleShow");
}
+ setShowingLocked(true);
mStatusBarKeyguardViewManager.show(options);
mHiding = false;
- setShowing(true);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
updateActivityLockScreenState();
@@ -1343,8 +1381,8 @@
playSounds(false);
}
+ setShowingLocked(false);
mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
- setShowing(false);
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
updateActivityLockScreenState();
@@ -1404,8 +1442,8 @@
private void handleVerifyUnlock() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
+ setShowingLocked(true);
mStatusBarKeyguardViewManager.verifyUnlock();
- setShowing(true);
updateActivityLockScreenState();
}
}
@@ -1432,15 +1470,6 @@
}
}
- public boolean isDismissable() {
- return mKeyguardDonePending || !isSecure();
- }
-
- private boolean isAssistantAvailable() {
- return mSearchManager != null
- && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
- }
-
private void resetKeyguardDonePendingLocked() {
mKeyguardDonePending = false;
mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT);
@@ -1488,11 +1517,31 @@
}
}
- private void setShowing(boolean showing) {
- boolean changed = (showing != mShowing);
- mShowing = showing;
- if (changed) {
+ private void setShowingLocked(boolean showing) {
+ if (showing != mShowing) {
+ mShowing = showing;
+ try {
+ int size = mKeyguardStateCallbacks.size();
+ for (int i = 0; i < size; i++) {
+ mKeyguardStateCallbacks.get(i).onShowingStateChanged(showing);
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onShowingStateChanged", e);
+ }
+ updateInputRestrictedLocked();
mTrustManager.reportKeyguardShowingChanged();
}
}
+
+ public void addStateMonitorCallback(IKeyguardStateCallback callback) {
+ synchronized (this) {
+ mKeyguardStateCallbacks.add(callback);
+ try {
+ callback.onSimSecureStateChanged(mUpdateMonitor.isSimPinSecure());
+ callback.onShowingStateChanged(mShowing);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onShowingStateChanged or onSimSecureStateChanged", e);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a2796c6..4a16f8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -92,7 +92,6 @@
import com.android.systemui.SwipeHelper;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.NotificationData.Entry;
-import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
import com.android.systemui.statusbar.phone.NavigationBarView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
@@ -2090,13 +2089,13 @@
boolean accessibilityForcesLaunch = isFullscreen
&& mAccessibilityManager.isTouchExplorationEnabled();
- final KeyguardTouchDelegate keyguard = KeyguardTouchDelegate.getInstance(mContext);
boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker)))
&& isAllowed
&& !accessibilityForcesLaunch
&& mPowerManager.isScreenOn()
- && !keyguard.isShowingAndNotOccluded()
- && !keyguard.isInputRestricted();
+ && (!mStatusBarKeyguardViewManager.isShowing()
+ || mStatusBarKeyguardViewManager.isOccluded())
+ && !mStatusBarKeyguardViewManager.isInputRestricted();
try {
interrupt = interrupt && !mDreamManager.isDreaming();
} catch (RemoteException e) {
@@ -2106,10 +2105,6 @@
return interrupt;
}
- public boolean inKeyguardRestrictedInputMode() {
- return KeyguardTouchDelegate.getInstance(mContext).isInputRestricted();
- }
-
public void setInteracting(int barWindow, boolean interacting) {
// hook for subclasses
}
@@ -2167,4 +2162,8 @@
// Ignore.
}
}
+
+ public boolean isKeyguardSecure() {
+ return mStatusBarKeyguardViewManager.isSecure();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index fddbee2..503f588 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -257,7 +257,7 @@
final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
final boolean disabledBecauseKeyguardSecure =
(disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
- && KeyguardTouchDelegate.getInstance(getContext()).isSecure();
+ && mPhoneStatusBar.isKeyguardSecure();
return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
} catch (RemoteException e) {
Log.e(TAG, "Can't get userId", e);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
deleted file mode 100644
index 754075a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.phone;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.util.Slog;
-import android.view.MotionEvent;
-
-import com.android.internal.policy.IKeyguardService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Facilitates event communication between navigation bar and keyguard. Currently used to
- * control WidgetPager in keyguard to expose the camera widget.
- *
- */
-public class KeyguardTouchDelegate {
- // TODO: propagate changes to these to {@link KeyguardServiceDelegate}
- static final String KEYGUARD_PACKAGE = "com.android.systemui";
- static final String KEYGUARD_CLASS = "com.android.systemui.keyguard.KeyguardService";
-
- private static KeyguardTouchDelegate sInstance;
- private static final List<OnKeyguardConnectionListener> sConnectionListeners =
- new ArrayList<OnKeyguardConnectionListener>();
-
- private volatile IKeyguardService mService;
-
- protected static final boolean DEBUG = false;
- protected static final String TAG = "KeyguardTouchDelegate";
-
- private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Slog.v(TAG, "Connected to keyguard");
- mService = IKeyguardService.Stub.asInterface(service);
-
- for (int i = 0; i < sConnectionListeners.size(); i++) {
- OnKeyguardConnectionListener listener = sConnectionListeners.get(i);
- listener.onKeyguardServiceConnected(KeyguardTouchDelegate.this);
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Slog.v(TAG, "Disconnected from keyguard");
- mService = null;
- sInstance = null; // force reconnection if this goes away
-
- for (int i = 0; i < sConnectionListeners.size(); i++) {
- OnKeyguardConnectionListener listener = sConnectionListeners.get(i);
- listener.onKeyguardServiceDisconnected(KeyguardTouchDelegate.this);
- }
- }
-
- };
-
- private KeyguardTouchDelegate(Context context) {
- Intent intent = new Intent();
- intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
- if (!context.bindServiceAsUser(intent, mKeyguardConnection,
- Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
- if (DEBUG) Slog.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
- } else {
- if (DEBUG) Slog.v(TAG, "*** Keyguard started");
- }
- }
-
- public static KeyguardTouchDelegate getInstance(Context context) {
- KeyguardTouchDelegate instance = sInstance;
- if (instance == null) {
- instance = sInstance = new KeyguardTouchDelegate(context);
- }
- return instance;
- }
-
- public boolean isSecure() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- return service.isSecure();
- } catch (RemoteException e) {
- Slog.e(TAG, "RemoteException calling keyguard.isSecure()!", e);
- }
- } else {
- Slog.w(TAG, "isSecure(): NO SERVICE!");
- }
- return false;
- }
-
- public boolean dispatch(MotionEvent event) {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- service.dispatch(event);
- return true;
- } catch (RemoteException e) {
- // What to do?
- Slog.e(TAG, "RemoteException sending event to keyguard!", e);
- }
- } else {
- Slog.w(TAG, "dispatch(event): NO SERVICE!");
- }
- return false;
- }
-
- public boolean isInputRestricted() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- return service.isInputRestricted();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- } else {
- Slog.w(TAG, "isInputRestricted(): NO SERVICE!");
- }
- return false;
- }
-
- public boolean isShowingAndNotOccluded() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- return service.isShowingAndNotOccluded();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- } else {
- Slog.w(TAG, "isShowingAndNotOccluded(): NO SERVICE!");
- }
- return false;
- }
-
- public void showAssistant() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- service.showAssistant();
- } catch (RemoteException e) {
- // What to do?
- Slog.e(TAG, "RemoteException launching assistant!", e);
- }
- } else {
- Slog.w(TAG, "showAssistant(event): NO SERVICE!");
- }
- }
-
- public void launchCamera() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- service.launchCamera();
- } catch (RemoteException e) {
- // What to do?
- Slog.e(TAG, "RemoteException launching camera!", e);
- }
- } else {
- Slog.w(TAG, "launchCamera(): NO SERVICE!");
- }
- }
-
- public void dismiss() {
- final IKeyguardService service = mService;
- if (service != null) {
- try {
- service.dismiss();
- } catch (RemoteException e) {
- // What to do?
- Slog.e(TAG, "RemoteException dismissing keyguard!", e);
- }
- } else {
- Slog.w(TAG, "dismiss(): NO SERVICE!");
- }
- }
-
- public static void addListener(OnKeyguardConnectionListener listener) {
- sConnectionListeners.add(listener);
- }
-
- public interface OnKeyguardConnectionListener {
-
- void onKeyguardServiceConnected(KeyguardTouchDelegate keyguardTouchDelegate);
- void onKeyguardServiceDisconnected(KeyguardTouchDelegate keyguardTouchDelegate);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index cec1559..0e6f1b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -430,4 +430,8 @@
public boolean isSecure(int userId) {
return mBouncer.isSecure() || mLockPatternUtils.isSecure(userId);
}
+
+ public boolean isInputRestricted() {
+ return mViewMediatorCallback.isInputRestricted();
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index dea9932..1271737 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -103,8 +103,6 @@
import android.view.animation.AnimationUtils;
import com.android.internal.R;
-import com.android.internal.policy.IKeyguardService;
-import com.android.internal.policy.IKeyguardServiceConstants;
import com.android.internal.policy.PolicyManager;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate.ShowListener;
@@ -483,6 +481,9 @@
boolean mShowingLockscreen;
boolean mShowingDream;
boolean mDreamingLockscreen;
+ boolean mKeyguardSecure;
+ boolean mKeyguardSecureIncludingHidden;
+ volatile boolean mKeyguardOccluded;
boolean mHomePressed;
boolean mHomeConsumed;
boolean mHomeDoubleTapPending;
@@ -1108,7 +1109,7 @@
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
}
- final boolean keyguardShowing = keyguardIsShowingTq();
+ final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
if (keyguardShowing) {
// since it took two seconds of long press to bring this up,
@@ -1973,7 +1974,8 @@
@Override
public boolean isForceHiding(WindowManager.LayoutParams attrs) {
return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
- (isKeyguardHostWindow(attrs) && isKeyguardSecureIncludingHidden()) ||
+ (isKeyguardHostWindow(attrs) &&
+ (mKeyguardDelegate != null && mKeyguardDelegate.isShowing())) ||
(attrs.type == TYPE_KEYGUARD_SCRIM);
}
@@ -2377,7 +2379,7 @@
}
boolean keyguardOn() {
- return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode();
+ return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode();
}
private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
@@ -2961,7 +2963,7 @@
* given the situation with the keyguard.
*/
void launchHomeFromHotKey() {
- if (mKeyguardDelegate != null && mKeyguardDelegate.isShowingAndNotOccluded()) {
+ if (isKeyguardShowingAndNotOccluded()) {
// don't launch home if keyguard showing
} else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
@@ -3995,6 +3997,9 @@
mShowingLockscreen = false;
mShowingDream = false;
mWinShowWhenLocked = null;
+ mKeyguardSecure = isKeyguardSecure();
+ mKeyguardSecureIncludingHidden = mKeyguardSecure
+ && (mKeyguardDelegate != null && mKeyguardDelegate.isShowing());
}
/** {@inheritDoc} */
@@ -4039,7 +4044,6 @@
final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
- final boolean secureKeyguard = isKeyguardSecure();
final IApplicationToken appToken = win.getAppToken();
// For app windows that are not attached, we decide if all windows in the app they
@@ -4050,13 +4054,13 @@
// Remove any previous windows with the same appToken.
mAppsToBeHidden.remove(appToken);
mAppsThatDismissKeyguard.remove(appToken);
- if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) {
+ if (mAppsToBeHidden.isEmpty() && mKeyguardSecureIncludingHidden) {
mWinShowWhenLocked = win;
mHideLockScreen = true;
mForceStatusBarFromKeyguard = false;
}
} else if (dismissKeyguard) {
- if (secureKeyguard) {
+ if (mKeyguardSecure) {
mAppsToBeHidden.add(appToken);
} else {
mAppsToBeHidden.remove(appToken);
@@ -4077,7 +4081,7 @@
mDismissKeyguard = mWinDismissingKeyguard == win ?
DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
mWinDismissingKeyguard = win;
- mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
+ mForceStatusBarFromKeyguard = mShowingLockscreen && mKeyguardSecure;
} else if (mAppsToBeHidden.isEmpty() && showWhenLocked) {
if (DEBUG_LAYOUT) Slog.v(TAG,
"Setting mHideLockScreen to true by win " + win);
@@ -4188,9 +4192,9 @@
if (mKeyguardDelegate != null && mStatusBar != null) {
if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+ mHideLockScreen);
- if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
+ if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardSecure) {
mKeyguardHidden = true;
- if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(true))) {
+ if (setKeyguardOccludedLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -4205,7 +4209,7 @@
}
} else if (mHideLockScreen) {
mKeyguardHidden = true;
- if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(true))) {
+ if (setKeyguardOccludedLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -4215,7 +4219,7 @@
if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
// Only launch the next keyguard unlock window once per window.
mKeyguardHidden = false;
- if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(false))) {
+ if (setKeyguardOccludedLw(false)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -4230,7 +4234,7 @@
} else {
mWinDismissingKeyguard = null;
mKeyguardHidden = false;
- if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(false))) {
+ if (setKeyguardOccludedLw(false)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -4250,23 +4254,22 @@
}
/**
- * Processes the result code of {@link IKeyguardService#setOccluded}. This is needed because we
- * immediately need to put the wallpaper directly behind the Keyguard when a window with flag
- * {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} gets dismissed. If we
- * would wait for Keyguard to change the flags, that would be running asynchronously and thus be
- * too late so the user might see the window behind.
+ * Updates the occluded state of the Keyguard.
*
- * @param setHiddenResult The result code from {@link IKeyguardService#setOccluded}.
* @return Whether the flags have changed and we have to redo the layout.
*/
- private boolean processKeyguardSetHiddenResultLw(int setHiddenResult) {
- if (setHiddenResult
- == IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_SET_FLAGS) {
+ private boolean setKeyguardOccludedLw(boolean isOccluded) {
+ boolean wasOccluded = mKeyguardOccluded;
+ boolean showing = mKeyguardDelegate.isShowing();
+ if (wasOccluded && !isOccluded && showing) {
+ mKeyguardOccluded = false;
+ mKeyguardDelegate.setOccluded(false);
mStatusBar.getAttrs().privateFlags |= PRIVATE_FLAG_KEYGUARD;
mStatusBar.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
return true;
- } else if (setHiddenResult
- == IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_UNSET_FLAGS) {
+ } else if (!wasOccluded && isOccluded && showing) {
+ mKeyguardOccluded = true;
+ mKeyguardDelegate.setOccluded(true);
mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
return true;
@@ -4477,7 +4480,7 @@
// when the keyguard is hidden by another activity.
final boolean keyguardActive = (mKeyguardDelegate == null ? false :
(interactive ?
- mKeyguardDelegate.isShowingAndNotOccluded() :
+ isKeyguardShowingAndNotOccluded() :
mKeyguardDelegate.isShowing()));
if (DEBUG_INPUT) {
@@ -4817,7 +4820,8 @@
private boolean shouldDispatchInputWhenNonInteractive() {
// Send events to keyguard while the screen is on.
- if (keyguardIsShowingTq() && mDisplay != null && mDisplay.getState() != Display.STATE_OFF) {
+ if (isKeyguardShowingAndNotOccluded() && mDisplay != null
+ && mDisplay.getState() != Display.STATE_OFF) {
return true;
}
@@ -5189,12 +5193,11 @@
}
}
- private boolean keyguardIsShowingTq() {
+ private boolean isKeyguardShowingAndNotOccluded() {
if (mKeyguardDelegate == null) return false;
- return mKeyguardDelegate.isShowingAndNotOccluded();
+ return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
}
-
/** {@inheritDoc} */
@Override
public boolean isKeyguardLocked() {
@@ -5208,11 +5211,6 @@
return mKeyguardDelegate.isSecure();
}
- // Returns true if keyguard is currently locked whether or not it is currently hidden.
- private boolean isKeyguardSecureIncludingHidden() {
- return mKeyguardDelegate.isSecure() && mKeyguardDelegate.isShowing();
- }
-
/** {@inheritDoc} */
@Override
public boolean inKeyguardRestrictedKeyInputMode() {
@@ -5527,7 +5525,7 @@
/** {@inheritDoc} */
@Override
public void systemReady() {
- mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null);
+ mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();
readCameraLensCoverState();
@@ -5974,7 +5972,7 @@
@Override
public void keepScreenOnStoppedLw() {
- if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotOccluded()) {
+ if (isKeyguardShowingAndNotOccluded()) {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index 50fe7c7..618ba1e 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -18,9 +18,8 @@
import android.view.WindowManagerPolicy.OnKeyguardExitResult;
import com.android.internal.policy.IKeyguardExitCallback;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardService;
-import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.policy.IKeyguardShowCallback;
/**
* A local class that keeps a cache of keyguard state that can be restored in the event
@@ -28,15 +27,16 @@
* local or remote instances of keyguard.
*/
public class KeyguardServiceDelegate {
- // TODO: propagate changes to these to {@link KeyguardTouchDelegate}
public static final String KEYGUARD_PACKAGE = "com.android.systemui";
public static final String KEYGUARD_CLASS = "com.android.systemui.keyguard.KeyguardService";
private static final String TAG = "KeyguardServiceDelegate";
private static final boolean DEBUG = true;
+
protected KeyguardServiceWrapper mKeyguardService;
- private View mScrim; // shown if keyguard crashes
- private KeyguardState mKeyguardState = new KeyguardState();
+ private final Context mContext;
+ private final View mScrim; // shown if keyguard crashes
+ private final KeyguardState mKeyguardState = new KeyguardState();
/* package */ static final class KeyguardState {
KeyguardState() {
@@ -101,7 +101,8 @@
}
};
- public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
+ public KeyguardServiceDelegate(Context context) {
+ mContext = context;
mScrim = createScrim(context);
}
@@ -123,7 +124,7 @@
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)");
- mKeyguardService = new KeyguardServiceWrapper(
+ mKeyguardService = new KeyguardServiceWrapper(mContext,
IKeyguardService.Stub.asInterface(service));
if (mKeyguardState.systemIsReady) {
// If the system is ready, it means keyguard crashed and restarted.
@@ -151,13 +152,6 @@
return mKeyguardState.showing;
}
- public boolean isShowingAndNotOccluded() {
- if (mKeyguardService != null) {
- mKeyguardState.showingAndNotOccluded = mKeyguardService.isShowingAndNotOccluded();
- }
- return mKeyguardState.showingAndNotOccluded;
- }
-
public boolean isInputRestricted() {
if (mKeyguardService != null) {
mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted();
@@ -177,13 +171,11 @@
}
}
- public int setOccluded(boolean isOccluded) {
- int result = 0;
+ public void setOccluded(boolean isOccluded) {
if (mKeyguardService != null) {
- result = mKeyguardService.setOccluded(isOccluded);
+ mKeyguardService.setOccluded(isOccluded);
}
mKeyguardState.occluded = isOccluded;
- return result;
}
public void dismiss() {
@@ -242,13 +234,6 @@
mKeyguardState.enabled = enabled;
}
- public boolean isDismissable() {
- if (mKeyguardService != null) {
- mKeyguardState.dismissable = mKeyguardService.isDismissable();
- }
- return mKeyguardState.dismissable;
- }
-
public void onSystemReady() {
if (mKeyguardService != null) {
mKeyguardService.onSystemReady();
@@ -263,12 +248,6 @@
}
}
- public void showAssistant() {
- if (mKeyguardService != null) {
- mKeyguardService.showAssistant();
- }
- }
-
public void setCurrentUser(int newUserId) {
if (mKeyguardService != null) {
mKeyguardService.setCurrentUser(newUserId);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
index 2778b15..b3b7684 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -16,16 +16,16 @@
package com.android.internal.policy.impl.keyguard;
+import android.content.Context;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
-import android.view.MotionEvent;
-import com.android.internal.policy.IKeyguardServiceConstants;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardShowCallback;
+import com.android.internal.policy.IKeyguardStateCallback;
/**
* A wrapper class for KeyguardService. It implements IKeyguardService to ensure the interface
@@ -33,58 +33,16 @@
*
*/
public class KeyguardServiceWrapper implements IKeyguardService {
+ private KeyguardStateMonitor mKeyguardStateMonitor;
private IKeyguardService mService;
private String TAG = "KeyguardServiceWrapper";
- public KeyguardServiceWrapper(IKeyguardService service) {
+ public KeyguardServiceWrapper(Context context, IKeyguardService service) {
mService = service;
+ mKeyguardStateMonitor = new KeyguardStateMonitor(context, service);
}
- public boolean isShowing() {
- try {
- return mService.isShowing();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- return false;
- }
-
- public boolean isSecure() {
- try {
- return mService.isSecure();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- return false; // TODO cache state
- }
-
- public boolean isShowingAndNotOccluded() {
- try {
- return mService.isShowingAndNotOccluded();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- return false; // TODO cache state
- }
-
- public boolean isInputRestricted() {
- try {
- return mService.isInputRestricted();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- return false; // TODO cache state
- }
-
- public boolean isDismissable() {
- try {
- return mService.isDismissable();
- } catch (RemoteException e) {
- Slog.w(TAG , "Remote Exception", e);
- }
- return true; // TODO cache state
- }
-
+ @Override // Binder interface
public void verifyUnlock(IKeyguardExitCallback callback) {
try {
mService.verifyUnlock(callback);
@@ -93,6 +51,7 @@
}
}
+ @Override // Binder interface
public void keyguardDone(boolean authenticated, boolean wakeup) {
try {
mService.keyguardDone(authenticated, wakeup);
@@ -101,15 +60,25 @@
}
}
- public int setOccluded(boolean isOccluded) {
+ @Override // Binder interface
+ public void setOccluded(boolean isOccluded) {
try {
- return mService.setOccluded(isOccluded);
+ mService.setOccluded(isOccluded);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
- return IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_NONE;
}
}
+ @Override
+ public void addStateMonitorCallback(IKeyguardStateCallback callback) {
+ try {
+ mService.addStateMonitorCallback(callback);
+ } catch (RemoteException e) {
+ Slog.w(TAG , "Remote Exception", e);
+ }
+ }
+
+ @Override // Binder interface
public void dismiss() {
try {
mService.dismiss();
@@ -118,6 +87,7 @@
}
}
+ @Override // Binder interface
public void onDreamingStarted() {
try {
mService.onDreamingStarted();
@@ -126,6 +96,7 @@
}
}
+ @Override // Binder interface
public void onDreamingStopped() {
try {
mService.onDreamingStopped();
@@ -134,6 +105,7 @@
}
}
+ @Override // Binder interface
public void onScreenTurnedOff(int reason) {
try {
mService.onScreenTurnedOff(reason);
@@ -142,6 +114,7 @@
}
}
+ @Override // Binder interface
public void onScreenTurnedOn(IKeyguardShowCallback result) {
try {
mService.onScreenTurnedOn(result);
@@ -150,6 +123,7 @@
}
}
+ @Override // Binder interface
public void setKeyguardEnabled(boolean enabled) {
try {
mService.setKeyguardEnabled(enabled);
@@ -158,6 +132,7 @@
}
}
+ @Override // Binder interface
public void onSystemReady() {
try {
mService.onSystemReady();
@@ -166,6 +141,7 @@
}
}
+ @Override // Binder interface
public void doKeyguardTimeout(Bundle options) {
try {
mService.doKeyguardTimeout(options);
@@ -174,7 +150,9 @@
}
}
+ @Override // Binder interface
public void setCurrentUser(int userId) {
+ mKeyguardStateMonitor.setCurrentUser(userId);
try {
mService.setCurrentUser(userId);
} catch (RemoteException e) {
@@ -182,6 +160,7 @@
}
}
+ @Override // Binder interface
public void onBootCompleted() {
try {
mService.onBootCompleted();
@@ -190,6 +169,7 @@
}
}
+ @Override // Binder interface
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
try {
mService.startKeyguardExitAnimation(startTime, fadeoutDuration);
@@ -198,6 +178,7 @@
}
}
+ @Override // Binder interface
public void onActivityDrawn() {
try {
mService.onActivityDrawn();
@@ -206,21 +187,20 @@
}
}
- public void showAssistant() {
- // Not used by PhoneWindowManager
- }
-
- public void dispatch(MotionEvent event) {
- // Not used by PhoneWindowManager. See code in {@link NavigationBarView}
- }
-
- public void launchCamera() {
- // Not used by PhoneWindowManager. See code in {@link NavigationBarView}
- }
-
- @Override
+ @Override // Binder interface
public IBinder asBinder() {
return mService.asBinder();
}
+ public boolean isShowing() {
+ return mKeyguardStateMonitor.isShowing();
+ }
+
+ public boolean isSecure() {
+ return mKeyguardStateMonitor.isSecure();
+ }
+
+ public boolean isInputRestricted() {
+ return mKeyguardStateMonitor.isInputRestricted();
+ }
}
\ No newline at end of file
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStateMonitor.java
new file mode 100644
index 0000000..6f9c617
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardStateMonitor.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl.keyguard;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.policy.IKeyguardService;
+import com.android.internal.policy.IKeyguardStateCallback;
+import com.android.internal.widget.LockPatternUtils;
+
+/**
+ * Maintains a cached copy of Keyguard's state.
+ * @hide
+ */
+public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub {
+ private static final String TAG = "KeyguardStateMonitor";
+
+ // These cache the current state of Keyguard to improve performance and avoid deadlock. After
+ // Keyguard changes its state, it always triggers a layout in window manager. Because
+ // IKeyguardStateCallback is synchronous and because these states are declared volatile, it's
+ // guaranteed that window manager picks up the new state all the time in the layout caused by
+ // the state change of Keyguard.
+ private volatile boolean mIsShowing;
+ private volatile boolean mSimSecure;
+ private volatile boolean mInputRestricted;
+
+ private final LockPatternUtils mLockPatternUtils;
+
+ public KeyguardStateMonitor(Context context, IKeyguardService service) {
+ mLockPatternUtils = new LockPatternUtils(context);
+ mLockPatternUtils.setCurrentUser(ActivityManager.getCurrentUser());
+ try {
+ service.addStateMonitorCallback(this);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Remote Exception", e);
+ }
+ }
+
+ public boolean isShowing() {
+ return mIsShowing;
+ }
+
+ public boolean isSecure() {
+ return mLockPatternUtils.isSecure() || mSimSecure;
+ }
+
+ public boolean isInputRestricted() {
+ return mInputRestricted;
+ }
+
+ @Override // Binder interface
+ public void onShowingStateChanged(boolean showing) {
+ mIsShowing = showing;
+ }
+
+ @Override // Binder interface
+ public void onSimSecureStateChanged(boolean simSecure) {
+ mSimSecure = simSecure;
+ }
+
+ public void setCurrentUser(int userId) {
+ mLockPatternUtils.setCurrentUser(userId);
+ }
+
+ @Override // Binder interface
+ public void onInputRestrictedStateChanged(boolean inputRestricted) {
+ mInputRestricted = inputRestricted;
+ }
+}
\ No newline at end of file