summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java205
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java210
-rw-r--r--policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java347
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java61
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java100
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardStateMonitor.java86
6 files changed, 441 insertions, 568 deletions
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 9c81f0a..30a271e 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -101,6 +101,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.PopupWindow;
@@ -1332,6 +1333,22 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ public final void setElevation(float elevation) {
+ mElevation = elevation;
+ if (mDecor != null) {
+ mDecor.setElevation(elevation);
+ }
+ }
+
+ @Override
+ public final void setClipToOutline(boolean clipToOutline) {
+ mClipToOutline = clipToOutline;
+ if (mDecor != null) {
+ mDecor.setClipToOutline(clipToOutline);
+ }
+ }
+
+ @Override
public final void setBackgroundDrawable(Drawable drawable) {
if (drawable != mBackgroundDrawable || mBackgroundResource != 0) {
mBackgroundResource = 0;
@@ -2137,6 +2154,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
+
/* package */int mDefaultOpacity = PixelFormat.OPAQUE;
/** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -2166,18 +2184,45 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// View added at runtime to draw under the navigation bar area
private View mNavigationGuard;
- private View mStatusColorView;
- private View mNavigationColorView;
+ private final ColorViewState mStatusColorViewState = new ColorViewState(
+ SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
+ Gravity.TOP,
+ STATUS_BAR_BACKGROUND_TRANSITION_NAME,
+ com.android.internal.R.id.statusBarBackground,
+ FLAG_FULLSCREEN);
+ private final ColorViewState mNavigationColorViewState = new ColorViewState(
+ SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
+ Gravity.BOTTOM,
+ NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
+ com.android.internal.R.id.navigationBarBackground,
+ 0 /* hideWindowFlag */);
+
+ private final Interpolator mShowInterpolator;
+ private final Interpolator mHideInterpolator;
+ private final int mBarEnterExitDuration;
+
private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
private int mLastTopInset = 0;
private int mLastBottomInset = 0;
private int mLastRightInset = 0;
+ private boolean mLastHasTopStableInset = false;
+ private boolean mLastHasBottomStableInset = false;
+ private int mLastWindowFlags = 0;
+ private int mRootScrollY = 0;
public DecorView(Context context, int featureId) {
super(context);
mFeatureId = featureId;
+
+ mShowInterpolator = AnimationUtils.loadInterpolator(context,
+ android.R.interpolator.linear_out_slow_in);
+ mHideInterpolator = AnimationUtils.loadInterpolator(context,
+ android.R.interpolator.fast_out_linear_in);
+
+ mBarEnterExitDuration = context.getResources().getInteger(
+ R.integer.dock_enter_exit_duration);
}
public void setBackgroundFallback(int resId) {
@@ -2770,13 +2815,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public void onWindowSystemUiVisibilityChanged(int visible) {
- updateColorViews(null /* insets */);
+ updateColorViews(null /* insets */, true /* animate */);
}
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
mFrameOffsets.set(insets.getSystemWindowInsets());
- insets = updateColorViews(insets);
+ insets = updateColorViews(insets, true /* animate */);
insets = updateStatusGuard(insets);
updateNavigationGuard(insets);
if (getForeground() != null) {
@@ -2790,11 +2835,16 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return false;
}
- private WindowInsets updateColorViews(WindowInsets insets) {
+ private WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
WindowManager.LayoutParams attrs = getAttributes();
int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
if (!mIsFloating && ActivityManager.isHighEndGfx()) {
+ boolean disallowAnimate = !isLaidOut();
+ disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
+ & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+ mLastWindowFlags = attrs.flags;
+
if (insets != null) {
mLastTopInset = Math.min(insets.getStableInsetTop(),
insets.getSystemWindowInsetTop());
@@ -2802,19 +2852,23 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
insets.getSystemWindowInsetBottom());
mLastRightInset = Math.min(insets.getStableInsetRight(),
insets.getSystemWindowInsetRight());
+
+ // Don't animate if the presence of stable insets has changed, because that
+ // indicates that the window was either just added and received them for the
+ // first time, or the window size or position has changed.
+ boolean hasTopStableInset = insets.getStableInsetTop() != 0;
+ disallowAnimate |= hasTopStableInset && !mLastHasTopStableInset;
+ mLastHasTopStableInset = hasTopStableInset;
+
+ boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
+ disallowAnimate |= hasBottomStableInset && !mLastHasBottomStableInset;
+ mLastHasBottomStableInset = hasBottomStableInset;
}
- mStatusColorView = updateColorViewInt(mStatusColorView, sysUiVisibility,
- SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
- mStatusBarColor, mLastTopInset, Gravity.TOP,
- STATUS_BAR_BACKGROUND_TRANSITION_NAME,
- com.android.internal.R.id.statusBarBackground,
- (getAttributes().flags & FLAG_FULLSCREEN) != 0);
- mNavigationColorView = updateColorViewInt(mNavigationColorView, sysUiVisibility,
- SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
- mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM,
- NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
- com.android.internal.R.id.navigationBarBackground,
- false /* hiddenByWindowFlag */);
+
+ updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
+ mLastTopInset, animate && !disallowAnimate);
+ updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
+ mLastBottomInset, animate && !disallowAnimate);
}
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2858,27 +2912,35 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return insets;
}
- private View updateColorViewInt(View view, int sysUiVis, int systemUiHideFlag,
- int translucentFlag, int color, int height, int verticalGravity,
- String transitionName, int id, boolean hiddenByWindowFlag) {
- boolean show = height > 0 && (sysUiVis & systemUiHideFlag) == 0
- && !hiddenByWindowFlag
- && (getAttributes().flags & translucentFlag) == 0
+ private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
+ int height, boolean animate) {
+ boolean show = height > 0 && (sysUiVis & state.systemUiHideFlag) == 0
+ && (getAttributes().flags & state.hideWindowFlag) == 0
+ && (getAttributes().flags & state.translucentFlag) == 0
&& (color & Color.BLACK) != 0
&& (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+ boolean visibilityChanged = false;
+ View view = state.view;
+
if (view == null) {
if (show) {
- view = new View(mContext);
+ state.view = view = new View(mContext);
view.setBackgroundColor(color);
- view.setTransitionName(transitionName);
- view.setId(id);
+ view.setTransitionName(state.transitionName);
+ view.setId(state.id);
+ visibilityChanged = true;
+ view.setVisibility(INVISIBLE);
+ state.targetVisibility = VISIBLE;
+
addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
- Gravity.START | verticalGravity));
+ Gravity.START | state.verticalGravity));
+ updateColorViewTranslations();
}
} else {
int vis = show ? VISIBLE : INVISIBLE;
- view.setVisibility(vis);
+ visibilityChanged = state.targetVisibility != vis;
+ state.targetVisibility = vis;
if (show) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (lp.height != height) {
@@ -2888,7 +2950,44 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
view.setBackgroundColor(color);
}
}
- return view;
+ if (visibilityChanged) {
+ view.animate().cancel();
+ if (animate) {
+ if (show) {
+ if (view.getVisibility() != VISIBLE) {
+ view.setVisibility(VISIBLE);
+ view.setAlpha(0.0f);
+ }
+ view.animate().alpha(1.0f).setInterpolator(mShowInterpolator).
+ setDuration(mBarEnterExitDuration);
+ } else {
+ view.animate().alpha(0.0f).setInterpolator(mHideInterpolator)
+ .setDuration(mBarEnterExitDuration)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ state.view.setAlpha(1.0f);
+ state.view.setVisibility(INVISIBLE);
+ }
+ });
+ }
+ } else {
+ view.setAlpha(1.0f);
+ view.setVisibility(show ? VISIBLE : INVISIBLE);
+ }
+ }
+ }
+
+ private void updateColorViewTranslations() {
+ // Put the color views back in place when they get moved off the screen
+ // due to the the ViewRootImpl panning.
+ int rootScrollY = mRootScrollY;
+ if (mStatusColorViewState.view != null) {
+ mStatusColorViewState.view.setTranslationY(rootScrollY > 0 ? rootScrollY : 0);
+ }
+ if (mNavigationColorViewState.view != null) {
+ mNavigationColorViewState.view.setTranslationY(rootScrollY < 0 ? rootScrollY : 0);
+ }
}
private WindowInsets updateStatusGuard(WindowInsets insets) {
@@ -2918,7 +3017,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mStatusGuard = new View(mContext);
mStatusGuard.setBackgroundColor(mContext.getResources()
.getColor(R.color.input_method_navigation_guard));
- addView(mStatusGuard, indexOfChild(mStatusColorView),
+ addView(mStatusGuard, indexOfChild(mStatusColorViewState.view),
new LayoutParams(LayoutParams.MATCH_PARENT,
mlp.topMargin, Gravity.START | Gravity.TOP));
} else {
@@ -2978,9 +3077,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mNavigationGuard = new View(mContext);
mNavigationGuard.setBackgroundColor(mContext.getResources()
.getColor(R.color.input_method_navigation_guard));
- addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams(
- LayoutParams.MATCH_PARENT, insets.getSystemWindowInsetBottom(),
- Gravity.START | Gravity.BOTTOM));
+ addView(mNavigationGuard, indexOfChild(mNavigationColorViewState.view),
+ new LayoutParams(LayoutParams.MATCH_PARENT,
+ insets.getSystemWindowInsetBottom(),
+ Gravity.START | Gravity.BOTTOM));
} else {
LayoutParams lp = (LayoutParams) mNavigationGuard.getLayoutParams();
lp.height = insets.getSystemWindowInsetBottom();
@@ -3149,6 +3249,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
else PhoneWindow.this.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
+ @Override
+ public void onRootViewScrollYChanged(int rootScrollY) {
+ mRootScrollY = rootScrollY;
+ updateColorViewTranslations();
+ }
+
/**
* Clears out internal reference when the action mode is destroyed.
*/
@@ -3342,9 +3448,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE);
if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) {
- addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
+ setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE);
} else {
- clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
+ setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE);
}
// Non-floating windows on high end devices must put up decor beneath the system bars and
@@ -3876,7 +3982,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
super.dispatchWindowAttributesChanged(attrs);
if (mDecor != null) {
- mDecor.updateColorViews(null /* insets */);
+ mDecor.updateColorViews(null /* insets */, true /* animate */);
}
}
@@ -4603,6 +4709,29 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
+ private static class ColorViewState {
+ View view = null;
+ int targetVisibility = View.INVISIBLE;
+
+ final int id;
+ final int systemUiHideFlag;
+ final int translucentFlag;
+ final int verticalGravity;
+ final String transitionName;
+ final int hideWindowFlag;
+
+ ColorViewState(int systemUiHideFlag,
+ int translucentFlag, int verticalGravity,
+ String transitionName, int id, int hideWindowFlag) {
+ this.id = id;
+ this.systemUiHideFlag = systemUiHideFlag;
+ this.translucentFlag = translucentFlag;
+ this.verticalGravity = verticalGravity;
+ this.transitionName = transitionName;
+ this.hideWindowFlag = hideWindowFlag;
+ }
+ }
+
void sendCloseSystemWindows() {
PhoneWindowManager.sendCloseSystemWindows(getContext(), null);
}
@@ -4621,7 +4750,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mStatusBarColor = color;
mForcedStatusBarColor = true;
if (mDecor != null) {
- mDecor.updateColorViews(null);
+ mDecor.updateColorViews(null, false /* animate */);
}
}
@@ -4635,7 +4764,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mNavigationBarColor = color;
mForcedNavigationBarColor = true;
if (mDecor != null) {
- mDecor.updateColorViews(null);
+ mDecor.updateColorViews(null, false /* animate */);
}
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 54fb89d..e855cf1 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -48,6 +48,7 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.media.session.MediaSessionLegacyHelper;
import android.os.Bundle;
+import android.os.Debug;
import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
@@ -102,8 +103,6 @@ import android.view.animation.AnimationSet;
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;
@@ -116,6 +115,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
+import java.util.List;
import static android.view.WindowManager.LayoutParams.*;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
@@ -136,8 +136,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final String TAG = "WindowManager";
static final boolean DEBUG = false;
static final boolean localLOGV = false;
- static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_INPUT = false;
+ static final boolean DEBUG_KEYGUARD = false;
+ static final boolean DEBUG_LAYOUT = false;
static final boolean DEBUG_STARTING_WINDOW = false;
static final boolean DEBUG_WAKEUP = false;
static final boolean SHOW_STARTING_ANIMATIONS = true;
@@ -340,6 +341,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mUndockedHdmiRotation;
int mDemoHdmiRotation;
boolean mDemoHdmiRotationLock;
+ int mDemoRotation;
+ boolean mDemoRotationLock;
boolean mWakeGestureEnabledSetting;
MyWakeGestureListener mWakeGestureListener;
@@ -478,6 +481,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mShowingLockscreen;
boolean mShowingDream;
boolean mDreamingLockscreen;
+ boolean mKeyguardSecure;
+ boolean mKeyguardSecureIncludingHidden;
+ volatile boolean mKeyguardOccluded;
boolean mHomePressed;
boolean mHomeConsumed;
boolean mHomeDoubleTapPending;
@@ -1103,7 +1109,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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,
@@ -1446,6 +1452,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
+ // For demo purposes, allow the rotation of the remote display to be controlled.
+ // By default, remote display locks rotation to landscape.
+ if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
+ mDemoRotation = mPortraitRotation;
+ } else {
+ mDemoRotation = mLandscapeRotation;
+ }
+ mDemoRotationLock = SystemProperties.getBoolean(
+ "persist.demo.rotationlock", false);
+
// Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
// http://developer.android.com/guide/practices/screens_support.html#range
mForceDefaultOrientation = longSizeDp >= 960 && shortSizeDp >= 720 &&
@@ -1625,8 +1641,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
outAppOp[0] = AppOpsManager.OP_NONE;
- if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
- || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
+ if (!((type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW)
+ || (type >= FIRST_SUB_WINDOW && type <= LAST_SUB_WINDOW)
+ || (type >= FIRST_SYSTEM_WINDOW && type <= LAST_SYSTEM_WINDOW))) {
+ return WindowManagerGlobal.ADD_INVALID_TYPE;
+ }
+
+ if (type < FIRST_SYSTEM_WINDOW || type > LAST_SYSTEM_WINDOW) {
+ // Window manager will make sure these are okay.
return WindowManagerGlobal.ADD_OKAY;
}
String permission = null;
@@ -1642,6 +1664,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_WALLPAPER:
case TYPE_PRIVATE_PRESENTATION:
case TYPE_VOICE_INTERACTION:
+ case TYPE_ACCESSIBILITY_OVERLAY:
// The window manager will check these.
break;
case TYPE_PHONE:
@@ -1695,7 +1718,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_PHONE:
case TYPE_POINTER:
case TYPE_PRIORITY_PHONE:
- case TYPE_RECENTS_OVERLAY:
case TYPE_SEARCH_BAR:
case TYPE_STATUS_BAR:
case TYPE_STATUS_BAR_PANEL:
@@ -1814,7 +1836,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_VOICE_INTERACTION:
// voice interaction layer is almost immediately above apps.
return 5;
- case TYPE_RECENTS_OVERLAY:
case TYPE_SYSTEM_DIALOG:
return 6;
case TYPE_TOAST:
@@ -1873,15 +1894,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
return 25;
- case TYPE_SECURE_SYSTEM_OVERLAY:
+ case TYPE_ACCESSIBILITY_OVERLAY:
+ // overlay put by accessibility services to intercept user interaction
return 26;
- case TYPE_BOOT_PROGRESS:
+ case TYPE_SECURE_SYSTEM_OVERLAY:
return 27;
+ case TYPE_BOOT_PROGRESS:
+ return 28;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 28;
- case TYPE_HIDDEN_NAV_CONSUMER:
return 29;
+ case TYPE_HIDDEN_NAV_CONSUMER:
+ return 30;
}
Log.e(TAG, "Unknown window type: " + type);
return 2;
@@ -1956,7 +1980,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@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);
}
@@ -2108,11 +2133,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
@Override
public void removeStartingWindow(IBinder appToken, View window) {
- if (DEBUG_STARTING_WINDOW) {
- RuntimeException e = new RuntimeException("here");
- e.fillInStackTrace();
- Log.v(TAG, "Removing starting window for " + appToken + ": " + window, e);
- }
+ if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Removing starting window for " + appToken + ": "
+ + window + " Callers=" + Debug.getCallers(4));
if (window != null) {
WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
@@ -2149,7 +2171,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mStatusBar = win;
mStatusBarController.setWindow(win);
- mKeyguardDelegate.hideScrim();
break;
case TYPE_NAVIGATION_BAR:
mContext.enforceCallingOrSelfPermission(
@@ -2185,7 +2206,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
mKeyguardScrim = win;
break;
-
}
return WindowManagerGlobal.ADD_OKAY;
}
@@ -2309,24 +2329,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean goingToNotificationShade) {
if (goingToNotificationShade) {
return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
- } else if (onWallpaper) {
- Animation a = AnimationUtils.loadAnimation(mContext,
- R.anim.lock_screen_behind_enter_wallpaper);
- AnimationSet set = (AnimationSet) a;
-
- // TODO: Use XML interpolators when we have log interpolators available in XML.
- set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
- set.getAnimations().get(1).setInterpolator(mLogDecelerateInterpolator);
- return set;
- } else {
- Animation a = AnimationUtils.loadAnimation(mContext,
+ }
+
+ AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
+ R.anim.lock_screen_behind_enter_wallpaper :
R.anim.lock_screen_behind_enter);
- AnimationSet set = (AnimationSet) a;
- // TODO: Use XML interpolators when we have log interpolators available in XML.
- set.getAnimations().get(0).setInterpolator(mLogDecelerateInterpolator);
- return set;
+ // TODO: Use XML interpolators when we have log interpolators available in XML.
+ final List<Animation> animations = set.getAnimations();
+ for (int i = animations.size() - 1; i >= 0; --i) {
+ animations.get(i).setInterpolator(mLogDecelerateInterpolator);
}
+
+ return set;
}
@@ -2369,7 +2384,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
boolean keyguardOn() {
- return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode();
+ return isKeyguardShowingAndNotOccluded() || inKeyguardRestrictedKeyInputMode();
}
private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = {
@@ -2962,7 +2977,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* 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
@@ -3091,7 +3106,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
+ public void getInsetHintLw(WindowManager.LayoutParams attrs, Rect outContentInsets,
+ Rect outStableInsets) {
final int fl = PolicyControl.getWindowFlags(null, attrs);
final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs);
final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility);
@@ -3109,26 +3125,30 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if ((systemUiVisibility & View.SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
if ((fl & FLAG_FULLSCREEN) != 0) {
- contentInset.set(mStableFullscreenLeft, mStableFullscreenTop,
+ outContentInsets.set(mStableFullscreenLeft, mStableFullscreenTop,
availRight - mStableFullscreenRight,
availBottom - mStableFullscreenBottom);
} else {
- contentInset.set(mStableLeft, mStableTop,
+ outContentInsets.set(mStableLeft, mStableTop,
availRight - mStableRight, availBottom - mStableBottom);
}
} else if ((fl & FLAG_FULLSCREEN) != 0 || (fl & FLAG_LAYOUT_IN_OVERSCAN) != 0) {
- contentInset.setEmpty();
+ outContentInsets.setEmpty();
} else if ((systemUiVisibility & (View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)) == 0) {
- contentInset.set(mCurLeft, mCurTop,
+ outContentInsets.set(mCurLeft, mCurTop,
availRight - mCurRight, availBottom - mCurBottom);
} else {
- contentInset.set(mCurLeft, mCurTop,
+ outContentInsets.set(mCurLeft, mCurTop,
availRight - mCurRight, availBottom - mCurBottom);
}
+
+ outStableInsets.set(mStableLeft, mStableTop,
+ availRight - mStableRight, availBottom - mStableBottom);
return;
}
- contentInset.setEmpty();
+ outContentInsets.setEmpty();
+ outStableInsets.setEmpty();
}
/** {@inheritDoc} */
@@ -3420,10 +3440,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// whether it is taking care of insetting its content. If not,
// we need to use the parent's content frame so that the entire
// window is positioned within that content. Otherwise we can use
- // the display frame and let the attached window take care of
+ // the overscan frame and let the attached window take care of
// positioning its content appropriately.
if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
- cf.set(attached.getOverscanFrameLw());
+ // Set the content frame of the attached window to the parent's decor frame
+ // (same as content frame when IME isn't present) if specifically requested by
+ // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag.
+ // Otherwise, use the overscan frame.
+ cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0
+ ? attached.getContentFrameLw() : attached.getOverscanFrameLw());
} else {
// If the window is resizing, then we want to base the content
// frame on our attached content frame to resize... however,
@@ -3986,11 +4011,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mShowingLockscreen = false;
mShowingDream = false;
mWinShowWhenLocked = null;
+ mKeyguardSecure = isKeyguardSecure();
+ mKeyguardSecureIncludingHidden = mKeyguardSecure
+ && (mKeyguardDelegate != null && mKeyguardDelegate.isShowing());
}
/** {@inheritDoc} */
@Override
- public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs) {
+ public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
+ WindowState attached) {
+
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+ win.isVisibleOrBehindKeyguardLw());
final int fl = PolicyControl.getWindowFlags(win, attrs);
@@ -4028,20 +4058,27 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
- final boolean secureKeyguard = isKeyguardSecure();
- if (appWindow) {
- final IApplicationToken appToken = win.getAppToken();
+ final IApplicationToken appToken = win.getAppToken();
+
+ // For app windows that are not attached, we decide if all windows in the app they
+ // represent should be hidden or if we should hide the lockscreen. For attached app
+ // windows we defer the decision to the window it is attached to.
+ if (appWindow && attached == null) {
if (showWhenLocked) {
// Remove any previous windows with the same appToken.
mAppsToBeHidden.remove(appToken);
mAppsThatDismissKeyguard.remove(appToken);
- if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) {
- mWinShowWhenLocked = win;
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
+ if (mAppsToBeHidden.isEmpty()) {
+ if (dismissKeyguard && !mKeyguardSecure) {
+ mAppsThatDismissKeyguard.add(appToken);
+ } else {
+ mWinShowWhenLocked = win;
+ mHideLockScreen = true;
+ mForceStatusBarFromKeyguard = false;
+ }
}
} else if (dismissKeyguard) {
- if (secureKeyguard) {
+ if (mKeyguardSecure) {
mAppsToBeHidden.add(appToken);
} else {
mAppsToBeHidden.remove(appToken);
@@ -4062,7 +4099,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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);
@@ -4173,9 +4210,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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;
@@ -4190,7 +4227,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
} 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;
@@ -4200,7 +4237,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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;
@@ -4215,7 +4252,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} 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;
@@ -4235,23 +4272,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
/**
- * 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;
@@ -4462,7 +4498,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// when the keyguard is hidden by another activity.
final boolean keyguardActive = (mKeyguardDelegate == null ? false :
(interactive ?
- mKeyguardDelegate.isShowingAndNotOccluded() :
+ isKeyguardShowingAndNotOccluded() :
mKeyguardDelegate.isShowing()));
if (DEBUG_INPUT) {
@@ -4802,7 +4838,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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;
}
@@ -5174,12 +5211,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- private boolean keyguardIsShowingTq() {
+ private boolean isKeyguardShowingAndNotOccluded() {
if (mKeyguardDelegate == null) return false;
- return mKeyguardDelegate.isShowingAndNotOccluded();
+ return mKeyguardDelegate.isShowing() && !mKeyguardOccluded;
}
-
/** {@inheritDoc} */
@Override
public boolean isKeyguardLocked() {
@@ -5193,11 +5229,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
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() {
@@ -5208,6 +5239,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void dismissKeyguardLw() {
if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.dismissKeyguardLw");
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -5239,6 +5271,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
if (mKeyguardDelegate != null) {
+ if (DEBUG_KEYGUARD) Slog.d(TAG, "PWM.startKeyguardExitAnimation");
mKeyguardDelegate.startKeyguardExitAnimation(startTime, fadeoutDuration);
}
}
@@ -5312,6 +5345,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// full multi-display support).
// Note that the dock orientation overrides the HDMI orientation.
preferredRotation = mUndockedHdmiRotation;
+ } else if (mDemoRotationLock) {
+ // Ignore sensor when demo rotation lock is enabled.
+ // Note that the dock orientation and HDMI rotation lock override this.
+ preferredRotation = mDemoRotation;
} else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
// Application just wants to remain locked in the last rotation.
preferredRotation = lastRotation;
@@ -5506,7 +5543,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
@Override
public void systemReady() {
- mKeyguardDelegate = new KeyguardServiceDelegate(mContext, null);
+ mKeyguardDelegate = new KeyguardServiceDelegate(mContext);
mKeyguardDelegate.onSystemReady();
readCameraLensCoverState();
@@ -5953,7 +5990,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void keepScreenOnStoppedLw() {
- if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotOccluded()) {
+ if (isKeyguardShowingAndNotOccluded()) {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
}
@@ -5961,7 +5998,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private int updateSystemUiVisibilityLw() {
// If there is no window focused, there will be nobody to handle the events
// anyway, so just hang on in whatever state we're in until things settle down.
- WindowState win = mFocusedWindow != null ? mFocusedWindow : mTopFullscreenOpaqueWindowState;
+ final WindowState win = mFocusedWindow != null ? mFocusedWindow
+ : mTopFullscreenOpaqueWindowState;
if (win == null) {
return 0;
}
@@ -5997,7 +6035,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
try {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
- statusbar.setSystemUiVisibility(visibility, 0xffffffff);
+ statusbar.setSystemUiVisibility(visibility, 0xffffffff, win.toString());
statusbar.topAppWindowChanged(needsMenu);
}
} catch (RemoteException e) {
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
deleted file mode 100644
index bc55ed1..0000000
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2008 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;
-
-import android.app.ActivityManager;
-import android.app.Dialog;
-import android.app.StatusBarManager;
-import android.content.ActivityNotFoundException;
-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.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Handler;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.View.OnClickListener;
-import android.widget.TextView;
-
-import java.util.List;
-
-public class RecentApplicationsDialog extends Dialog implements OnClickListener {
- // Elements for debugging support
-// private static final String LOG_TAG = "RecentApplicationsDialog";
- private static final boolean DBG_FORCE_EMPTY_LIST = false;
-
- static private StatusBarManager sStatusBar;
-
- private static final int NUM_BUTTONS = 8;
- private static final int MAX_RECENT_TASKS = NUM_BUTTONS * 2; // allow for some discards
-
- final TextView[] mIcons = new TextView[NUM_BUTTONS];
- View mNoAppsText;
- IntentFilter mBroadcastIntentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-
- class RecentTag {
- ActivityManager.RecentTaskInfo info;
- Intent intent;
- }
-
- Handler mHandler = new Handler();
- Runnable mCleanup = new Runnable() {
- public void run() {
- // dump extra memory we're hanging on to
- for (TextView icon: mIcons) {
- icon.setCompoundDrawables(null, null, null, null);
- icon.setTag(null);
- }
- }
- };
-
- public RecentApplicationsDialog(Context context) {
- super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
-
- }
-
- /**
- * We create the recent applications dialog just once, and it stays around (hidden)
- * until activated by the user.
- *
- * @see PhoneWindowManager#showRecentAppsDialog
- */
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Context context = getContext();
-
- if (sStatusBar == null) {
- sStatusBar = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE);
- }
-
- Window window = getWindow();
- window.requestFeature(Window.FEATURE_NO_TITLE);
- window.setType(WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY);
- window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
- WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
- window.setTitle("Recents");
-
- setContentView(com.android.internal.R.layout.recent_apps_dialog);
-
- final WindowManager.LayoutParams params = window.getAttributes();
- params.width = WindowManager.LayoutParams.MATCH_PARENT;
- params.height = WindowManager.LayoutParams.MATCH_PARENT;
- window.setAttributes(params);
- window.setFlags(0, WindowManager.LayoutParams.FLAG_DIM_BEHIND);
-
- mIcons[0] = (TextView)findViewById(com.android.internal.R.id.button0);
- mIcons[1] = (TextView)findViewById(com.android.internal.R.id.button1);
- mIcons[2] = (TextView)findViewById(com.android.internal.R.id.button2);
- mIcons[3] = (TextView)findViewById(com.android.internal.R.id.button3);
- mIcons[4] = (TextView)findViewById(com.android.internal.R.id.button4);
- mIcons[5] = (TextView)findViewById(com.android.internal.R.id.button5);
- mIcons[6] = (TextView)findViewById(com.android.internal.R.id.button6);
- mIcons[7] = (TextView)findViewById(com.android.internal.R.id.button7);
- mNoAppsText = findViewById(com.android.internal.R.id.no_applications_message);
-
- for (TextView b: mIcons) {
- b.setOnClickListener(this);
- }
- }
-
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_TAB) {
- // Ignore all meta keys other than SHIFT. The app switch key could be a
- // fallback action chorded with ALT, META or even CTRL depending on the key map.
- // DPad navigation is handled by the ViewRoot elsewhere.
- final boolean backward = event.isShiftPressed();
- final int numIcons = mIcons.length;
- int numButtons = 0;
- while (numButtons < numIcons && mIcons[numButtons].getVisibility() == View.VISIBLE) {
- numButtons += 1;
- }
- if (numButtons != 0) {
- int nextFocus = backward ? numButtons - 1 : 0;
- for (int i = 0; i < numButtons; i++) {
- if (mIcons[i].hasFocus()) {
- if (backward) {
- nextFocus = (i + numButtons - 1) % numButtons;
- } else {
- nextFocus = (i + 1) % numButtons;
- }
- break;
- }
- }
- final int direction = backward ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
- if (mIcons[nextFocus].requestFocus(direction)) {
- mIcons[nextFocus].playSoundEffect(
- SoundEffectConstants.getContantForFocusDirection(direction));
- }
- }
-
- // The dialog always handles the key to prevent the ViewRoot from
- // performing the default navigation itself.
- return true;
- }
-
- return super.onKeyDown(keyCode, event);
- }
-
- /**
- * Dismiss the dialog and switch to the selected application.
- */
- public void dismissAndSwitch() {
- final int numIcons = mIcons.length;
- RecentTag tag = null;
- for (int i = 0; i < numIcons; i++) {
- if (mIcons[i].getVisibility() != View.VISIBLE) {
- break;
- }
- if (i == 0 || mIcons[i].hasFocus()) {
- tag = (RecentTag) mIcons[i].getTag();
- if (mIcons[i].hasFocus()) {
- break;
- }
- }
- }
- if (tag != null) {
- switchTo(tag);
- }
- dismiss();
- }
-
- /**
- * Handler for user clicks. If a button was clicked, launch the corresponding activity.
- */
- public void onClick(View v) {
- for (TextView b: mIcons) {
- if (b == v) {
- RecentTag tag = (RecentTag)b.getTag();
- switchTo(tag);
- break;
- }
- }
- dismiss();
- }
-
- private void switchTo(RecentTag tag) {
- if (tag.info.id >= 0) {
- // This is an active task; it should just go to the foreground.
- final ActivityManager am = (ActivityManager)
- getContext().getSystemService(Context.ACTIVITY_SERVICE);
- am.moveTaskToFront(tag.info.id, ActivityManager.MOVE_TASK_WITH_HOME);
- } else if (tag.intent != null) {
- tag.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
- | Intent.FLAG_ACTIVITY_TASK_ON_HOME);
- try {
- getContext().startActivity(tag.intent);
- } catch (ActivityNotFoundException e) {
- Log.w("Recent", "Unable to launch recent task", e);
- }
- }
- }
-
- /**
- * Set up and show the recent activities dialog.
- */
- @Override
- public void onStart() {
- super.onStart();
- reloadButtons();
- if (sStatusBar != null) {
- sStatusBar.disable(StatusBarManager.DISABLE_EXPAND);
- }
-
- // receive broadcasts
- getContext().registerReceiver(mBroadcastReceiver, mBroadcastIntentFilter);
-
- mHandler.removeCallbacks(mCleanup);
- }
-
- /**
- * Dismiss the recent activities dialog.
- */
- @Override
- public void onStop() {
- super.onStop();
-
- if (sStatusBar != null) {
- sStatusBar.disable(StatusBarManager.DISABLE_NONE);
- }
-
- // stop receiving broadcasts
- getContext().unregisterReceiver(mBroadcastReceiver);
-
- mHandler.postDelayed(mCleanup, 100);
- }
-
- /**
- * Reload the 6 buttons with recent activities
- */
- private void reloadButtons() {
-
- final Context context = getContext();
- final PackageManager pm = context.getPackageManager();
- final ActivityManager am = (ActivityManager)
- context.getSystemService(Context.ACTIVITY_SERVICE);
- final List<ActivityManager.RecentTaskInfo> recentTasks =
- am.getRecentTasks(MAX_RECENT_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
-
- ActivityInfo homeInfo =
- new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
- .resolveActivityInfo(pm, 0);
-
- IconUtilities iconUtilities = new IconUtilities(getContext());
-
- // Performance note: Our android performance guide says to prefer Iterator when
- // using a List class, but because we know that getRecentTasks() always returns
- // an ArrayList<>, we'll use a simple index instead.
- int index = 0;
- int numTasks = recentTasks.size();
- for (int i = 0; i < numTasks && (index < NUM_BUTTONS); ++i) {
- final ActivityManager.RecentTaskInfo info = recentTasks.get(i);
-
- // for debug purposes only, disallow first result to create empty lists
- if (DBG_FORCE_EMPTY_LIST && (i == 0)) continue;
-
- Intent intent = new Intent(info.baseIntent);
- if (info.origActivity != null) {
- intent.setComponent(info.origActivity);
- }
-
- // Skip the current home activity.
- if (homeInfo != null) {
- if (homeInfo.packageName.equals(
- intent.getComponent().getPackageName())
- && homeInfo.name.equals(
- intent.getComponent().getClassName())) {
- continue;
- }
- }
-
- intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
- | Intent.FLAG_ACTIVITY_NEW_TASK);
- final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
- if (resolveInfo != null) {
- final ActivityInfo activityInfo = resolveInfo.activityInfo;
- final String title = activityInfo.loadLabel(pm).toString();
- Drawable icon = activityInfo.loadIcon(pm);
-
- if (title != null && title.length() > 0 && icon != null) {
- final TextView tv = mIcons[index];
- tv.setText(title);
- icon = iconUtilities.createIconDrawable(icon);
- tv.setCompoundDrawables(null, icon, null, null);
- RecentTag tag = new RecentTag();
- tag.info = info;
- tag.intent = intent;
- tv.setTag(tag);
- tv.setVisibility(View.VISIBLE);
- tv.setPressed(false);
- tv.clearFocus();
- ++index;
- }
- }
- }
-
- // handle the case of "no icons to show"
- mNoAppsText.setVisibility((index == 0) ? View.VISIBLE : View.GONE);
-
- // hide the rest
- for (; index < NUM_BUTTONS; ++index) {
- mIcons[index].setVisibility(View.GONE);
- }
- }
-
- /**
- * This is the listener for the ACTION_CLOSE_SYSTEM_DIALOGS intent. It's an indication that
- * we should close ourselves immediately, in order to allow a higher-priority UI to take over
- * (e.g. phone call received).
- */
- private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY);
- if (! PhoneWindowManager.SYSTEM_DIALOG_REASON_RECENT_APPS.equals(reason)) {
- dismiss();
- }
- }
- }
- };
-}
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..6e8f550 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.WindowManager;
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,17 @@ import com.android.internal.widget.LockPatternUtils;
* 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();
+ private ShowListener mShowListenerWhenConnect;
/* package */ static final class KeyguardState {
KeyguardState() {
@@ -46,6 +47,7 @@ public class KeyguardServiceDelegate {
showing = true;
showingAndNotOccluded = true;
secure = true;
+ deviceHasKeyguard = true;
}
boolean showing;
boolean showingAndNotOccluded;
@@ -54,6 +56,7 @@ public class KeyguardServiceDelegate {
boolean secure;
boolean dreaming;
boolean systemIsReady;
+ boolean deviceHasKeyguard;
public boolean enabled;
public boolean dismissable;
public int offReason;
@@ -101,7 +104,8 @@ public class KeyguardServiceDelegate {
}
};
- public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) {
+ public KeyguardServiceDelegate(Context context) {
+ mContext = context;
mScrim = createScrim(context);
}
@@ -110,10 +114,12 @@ public class KeyguardServiceDelegate {
intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS);
if (!context.bindServiceAsUser(intent, mKeyguardConnection,
Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
- if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
+ Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
mKeyguardState.showing = false;
mKeyguardState.showingAndNotOccluded = false;
mKeyguardState.secure = false;
+ mKeyguardState.deviceHasKeyguard = false;
+ hideScrim();
} else {
if (DEBUG) Log.v(TAG, "*** Keyguard started");
}
@@ -123,13 +129,15 @@ public class KeyguardServiceDelegate {
@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.
mKeyguardService.onSystemReady();
// This is used to hide the scrim once keyguard displays.
- mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null));
+ mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(
+ mShowListenerWhenConnect));
+ mShowListenerWhenConnect = null;
}
if (mKeyguardState.bootCompleted) {
mKeyguardService.onBootCompleted();
@@ -151,13 +159,6 @@ public class KeyguardServiceDelegate {
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 +178,11 @@ public class KeyguardServiceDelegate {
}
}
- 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() {
@@ -220,9 +219,10 @@ public class KeyguardServiceDelegate {
} else {
// try again when we establish a connection
Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!");
- // This shouldn't happen, but if it does, invoke the listener immediately
- // to avoid a dark screen...
- showListener.onShown(null);
+ // This shouldn't happen, but if it does, show the scrim immediately and
+ // invoke the listener's callback after the service actually connects.
+ mShowListenerWhenConnect = showListener;
+ showScrim();
}
mKeyguardState.screenIsOn = true;
}
@@ -242,13 +242,6 @@ public class KeyguardServiceDelegate {
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 +256,6 @@ public class KeyguardServiceDelegate {
}
}
- public void showAssistant() {
- if (mKeyguardService != null) {
- mKeyguardService.showAssistant();
- }
- }
-
public void setCurrentUser(int newUserId) {
if (mKeyguardService != null) {
mKeyguardService.setCurrentUser(newUserId);
@@ -301,7 +288,6 @@ public class KeyguardServiceDelegate {
lp.setTitle("KeyguardScrim");
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
wm.addView(view, lp);
- view.setVisibility(View.GONE);
// Disable pretty much everything in statusbar until keyguard comes back and we know
// the state of the world.
view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME
@@ -313,6 +299,7 @@ public class KeyguardServiceDelegate {
}
public void showScrim() {
+ if (!mKeyguardState.deviceHasKeyguard) return;
mScrim.post(new Runnable() {
@Override
public void run() {
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,83 +33,52 @@ import com.android.internal.policy.IKeyguardService;
*
*/
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() {
+ @Override // Binder interface
+ public void verifyUnlock(IKeyguardExitCallback callback) {
try {
- return mService.isDismissable();
+ mService.verifyUnlock(callback);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
- return true; // TODO cache state
}
- public void verifyUnlock(IKeyguardExitCallback callback) {
+ @Override // Binder interface
+ public void keyguardDone(boolean authenticated, boolean wakeup) {
try {
- mService.verifyUnlock(callback);
+ mService.keyguardDone(authenticated, wakeup);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
- public void keyguardDone(boolean authenticated, boolean wakeup) {
+ @Override // Binder interface
+ public void setOccluded(boolean isOccluded) {
try {
- mService.keyguardDone(authenticated, wakeup);
+ mService.setOccluded(isOccluded);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
}
- public int setOccluded(boolean isOccluded) {
+ @Override
+ public void addStateMonitorCallback(IKeyguardStateCallback callback) {
try {
- return mService.setOccluded(isOccluded);
+ mService.addStateMonitorCallback(callback);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
- return IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_NONE;
}
}
+ @Override // Binder interface
public void dismiss() {
try {
mService.dismiss();
@@ -118,6 +87,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onDreamingStarted() {
try {
mService.onDreamingStarted();
@@ -126,6 +96,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onDreamingStopped() {
try {
mService.onDreamingStopped();
@@ -134,6 +105,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onScreenTurnedOff(int reason) {
try {
mService.onScreenTurnedOff(reason);
@@ -142,6 +114,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onScreenTurnedOn(IKeyguardShowCallback result) {
try {
mService.onScreenTurnedOn(result);
@@ -150,6 +123,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void setKeyguardEnabled(boolean enabled) {
try {
mService.setKeyguardEnabled(enabled);
@@ -158,6 +132,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onSystemReady() {
try {
mService.onSystemReady();
@@ -166,6 +141,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void doKeyguardTimeout(Bundle options) {
try {
mService.doKeyguardTimeout(options);
@@ -174,7 +150,9 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void setCurrentUser(int userId) {
+ mKeyguardStateMonitor.setCurrentUser(userId);
try {
mService.setCurrentUser(userId);
} catch (RemoteException e) {
@@ -182,6 +160,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onBootCompleted() {
try {
mService.onBootCompleted();
@@ -190,6 +169,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
try {
mService.startKeyguardExitAnimation(startTime, fadeoutDuration);
@@ -198,6 +178,7 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
+ @Override // Binder interface
public void onActivityDrawn() {
try {
mService.onActivityDrawn();
@@ -206,21 +187,20 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
- public void showAssistant() {
- // Not used by PhoneWindowManager
+ @Override // Binder interface
+ public IBinder asBinder() {
+ return mService.asBinder();
}
- public void dispatch(MotionEvent event) {
- // Not used by PhoneWindowManager. See code in {@link NavigationBarView}
+ public boolean isShowing() {
+ return mKeyguardStateMonitor.isShowing();
}
- public void launchCamera() {
- // Not used by PhoneWindowManager. See code in {@link NavigationBarView}
+ public boolean isSecure() {
+ return mKeyguardStateMonitor.isSecure();
}
- @Override
- public IBinder asBinder() {
- return mService.asBinder();
+ 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