summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/BarController.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/GlobalActions.java56
-rw-r--r--policy/src/com/android/internal/policy/impl/IconUtilities.java9
-rw-r--r--policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java123
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java239
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java347
-rw-r--r--policy/src/com/android/internal/policy/impl/PolicyControl.java256
-rw-r--r--policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/ShortcutManager.java1
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java27
-rw-r--r--policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java10
12 files changed, 788 insertions, 285 deletions
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java
index 0ce4b12..fc49a569 100644
--- a/policy/src/com/android/internal/policy/impl/BarController.java
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -108,7 +108,7 @@ public class BarController {
if (mWin != null) {
if (win != null && (win.getAttrs().privateFlags
& WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) {
- if ((win.getAttrs().flags & mTranslucentWmFlag) != 0) {
+ if ((PolicyControl.getWindowFlags(win, null) & mTranslucentWmFlag) != 0) {
vis |= mTranslucentFlag;
} else {
vis &= ~mTranslucentFlag;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index b8300af..fec9dda 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -417,36 +417,38 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
}
private void addUsersToMenu(ArrayList<Action> items) {
- List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
- .getUsers();
- if (users.size() > 1) {
+ UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ if (um.isUserSwitcherEnabled()) {
+ List<UserInfo> users = um.getUsers();
UserInfo currentUser = getCurrentUser();
for (final UserInfo user : users) {
- boolean isCurrentUser = currentUser == null
- ? user.id == 0 : (currentUser.id == user.id);
- Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
- : null;
- SinglePressAction switchToUser = new SinglePressAction(
- com.android.internal.R.drawable.ic_menu_cc, icon,
- (user.name != null ? user.name : "Primary")
- + (isCurrentUser ? " \u2714" : "")) {
- public void onPress() {
- try {
- ActivityManagerNative.getDefault().switchUser(user.id);
- } catch (RemoteException re) {
- Log.e(TAG, "Couldn't switch user " + re);
+ if (user.supportsSwitchTo()) {
+ boolean isCurrentUser = currentUser == null
+ ? user.id == 0 : (currentUser.id == user.id);
+ Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
+ : null;
+ SinglePressAction switchToUser = new SinglePressAction(
+ com.android.internal.R.drawable.ic_menu_cc, icon,
+ (user.name != null ? user.name : "Primary")
+ + (isCurrentUser ? " \u2714" : "")) {
+ public void onPress() {
+ try {
+ ActivityManagerNative.getDefault().switchUser(user.id);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Couldn't switch user " + re);
+ }
}
- }
- public boolean showDuringKeyguard() {
- return true;
- }
+ public boolean showDuringKeyguard() {
+ return true;
+ }
- public boolean showBeforeProvisioning() {
- return false;
- }
- };
- items.add(switchToUser);
+ public boolean showBeforeProvisioning() {
+ return false;
+ }
+ };
+ items.add(switchToUser);
+ }
}
}
}
@@ -645,7 +647,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
icon.setImageDrawable(mIcon);
icon.setScaleType(ScaleType.CENTER_CROP);
} else if (mIconResId != 0) {
- icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+ icon.setImageDrawable(context.getDrawable(mIconResId));
}
if (mMessage != null) {
messageView.setText(mMessage);
@@ -735,7 +737,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
boolean on = ((mState == State.On) || (mState == State.TurningOn));
if (icon != null) {
- icon.setImageDrawable(context.getResources().getDrawable(
+ icon.setImageDrawable(context.getDrawable(
(on ? mEnabledIconResId : mDisabledIconResid)));
icon.setEnabled(enabled);
}
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index a47c904..82f26ad 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -24,22 +24,13 @@ import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.TableMaskFilter;
-import android.graphics.Typeface;
-import android.text.Layout.Alignment;
-import android.text.StaticLayout;
-import android.text.TextPaint;
import android.util.DisplayMetrics;
-import android.util.Log;
import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
import android.content.res.Resources;
import android.content.Context;
diff --git a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
index b734c41..5602206 100644
--- a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
+++ b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
@@ -19,6 +19,7 @@ package com.android.internal.policy.impl;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -27,12 +28,12 @@ import android.graphics.PixelFormat;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.Slog;
+import android.util.SparseBooleanArray;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@@ -46,8 +47,6 @@ import android.widget.FrameLayout;
import com.android.internal.R;
-import java.util.Arrays;
-
/**
* Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden
* entering immersive mode.
@@ -56,19 +55,19 @@ public class ImmersiveModeConfirmation {
private static final String TAG = "ImmersiveModeConfirmation";
private static final boolean DEBUG = false;
private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution
+ private static final String CONFIRMED = "confirmed";
private final Context mContext;
private final H mHandler;
- private final ArraySet<String> mConfirmedPackages = new ArraySet<String>();
private final long mShowDelayMs;
private final long mPanicThresholdMs;
+ private final SparseBooleanArray mUserPanicResets = new SparseBooleanArray();
+ private boolean mConfirmed;
private ClingWindowView mClingWindow;
- private String mLastPackage;
- private String mPromptPackage;
private long mPanicTime;
- private String mPanicPackage;
private WindowManager mWindowManager;
+ private int mCurrentUserId;
public ImmersiveModeConfirmation(Context context) {
mContext = context;
@@ -85,83 +84,84 @@ public class ImmersiveModeConfirmation {
return exit != null ? exit.getDuration() : 0;
}
- public void loadSetting() {
- if (DEBUG) Slog.d(TAG, "loadSetting()");
- mConfirmedPackages.clear();
- String packages = null;
+ public void loadSetting(int currentUserId) {
+ mConfirmed = false;
+ mCurrentUserId = currentUserId;
+ if (DEBUG) Slog.d(TAG, String.format("loadSetting() mCurrentUserId=%d resetForPanic=%s",
+ mCurrentUserId, mUserPanicResets.get(mCurrentUserId, false)));
+ String value = null;
try {
- packages = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ value = Settings.Secure.getStringForUser(mContext.getContentResolver(),
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
UserHandle.USER_CURRENT);
- if (packages != null) {
- mConfirmedPackages.addAll(Arrays.asList(packages.split(",")));
- if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages);
- }
+ mConfirmed = CONFIRMED.equals(value);
+ if (DEBUG) Slog.d(TAG, "Loaded mConfirmed=" + mConfirmed);
} catch (Throwable t) {
- Slog.w(TAG, "Error loading confirmations, packages=" + packages, t);
+ Slog.w(TAG, "Error loading confirmations, value=" + value, t);
}
}
private void saveSetting() {
if (DEBUG) Slog.d(TAG, "saveSetting()");
try {
- final String packages = TextUtils.join(",", mConfirmedPackages);
+ final String value = mConfirmed ? CONFIRMED : null;
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
- packages,
+ value,
UserHandle.USER_CURRENT);
- if (DEBUG) Slog.d(TAG, "Saved packages=" + packages);
+ if (DEBUG) Slog.d(TAG, "Saved value=" + value);
} catch (Throwable t) {
- Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t);
+ Slog.w(TAG, "Error saving confirmations, mConfirmed=" + mConfirmed, t);
}
}
public void immersiveModeChanged(String pkg, boolean isImmersiveMode) {
- if (pkg == null) {
- return;
- }
mHandler.removeMessages(H.SHOW);
if (isImmersiveMode) {
- mLastPackage = pkg;
- if (DEBUG_SHOW_EVERY_TIME || !mConfirmedPackages.contains(pkg)) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs);
+ final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg);
+ if (DEBUG) Slog.d(TAG, String.format("immersiveModeChanged() disabled=%s mConfirmed=%s",
+ disabled, mConfirmed));
+ if (!disabled && (DEBUG_SHOW_EVERY_TIME || !mConfirmed)) {
+ mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
}
} else {
- mLastPackage = null;
mHandler.sendEmptyMessage(H.HIDE);
}
}
- public void onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
- if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
+ public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
+ if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
// turning the screen back on within the panic threshold
- unconfirmPackage(mPanicPackage);
+ mHandler.sendEmptyMessage(H.PANIC);
+ return mClingWindow == null;
}
if (isScreenOn && inImmersiveMode) {
// turning the screen off, remember if we were in immersive mode
mPanicTime = time;
- mPanicPackage = mLastPackage;
} else {
mPanicTime = 0;
- mPanicPackage = null;
}
+ return false;
}
public void confirmCurrentPrompt() {
- mHandler.post(confirmAction(mPromptPackage));
+ if (mClingWindow != null) {
+ if (DEBUG) Slog.d(TAG, "confirmCurrentPrompt()");
+ mHandler.post(mConfirm);
+ }
}
- private void unconfirmPackage(String pkg) {
- if (pkg != null) {
- if (DEBUG) Slog.d(TAG, "Unconfirming immersive mode confirmation for " + pkg);
- mConfirmedPackages.remove(pkg);
- saveSetting();
- }
+ private void handlePanic() {
+ if (DEBUG) Slog.d(TAG, "handlePanic()");
+ if (mUserPanicResets.get(mCurrentUserId, false)) return; // already reset for panic
+ mUserPanicResets.put(mCurrentUserId, true);
+ mConfirmed = false;
+ saveSetting();
}
private void handleHide() {
if (mClingWindow != null) {
- if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation for " + mPromptPackage);
+ if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation");
mWindowManager.removeView(mClingWindow);
mClingWindow = null;
}
@@ -297,11 +297,10 @@ public class ImmersiveModeConfirmation {
}
}
- private void handleShow(String pkg) {
- mPromptPackage = pkg;
- if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation for " + pkg);
+ private void handleShow() {
+ if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation");
- mClingWindow = new ClingWindowView(mContext, confirmAction(pkg));
+ mClingWindow = new ClingWindowView(mContext, mConfirm);
// we will be hiding the nav bar, so layout as if it's already hidden
mClingWindow.setSystemUiVisibility(
@@ -313,33 +312,35 @@ public class ImmersiveModeConfirmation {
mWindowManager.addView(mClingWindow, lp);
}
- private Runnable confirmAction(final String pkg) {
- return new Runnable() {
- @Override
- public void run() {
- if (pkg != null && !mConfirmedPackages.contains(pkg)) {
- if (DEBUG) Slog.d(TAG, "Confirming immersive mode for " + pkg);
- mConfirmedPackages.add(pkg);
- saveSetting();
- }
- handleHide();
+ private final Runnable mConfirm = new Runnable() {
+ @Override
+ public void run() {
+ if (DEBUG) Slog.d(TAG, "mConfirm.run()");
+ if (!mConfirmed) {
+ mConfirmed = true;
+ saveSetting();
}
- };
- }
+ handleHide();
+ }
+ };
private final class H extends Handler {
- private static final int SHOW = 0;
- private static final int HIDE = 1;
+ private static final int SHOW = 1;
+ private static final int HIDE = 2;
+ private static final int PANIC = 3;
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case SHOW:
- handleShow((String)msg.obj);
+ handleShow();
break;
case HIDE:
handleHide();
break;
+ case PANIC:
+ handlePanic();
+ break;
}
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
index 968976b..df6fca4c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
@@ -16,8 +16,6 @@
package com.android.internal.policy.impl;
-import java.util.Map;
-
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 78020e9..b1fea03 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,8 +22,6 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.*;
-import android.view.ViewConfiguration;
-
import com.android.internal.R;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
@@ -40,6 +38,9 @@ import com.android.internal.widget.ActionBarOverlayLayout;
import com.android.internal.widget.ActionBarView;
import com.android.internal.widget.SwipeDismissLayout;
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -53,17 +54,26 @@ import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Debug;
import android.os.Handler;
+import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.transition.ChangeBounds;
+import android.transition.Explode;
+import android.transition.Fade;
+import android.transition.MoveImage;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
import android.util.AndroidRuntimeException;
+import android.util.ArrayMap;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
-import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.ActionMode;
@@ -81,11 +91,13 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.ViewStub;
+import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
@@ -100,6 +112,8 @@ import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
/**
* Android-specific Window.
@@ -112,7 +126,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private final static String TAG = "PhoneWindow";
private final static boolean SWEEP_OPEN_MENU = false;
-
/**
* Simple callback used by the context menu and its submenus. The options
* menu submenus do not use this (their behavior is more complex).
@@ -135,19 +148,22 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private ViewGroup mContentParent;
SurfaceHolder.Callback2 mTakeSurfaceCallback;
-
+
InputQueue.Callback mTakeInputQueueCallback;
-
+
private boolean mIsFloating;
private LayoutInflater mLayoutInflater;
private TextView mTitleView;
-
+
private ActionBarView mActionBar;
private ActionMenuPresenterCallback mActionMenuPresenterCallback;
private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
+ private TransitionManager mTransitionManager;
+ private Scene mContentScene;
+
// The icon resource has been explicitly set elsewhere
// and should not be overwritten with a default.
static final int FLAG_RESOURCE_SET_ICON = 1 << 0;
@@ -228,6 +244,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
};
+ private Transition mEnterTransition;
+ private Transition mExitTransition;
+ private Transition mSharedElementEnterTransition;
+ private Transition mSharedElementExitTransition;
+ private Boolean mAllowExitTransitionOverlap;
+ private Boolean mAllowEnterTransitionOverlap;
+
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
@@ -292,13 +315,38 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ public TransitionManager getTransitionManager() {
+ return mTransitionManager;
+ }
+
+ @Override
+ public void setTransitionManager(TransitionManager tm) {
+ mTransitionManager = tm;
+ }
+
+ @Override
+ public Scene getContentScene() {
+ return mContentScene;
+ }
+
+ @Override
public void setContentView(int layoutResID) {
+ // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+ // decor, when theme attributes and the like are crystalized. Do not check the feature
+ // before this happens.
if (mContentParent == null) {
installDecor();
- } else {
+ } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
- mLayoutInflater.inflate(layoutResID, mContentParent);
+
+ if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+ final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
+ getContext());
+ transitionTo(newScene);
+ } else {
+ mLayoutInflater.inflate(layoutResID, mContentParent);
+ }
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
@@ -312,12 +360,22 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
+ // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+ // decor, when theme attributes and the like are crystalized. Do not check the feature
+ // before this happens.
if (mContentParent == null) {
installDecor();
- } else {
+ } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
- mContentParent.addView(view, params);
+
+ if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+ view.setLayoutParams(params);
+ final Scene newScene = new Scene(mContentParent, view);
+ transitionTo(newScene);
+ } else {
+ mContentParent.addView(view, params);
+ }
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onContentChanged();
@@ -329,6 +387,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (mContentParent == null) {
installDecor();
}
+ if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+ // TODO Augment the scenes/transitions API to support this.
+ throw new UnsupportedOperationException(
+ "addContentView does not support content transitions");
+ }
mContentParent.addView(view, params);
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
@@ -336,6 +399,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
+ private void transitionTo(Scene scene) {
+ if (mContentScene == null) {
+ scene.enter();
+ } else {
+ mTransitionManager.transitionTo(scene);
+ }
+ mContentScene = scene;
+ }
+
@Override
public View getCurrentFocus() {
return mDecor != null ? mDecor.findFocus() : null;
@@ -345,11 +417,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
public void takeSurface(SurfaceHolder.Callback2 callback) {
mTakeSurfaceCallback = callback;
}
-
+
public void takeInputQueue(InputQueue.Callback callback) {
mTakeInputQueueCallback = callback;
}
-
+
@Override
public boolean isFloating() {
return mIsFloating;
@@ -377,6 +449,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ @Deprecated
public void setTitleColor(int textColor) {
if (mTitleView != null) {
mTitleView.setTextColor(textColor);
@@ -635,7 +708,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Otherwise, set the normal panel background
backgroundResId = st.background;
}
- st.decorView.setWindowBackground(getContext().getResources().getDrawable(
+ st.decorView.setWindowBackground(getContext().getDrawable(
backgroundResId));
ViewParent shownPanelParent = st.shownPanelView.getParent();
@@ -1220,7 +1293,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (st.resid != resId) {
st.resid = resId;
st.uri = null;
- st.local = getContext().getResources().getDrawable(resId);
+ st.local = getContext().getDrawable(resId);
updateDrawable(featureId, st, false);
}
} else {
@@ -2236,7 +2309,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (mMenuBackground == null && mFeatureId < 0
&& getAttributes().height
== WindowManager.LayoutParams.MATCH_PARENT) {
- mMenuBackground = getContext().getResources().getDrawable(
+ mMenuBackground = getContext().getDrawable(
com.android.internal.R.drawable.menu_background);
}
if (mMenuBackground != null) {
@@ -2513,6 +2586,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return super.fitSystemWindows(insets);
}
+ @Override
+ public boolean isTransitionGroup() {
+ return false;
+ }
+
private void updateStatusGuard(Rect insets) {
boolean showStatusGuard = false;
// Show the status guard when the non-overlay contextual action bar is showing
@@ -2913,6 +2991,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
a.getValue(com.android.internal.R.styleable.Window_windowFixedHeightMinor,
mFixedHeightMinor);
}
+ if (a.getBoolean(com.android.internal.R.styleable.Window_windowContentTransitions, false)) {
+ requestFeature(FEATURE_CONTENT_TRANSITIONS);
+ }
if (a.hasValue(com.android.internal.R.styleable.Window_windowOutsetBottom)) {
if (mOutsetBottom == null) mOutsetBottom = new TypedValue();
a.getValue(com.android.internal.R.styleable.Window_windowOutsetBottom, mOutsetBottom);
@@ -3072,12 +3153,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (getContainer() == null) {
Drawable drawable = mBackgroundDrawable;
if (mBackgroundResource != 0) {
- drawable = getContext().getResources().getDrawable(mBackgroundResource);
+ drawable = getContext().getDrawable(mBackgroundResource);
}
mDecor.setWindowBackground(drawable);
drawable = null;
if (mFrameResource != 0) {
- drawable = getContext().getResources().getDrawable(mFrameResource);
+ drawable = getContext().getDrawable(mFrameResource);
}
mDecor.setWindowFrame(drawable);
@@ -3212,13 +3293,63 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
});
}
}
+
+ // Only inflate or create a new TransitionManager if the caller hasn't
+ // already set a custom one.
+ if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+ if (mTransitionManager == null) {
+ final int transitionRes = getWindowStyle().getResourceId(
+ com.android.internal.R.styleable.Window_windowContentTransitionManager,
+ 0);
+ if (transitionRes != 0) {
+ final TransitionInflater inflater = TransitionInflater.from(getContext());
+ mTransitionManager = inflater.inflateTransitionManager(transitionRes,
+ mContentParent);
+ } else {
+ mTransitionManager = new TransitionManager();
+ }
+ }
+
+ mEnterTransition = getTransition(mEnterTransition,
+ com.android.internal.R.styleable.Window_windowEnterTransition);
+ mExitTransition = getTransition(mExitTransition,
+ com.android.internal.R.styleable.Window_windowExitTransition);
+ mSharedElementEnterTransition = getTransition(mSharedElementEnterTransition,
+ com.android.internal.R.styleable.Window_windowSharedElementEnterTransition);
+ mSharedElementExitTransition = getTransition(mSharedElementExitTransition,
+ com.android.internal.R.styleable.Window_windowSharedElementExitTransition);
+ if (mAllowEnterTransitionOverlap == null) {
+ mAllowEnterTransitionOverlap = getWindowStyle().getBoolean(
+ com.android.internal.R.styleable.
+ Window_windowAllowEnterTransitionOverlap, true);
+ }
+ if (mAllowExitTransitionOverlap == null) {
+ mAllowExitTransitionOverlap = getWindowStyle().getBoolean(
+ com.android.internal.R.styleable.
+ Window_windowAllowExitTransitionOverlap, true);
+ }
+ }
+ }
+ }
+
+ private Transition getTransition(Transition currentValue, int id) {
+ if (currentValue != null) {
+ return currentValue;
+ }
+ int transitionId = getWindowStyle().getResourceId(id, -1);
+ Transition transition = null;
+ if (transitionId != -1 && transitionId != com.android.internal.R.transition.no_transition) {
+ TransitionInflater inflater = TransitionInflater.from(getContext());
+ transition = inflater.inflateTransition(transitionId);
}
+ return transition;
}
private Drawable loadImageURI(Uri uri) {
try {
- return Drawable.createFromStream(
- getContext().getContentResolver().openInputStream(uri), null);
+ final Context context = getContext();
+ return Drawable.createFromStreamThemed(
+ context.getContentResolver().openInputStream(uri), null, context.getTheme());
} catch (Exception e) {
Log.w(TAG, "Unable to open content: " + uri);
}
@@ -3530,6 +3661,72 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return mVolumeControlStreamType;
}
+ private boolean isTranslucent() {
+ TypedArray a = getWindowStyle();
+ return a.getBoolean(a.getResourceId(
+ com.android.internal.R.styleable.Window_windowIsTranslucent, 0), false);
+ }
+
+ @Override
+ public void setEnterTransition(Transition enterTransition) {
+ mEnterTransition = enterTransition;
+ }
+
+ @Override
+ public void setExitTransition(Transition exitTransition) {
+ mExitTransition = exitTransition;
+ }
+
+ @Override
+ public void setSharedElementEnterTransition(Transition sharedElementEnterTransition) {
+ mSharedElementEnterTransition = sharedElementEnterTransition;
+ }
+
+ @Override
+ public void setSharedElementExitTransition(Transition sharedElementExitTransition) {
+ mSharedElementExitTransition = sharedElementExitTransition;
+ }
+
+ @Override
+ public Transition getEnterTransition() {
+ return mEnterTransition;
+ }
+
+ @Override
+ public Transition getExitTransition() {
+ return mExitTransition;
+ }
+
+ @Override
+ public Transition getSharedElementEnterTransition() {
+ return mSharedElementEnterTransition;
+ }
+
+ @Override
+ public Transition getSharedElementExitTransition() {
+ return mSharedElementExitTransition;
+ }
+
+ @Override
+ public void setAllowEnterTransitionOverlap(boolean allow) {
+ mAllowEnterTransitionOverlap = allow;
+ }
+
+ @Override
+ public boolean getAllowEnterTransitionOverlap() {
+ return (mAllowEnterTransitionOverlap == null) ? true : mAllowEnterTransitionOverlap;
+ }
+
+ @Override
+ public void setAllowExitTransitionOverlap(boolean allowExitTransitionOverlap) {
+ mAllowExitTransitionOverlap = allowExitTransitionOverlap;
+ }
+
+ @Override
+ public boolean getAllowExitTransitionOverlap() {
+ return (mAllowExitTransitionOverlap == null) ? true : mAllowExitTransitionOverlap;
+ }
+
private static final class DrawableFeatureState {
DrawableFeatureState(int _featureId) {
featureId = _featureId;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 72f1e4f..ae6aeee 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -91,10 +91,13 @@ import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
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.statusbar.IStatusBarService;
@@ -173,6 +176,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* Keyguard stuff
*/
private WindowState mKeyguardScrim;
+ private boolean mKeyguardHidden;
+ private boolean mKeyguardDrawn;
/* Table of Application Launch keys. Maps from key codes to intent categories.
*
@@ -213,6 +218,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
final Object mServiceAquireLock = new Object();
Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
SearchManager mSearchManager;
+ AccessibilityManager mAccessibilityManager;
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -223,6 +229,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Vibrator pattern for a short vibration.
long[] mKeyboardTapVibePattern;
+ // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
+ long[] mClockTickVibePattern;
+
// Vibrator pattern for haptic feedback during boot when safe mode is disabled.
long[] mSafeModeDisabledVibePattern;
@@ -243,7 +252,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int[] mNavigationBarHeightForRotation = new int[4];
int[] mNavigationBarWidthForRotation = new int[4];
- WindowState mKeyguard = null;
KeyguardServiceDelegate mKeyguardDelegate;
GlobalActions mGlobalActions;
volatile boolean mPowerKeyHandled; // accessed from input reader and handler thread
@@ -297,7 +305,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean mOrientationSensorEnabled = false;
int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
- boolean mTouchExplorationEnabled = false;
boolean mTranslucentDecorEnabled = true;
int mPointerLocationMode = 0; // guarded by mLock
@@ -306,17 +313,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowState mFocusedWindow;
IApplicationToken mFocusedApp;
- private final class PointerLocationPointerEventListener implements PointerEventListener {
- @Override
- public void onPointerEvent(MotionEvent motionEvent) {
- if (mPointerLocationView != null) {
- mPointerLocationView.addPointerEvent(motionEvent);
- }
- }
- }
-
- // Pointer location view state, only modified on the mHandler Looper.
- PointerLocationPointerEventListener mPointerLocationPointerEventListener;
PointerLocationView mPointerLocationView;
// The current size of the screen; really; extends into the overscan area of
@@ -534,9 +530,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.POLICY_CONTROL), false, this,
+ UserHandle.USER_ALL);
updateSettings();
}
@@ -912,6 +911,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.bool.config_enableTranslucentDecor);
readConfigurationDependentBehaviors();
+ mAccessibilityManager = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+
// register for dock events
IntentFilter filter = new IntentFilter();
filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
@@ -972,6 +974,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.array.config_virtualKeyVibePattern);
mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_keyboardTapVibePattern);
+ mClockTickVibePattern = getLongIntArray(mContext.getResources(),
+ com.android.internal.R.array.config_clockTickVibePattern);
mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
com.android.internal.R.array.config_safeModeDisabledVibePattern);
mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
@@ -986,7 +990,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
initializeHdmiState();
// Match current screen state.
- if (mPowerManager.isScreenOn()) {
+ if (mPowerManager.isInteractive()) {
wakingUp(null);
} else {
goingToSleep(WindowManagerPolicy.OFF_BECAUSE_OF_USER);
@@ -1110,7 +1114,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* navigation bar and touch exploration is not enabled
*/
private boolean canHideNavigationBar() {
- return mHasNavigationBar && !mTouchExplorationEnabled;
+ return mHasNavigationBar
+ && !mAccessibilityManager.isTouchExplorationEnabled();
}
@Override
@@ -1179,8 +1184,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
updateRotation = true;
}
if (mImmersiveModeConfirmation != null) {
- mImmersiveModeConfirmation.loadSetting();
+ mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
}
+ PolicyControl.reloadFromSetting(mContext);
}
if (updateRotation) {
updateRotation(true);
@@ -1191,7 +1197,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mPointerLocationView == null) {
mPointerLocationView = new PointerLocationView(mContext);
mPointerLocationView.setPrintCoords(false);
-
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT);
@@ -1211,22 +1216,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContext.getSystemService(Context.WINDOW_SERVICE);
lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
wm.addView(mPointerLocationView, lp);
-
- mPointerLocationPointerEventListener = new PointerLocationPointerEventListener();
- mWindowManagerFuncs.registerPointerEventListener(mPointerLocationPointerEventListener);
+ mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView);
}
}
private void disablePointerLocation() {
- if (mPointerLocationPointerEventListener != null) {
- mWindowManagerFuncs.unregisterPointerEventListener(
- mPointerLocationPointerEventListener);
- mPointerLocationPointerEventListener = null;
- }
-
if (mPointerLocationView != null) {
- WindowManager wm = (WindowManager)
- mContext.getSystemService(Context.WINDOW_SERVICE);
+ mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView);
+ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(mPointerLocationView);
mPointerLocationView = null;
}
@@ -1318,7 +1315,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_BOOT_PROGRESS:
case TYPE_DISPLAY_OVERLAY:
case TYPE_HIDDEN_NAV_CONSUMER:
- case TYPE_KEYGUARD:
case TYPE_KEYGUARD_SCRIM:
case TYPE_KEYGUARD_DIALOG:
case TYPE_MAGNIFICATION_OVERLAY:
@@ -1355,6 +1351,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
attrs.flags &= ~WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
break;
+ case TYPE_STATUS_BAR:
+
+ // If the Keyguard is in a hidden state (occluded by another window), we force to
+ // remove the wallpaper and keyguard flag so that any change in-flight after setting
+ // the keyguard as occluded wouldn't set these flags again.
+ // See {@link #processKeyguardSetHiddenResultLw}.
+ if (mKeyguardHidden) {
+ attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+ attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+ }
+ break;
+ }
+
+ if (attrs.type != TYPE_STATUS_BAR) {
+ // The status bar is the only window allowed to exhibit keyguard behavior.
+ attrs.privateFlags &= ~WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
}
}
@@ -1441,54 +1453,50 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_KEYGUARD_SCRIM:
// the safety window that shows behind keyguard while keyguard is starting
return 12;
- case TYPE_KEYGUARD:
- // the keyguard; nothing on top of these can take focus, since they are
- // responsible for power management when displayed.
+ case TYPE_STATUS_BAR_SUB_PANEL:
return 13;
- case TYPE_KEYGUARD_DIALOG:
+ case TYPE_STATUS_BAR:
return 14;
- case TYPE_STATUS_BAR_SUB_PANEL:
+ case TYPE_STATUS_BAR_PANEL:
return 15;
- case TYPE_STATUS_BAR:
+ case TYPE_KEYGUARD_DIALOG:
return 16;
- case TYPE_STATUS_BAR_PANEL:
- return 17;
case TYPE_VOLUME_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 18;
+ return 17;
case TYPE_SYSTEM_OVERLAY:
// the on-screen volume indicator and controller shown when the user
// changes the device volume
- return 19;
+ return 18;
case TYPE_NAVIGATION_BAR:
// the navigation bar, if available, shows atop most things
- return 20;
+ return 19;
case TYPE_NAVIGATION_BAR_PANEL:
// some panels (e.g. search) need to show on top of the navigation bar
- return 21;
+ return 20;
case TYPE_SYSTEM_ERROR:
// system-level error dialogs
- return 22;
+ return 21;
case TYPE_MAGNIFICATION_OVERLAY:
// used to highlight the magnified portion of a display
- return 23;
+ return 22;
case TYPE_DISPLAY_OVERLAY:
// used to simulate secondary display devices
- return 24;
+ return 23;
case TYPE_DRAG:
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- return 25;
+ return 24;
case TYPE_SECURE_SYSTEM_OVERLAY:
- return 26;
+ return 25;
case TYPE_BOOT_PROGRESS:
- return 27;
+ return 26;
case TYPE_POINTER:
// the (mouse) pointer layer
- return 28;
+ return 27;
case TYPE_HIDDEN_NAV_CONSUMER:
- return 29;
+ return 28;
}
Log.e(TAG, "Unknown window type: " + type);
return 2;
@@ -1558,7 +1566,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) {
- return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD;
+ return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
}
@Override
@@ -1569,7 +1577,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case TYPE_WALLPAPER:
case TYPE_DREAM:
case TYPE_UNIVERSE_BACKGROUND:
- case TYPE_KEYGUARD:
case TYPE_KEYGUARD_SCRIM:
return false;
default:
@@ -1768,12 +1775,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
android.Manifest.permission.STATUS_BAR_SERVICE,
"PhoneWindowManager");
break;
- case TYPE_KEYGUARD:
- if (mKeyguard != null) {
- return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
- }
- mKeyguard = win;
- break;
case TYPE_KEYGUARD_SCRIM:
if (mKeyguardScrim != null) {
return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
@@ -1790,9 +1791,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mStatusBar == win) {
mStatusBar = null;
mStatusBarController.setWindow(null);
- } else if (mKeyguard == win) {
- Log.v(TAG, "Removing keyguard window (Did it crash?)");
- mKeyguard = null;
mKeyguardDelegate.showScrim();
} else if (mKeyguardScrim == win) {
Log.v(TAG, "Removing keyguard scrim");
@@ -1811,12 +1809,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win
+ ": transit=" + transit);
if (win == mStatusBar) {
+ boolean isKeyguard = (win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
if (transit == TRANSIT_EXIT
|| transit == TRANSIT_HIDE) {
- return R.anim.dock_top_exit;
+ return isKeyguard ? -1 : R.anim.dock_top_exit;
} else if (transit == TRANSIT_ENTER
|| transit == TRANSIT_SHOW) {
- return R.anim.dock_top_enter;
+ return isKeyguard ? -1 : R.anim.dock_top_enter;
}
} else if (win == mNavigationBar) {
// This can be on either the bottom or the right.
@@ -2037,9 +2036,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
- if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
- || type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
- || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
+ if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
+ || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
+ || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
// the "app" is keyguard, so give it the key
return 0;
}
@@ -2468,7 +2467,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* given the situation with the keyguard.
*/
void launchHomeFromHotKey() {
- if (mKeyguardDelegate != null && mKeyguardDelegate.isShowingAndNotHidden()) {
+ if (mKeyguardDelegate != null && mKeyguardDelegate.isShowingAndNotOccluded()) {
// don't launch home if keyguard showing
} else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
@@ -2588,8 +2587,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
- final int fl = attrs.flags;
- final int systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+ final int fl = PolicyControl.getWindowFlags(null, attrs);
+ final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs);
+ final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility);
if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
== (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
@@ -2761,7 +2761,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// We currently want to hide the navigation UI.
mNavigationBarController.setBarShowingLw(false);
}
- if (navVisible && !navTranslucent && !mNavigationBar.isAnimatingLw()
+ if (navVisible && !navTranslucent && !navAllowedHidden
+ && !mNavigationBar.isAnimatingLw()
&& !mNavigationBarController.wasRecentlyTranslucent()) {
// If the opaque nav bar is currently requested to be visible,
// and not in the process of animating on or off, then
@@ -2970,9 +2971,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
offsetInputMethodWindowLw(mLastInputMethodWindow);
}
- final int fl = attrs.flags;
+ final int fl = PolicyControl.getWindowFlags(win, attrs);
final int sim = attrs.softInputMode;
- final int sysUiFl = win.getSystemUiVisibility();
+ final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null);
final Rect pf = mTmpParentFrame;
final Rect df = mTmpDisplayFrame;
@@ -3088,9 +3089,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
+ mOverscanScreenHeight;
} else if (canHideNavigationBar()
&& (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
- && (attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD || (
- attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
- && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
+ && attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
+ && attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
// Asking for layout as if the nav bar is hidden, lets the
// application extend into the unrestricted overscan screen area. We
// only do this for application windows to ensure no window that
@@ -3391,21 +3391,25 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowManager.LayoutParams attrs) {
if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
+ win.isVisibleOrBehindKeyguardLw());
+ final int fl = PolicyControl.getWindowFlags(win, attrs);
if (mTopFullscreenOpaqueWindowState == null
&& win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
mForcingShowNavBar = true;
mForcingShowNavBarLayer = win.getSurfaceLayer();
}
+ if (attrs.type == TYPE_STATUS_BAR && (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+ mForceStatusBarFromKeyguard = true;
+ }
if (mTopFullscreenOpaqueWindowState == null &&
win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
- if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
- if (attrs.type == TYPE_KEYGUARD) {
+ if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
+ if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
mForceStatusBarFromKeyguard = true;
} else {
mForceStatusBar = true;
}
}
- if (attrs.type == TYPE_KEYGUARD) {
+ if ((attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
mShowingLockscreen = true;
}
boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
@@ -3420,8 +3424,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- final boolean showWhenLocked = (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
- final boolean dismissKeyguard = (attrs.flags & FLAG_DISMISS_KEYGUARD) != 0;
+ final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
+ final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
if (appWindow) {
if (showWhenLocked || (dismissKeyguard && !isKeyguardSecure())) {
mAppsToBeHidden.remove(win.getAppToken());
@@ -3441,14 +3445,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mForceStatusBarFromKeyguard = false;
}
if (dismissKeyguard && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Setting mDismissKeyguard true by win " + win);
mDismissKeyguard = mWinDismissingKeyguard == win ?
DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
mWinDismissingKeyguard = win;
mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
}
}
- if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
+ if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
mAllowLockscreenWhenOn = true;
}
}
@@ -3491,13 +3496,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mLastSystemUiFlags, mLastSystemUiFlags);
}
} else if (mTopFullscreenOpaqueWindowState != null) {
+ final int fl = PolicyControl.getWindowFlags(null, lp);
if (localLOGV) {
Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
+ " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
- + " lp.flags=0x" + Integer.toHexString(lp.flags));
+ + " lp.flags=0x" + Integer.toHexString(fl));
}
- topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
+ topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
|| (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
// The subtle difference between the window for mTopFullscreenOpaqueWindowState
// and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
@@ -3533,11 +3539,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Hide the key guard if a visible window explicitly specifies that it wants to be
// displayed when the screen is locked.
- if (mKeyguard != null) {
+ if (mKeyguardDelegate != null && mStatusBar != null) {
if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+ mHideLockScreen);
if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
- if (mKeyguard.hideLw(true)) {
+ mKeyguardHidden = true;
+ if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(true))) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
@@ -3551,24 +3558,22 @@ public class PhoneWindowManager implements WindowManagerPolicy {
});
}
} else if (mHideLockScreen) {
- if (mKeyguard.hideLw(true)) {
+ mKeyguardHidden = true;
+ if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(true))) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
}
- if (!mShowingDream) {
- mKeyguardDelegate.setHidden(true);
- }
} else if (mDismissKeyguard != DISMISS_KEYGUARD_NONE) {
// This is the case of keyguard isSecure() and not mHideLockScreen.
if (mDismissKeyguard == DISMISS_KEYGUARD_START) {
// Only launch the next keyguard unlock window once per window.
- if (mKeyguard.showLw(true)) {
+ mKeyguardHidden = false;
+ if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(false))) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
}
- mKeyguardDelegate.setHidden(false);
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -3578,12 +3583,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
} else {
mWinDismissingKeyguard = null;
- if (mKeyguard.showLw(true)) {
+ mKeyguardHidden = false;
+ if (processKeyguardSetHiddenResultLw(mKeyguardDelegate.setOccluded(false))) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
| FINISH_LAYOUT_REDO_WALLPAPER;
}
- mKeyguardDelegate.setHidden(false);
}
}
@@ -3598,9 +3603,39 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return changes;
}
+ /**
+ * 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.
+ *
+ * @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) {
+ 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) {
+ mStatusBar.getAttrs().privateFlags &= ~PRIVATE_FLAG_KEYGUARD;
+ mStatusBar.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isStatusBarKeyguard() {
+ return mStatusBar != null
+ && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
+ }
+
public boolean allowAppAnimationsLw() {
- if (mKeyguard != null && mKeyguard.isVisibleLw() && !mKeyguard.isAnimatingLw()
- || mShowingDream) {
+ if (isStatusBarKeyguard() || mShowingDream) {
// If keyguard or dreams is currently visible, no reason to animate behind it.
return false;
}
@@ -3822,15 +3857,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// when the keyguard is hidden by another activity.
final boolean keyguardActive = (mKeyguardDelegate == null ? false :
(interactive ?
- mKeyguardDelegate.isShowingAndNotHidden() :
+ mKeyguardDelegate.isShowingAndNotOccluded() :
mKeyguardDelegate.isShowing()));
- if (keyCode == KeyEvent.KEYCODE_POWER
- || keyCode == KeyEvent.KEYCODE_SLEEP
- || keyCode == KeyEvent.KEYCODE_WAKEUP) {
- policyFlags |= WindowManagerPolicy.FLAG_WAKE;
- }
-
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
+ " interactive=" + interactive + " keyguardActive=" + keyguardActive
@@ -3844,8 +3873,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Basic policy based on interactive state.
int result;
- boolean isWakeKey = (policyFlags & (WindowManagerPolicy.FLAG_WAKE
- | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0;
+ boolean isWakeKey = (policyFlags & WindowManagerPolicy.FLAG_WAKE) != 0
+ || event.isWakeKey();
if (interactive || (isInjected && !isWakeKey)) {
// When the screen is on or if the key is injected pass the key to the application.
result = ACTION_PASS_TO_USER;
@@ -3975,8 +4004,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_POWER: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
- mImmersiveModeConfirmation.onPowerKeyDown(interactive, event.getDownTime(),
- isImmersiveMode(mLastSystemUiFlags));
+ boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(interactive,
+ event.getDownTime(), isImmersiveMode(mLastSystemUiFlags));
+ if (panic) {
+ mHandler.post(mRequestTransientNav);
+ }
if (interactive && !mPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
mPowerKeyTriggered = true;
@@ -3994,7 +4026,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
telephonyService.silenceRinger();
} else if ((mIncallPowerBehavior
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
- && telephonyService.isOffhook() && isScreenOn) {
+ && telephonyService.isOffhook() && interactive) {
// Otherwise, if "Power button ends call" is enabled,
// the Power button will hang up any current active call.
hungUp = telephonyService.endCall();
@@ -4257,6 +4289,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
+ private final Runnable mRequestTransientNav = new Runnable() {
+ @Override
+ public void run() {
+ requestTransientBars(mNavigationBar);
+ }
+ };
+
private void requestTransientBars(WindowState swipeTarget) {
synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
boolean sb = mStatusBarController.checkShowTransientBarLw();
@@ -4311,21 +4350,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private void waitForKeyguard(final ScreenOnListener screenOnListener) {
if (mKeyguardDelegate != null) {
- if (screenOnListener != null) {
- mKeyguardDelegate.onScreenTurnedOn(new KeyguardServiceDelegate.ShowListener() {
- @Override
- public void onShown(IBinder windowToken) {
- waitForKeyguardWindowDrawn(windowToken, screenOnListener);
- }
- });
- return;
- } else {
- mKeyguardDelegate.onScreenTurnedOn(null);
- }
+ mKeyguardDelegate.onScreenTurnedOn(new KeyguardServiceDelegate.ShowListener() {
+ @Override
+ public void onShown(IBinder windowToken) {
+ waitForKeyguardWindowDrawn(windowToken, screenOnListener);
+ }
+ });
} else {
Slog.i(TAG, "No keyguard interface!");
+ finishScreenTurningOn(screenOnListener);
}
- finishScreenTurningOn(screenOnListener);
}
private void waitForKeyguardWindowDrawn(IBinder windowToken,
@@ -4338,6 +4372,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void sendResult(Bundle data) {
Slog.i(TAG, "Lock screen displayed!");
finishScreenTurningOn(screenOnListener);
+ setKeyguardDrawn();
}
})) {
return;
@@ -4351,6 +4386,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
finishScreenTurningOn(screenOnListener);
+ setKeyguardDrawn();
}
private void finishScreenTurningOn(ScreenOnListener screenOnListener) {
@@ -4394,7 +4430,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean keyguardIsShowingTq() {
if (mKeyguardDelegate == null) return false;
- return mKeyguardDelegate.isShowingAndNotHidden();
+ return mKeyguardDelegate.isShowingAndNotOccluded();
}
@@ -4431,6 +4467,23 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
+ private void setKeyguardDrawn() {
+ synchronized (mLock) {
+ mKeyguardDrawn = true;
+ }
+ try {
+ mWindowManager.enableScreenIfNeeded();
+ } catch (RemoteException unhandled) {
+ }
+ }
+
+ @Override
+ public boolean isKeyguardDrawnLw() {
+ synchronized (mLock) {
+ return mKeyguardDrawn;
+ }
+ }
+
void sendCloseSystemWindows() {
sendCloseSystemWindows(mContext, null);
}
@@ -4714,6 +4767,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
mSystemBooted = true;
}
+ waitForKeyguard(null);
}
ProgressDialog mBootMsgDialog = null;
@@ -5042,7 +5096,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
final boolean hapticsDisabled = Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.HAPTIC_FEEDBACK_ENABLED, 0, UserHandle.USER_CURRENT) == 0;
- if (!always && (hapticsDisabled || mKeyguardDelegate.isShowingAndNotHidden())) {
+ if (!always && (hapticsDisabled || mKeyguardDelegate.isShowingAndNotOccluded())) {
return false;
}
long[] pattern = null;
@@ -5056,6 +5110,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case HapticFeedbackConstants.KEYBOARD_TAP:
pattern = mKeyboardTapVibePattern;
break;
+ case HapticFeedbackConstants.CLOCK_TICK:
+ pattern = mClockTickVibePattern;
+ break;
case HapticFeedbackConstants.SAFE_MODE_DISABLED:
pattern = mSafeModeDisabledVibePattern;
break;
@@ -5076,10 +5133,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (pattern.length == 1) {
// One-shot vibration
- mVibrator.vibrate(owningUid, owningPackage, pattern[0]);
+ mVibrator.vibrate(owningUid, owningPackage, pattern[0], AudioManager.STREAM_SYSTEM);
} else {
// Pattern vibration
- mVibrator.vibrate(owningUid, owningPackage, pattern, -1);
+ mVibrator.vibrate(owningUid, owningPackage, pattern, -1, AudioManager.STREAM_SYSTEM);
}
return true;
}
@@ -5090,8 +5147,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public void keepScreenOnStoppedLw() {
- if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotHidden()) {
- long curTime = SystemClock.uptimeMillis();
+ if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotOccluded()) {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
}
@@ -5103,7 +5159,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (win == null) {
return 0;
}
- if (win.getAttrs().type == TYPE_KEYGUARD && mHideLockScreen == true) {
+ if ((win.getAttrs().privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 && mHideLockScreen == true) {
// We are updating at a point where the keyguard has gotten
// focus, but we were last in a state where the top window is
// hiding it. This is probably because the keyguard as been
@@ -5113,11 +5169,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return 0;
}
- int tmpVisibility = win.getSystemUiVisibility()
+ int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
& ~mResettingSystemUiFlags
& ~mForceClearedSystemUiFlags;
if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) {
- tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
+ tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);
}
final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
final int diff = visibility ^ mLastSystemUiFlags;
@@ -5149,8 +5205,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private int updateSystemBarsLw(WindowState win, int oldVis, int vis) {
// apply translucent bar vis flags
- WindowState transWin = mKeyguard != null && mKeyguard.isVisibleLw() && !mHideLockScreen
- ? mKeyguard
+ WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen
+ ? mStatusBar
: mTopFullscreenOpaqueWindowState;
vis = mStatusBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
vis = mNavigationBarController.applyTranslucentFlagLw(transWin, vis, oldVis);
@@ -5161,9 +5217,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int flags = View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_IMMERSIVE
- | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
- | View.STATUS_BAR_TRANSLUCENT
- | View.NAVIGATION_BAR_TRANSLUCENT;
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
+ if (!isStatusBarKeyguard() || mHideLockScreen) {
+ flags |= View.STATUS_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSLUCENT;
+ }
vis = (vis & ~flags) | (oldVis & flags);
}
@@ -5176,7 +5233,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
(vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
boolean hideStatusBarWM =
mTopFullscreenOpaqueWindowState != null &&
- (mTopFullscreenOpaqueWindowState.getAttrs().flags
+ (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null)
& WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
boolean hideStatusBarSysui =
(vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
@@ -5240,7 +5297,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* R.boolean.config_enableTranslucentDecor is false.
*/
private boolean areTranslucentBarsAllowed() {
- return mTranslucentDecorEnabled && !mTouchExplorationEnabled;
+ return mTranslucentDecorEnabled
+ && !mAccessibilityManager.isTouchExplorationEnabled();
}
// Use this instead of checking config_showNavigationBar so that it can be consistently
@@ -5257,6 +5315,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
+ public int getInputMethodWindowVisibleHeightLw() {
+ return mDockBottom - mCurBottom;
+ }
+
+ @Override
public void setCurrentUserLw(int newUserId) {
mCurrentUserId = newUserId;
if (mKeyguardDelegate != null) {
@@ -5286,11 +5349,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
- public void setTouchExplorationEnabled(boolean enabled) {
- mTouchExplorationEnabled = enabled;
- }
-
- @Override
public boolean isTopLevelWindow(int windowType) {
if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
&& windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
@@ -5407,15 +5465,13 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (mStatusBar != null) {
pw.print(prefix); pw.print("mStatusBar=");
pw.println(mStatusBar);
+ pw.print(prefix); pw.print("isStatusBarKeyguard=");
+ pw.print(isStatusBarKeyguard());
}
if (mNavigationBar != null) {
pw.print(prefix); pw.print("mNavigationBar=");
pw.println(mNavigationBar);
}
- if (mKeyguard != null) {
- pw.print(prefix); pw.print("mKeyguard=");
- pw.println(mKeyguard);
- }
if (mFocusedWindow != null) {
pw.print(prefix); pw.print("mFocusedWindow=");
pw.println(mFocusedWindow);
@@ -5460,5 +5516,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation);
mStatusBarController.dump(pw, prefix);
mNavigationBarController.dump(pw, prefix);
+ PolicyControl.dump(prefix, pw);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PolicyControl.java b/policy/src/com/android/internal/policy/impl/PolicyControl.java
new file mode 100644
index 0000000..ffdb520
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/PolicyControl.java
@@ -0,0 +1,256 @@
+/*
+ * 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.impl;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerPolicy.WindowState;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Runtime adjustments applied to the global window policy.
+ *
+ * This includes forcing immersive mode behavior for one or both system bars (based on a package
+ * list) and permanently disabling immersive mode confirmations for specific packages.
+ *
+ * Control by setting {@link Settings.Global.POLICY_CONTROL} to one or more name-value pairs.
+ * e.g.
+ * to force immersive mode everywhere:
+ * "immersive.full=*"
+ * to force transient status for all apps except a specific package:
+ * "immersive.status=apps,-com.package"
+ * to disable the immersive mode confirmations for specific packages:
+ * "immersive.preconfirms=com.package.one,com.package.two"
+ *
+ * Separate multiple name-value pairs with ':'
+ * e.g. "immersive.status=apps:immersive.preconfirms=*"
+ */
+public class PolicyControl {
+ private static String TAG = "PolicyControl";
+ private static boolean DEBUG = false;
+
+ private static final String NAME_IMMERSIVE_FULL = "immersive.full";
+ private static final String NAME_IMMERSIVE_STATUS = "immersive.status";
+ private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation";
+ private static final String NAME_IMMERSIVE_PRECONFIRMATIONS = "immersive.preconfirms";
+
+ private static String sSettingValue;
+ private static Filter sImmersivePreconfirmationsFilter;
+ private static Filter sImmersiveStatusFilter;
+ private static Filter sImmersiveNavigationFilter;
+
+ public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
+ attrs = attrs != null ? attrs : win.getAttrs();
+ int vis = win != null ? win.getSystemUiVisibility() : attrs.systemUiVisibility;
+ if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+ vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.STATUS_BAR_TRANSLUCENT);
+ }
+ if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
+ vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.NAVIGATION_BAR_TRANSLUCENT);
+ }
+ return vis;
+ }
+
+ public static int getWindowFlags(WindowState win, LayoutParams attrs) {
+ attrs = attrs != null ? attrs : win.getAttrs();
+ int flags = attrs.flags;
+ if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+ flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
+ flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
+ | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+ }
+ if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
+ flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+ }
+ return flags;
+ }
+
+ public static int adjustClearableFlags(WindowState win, int clearableFlags) {
+ final LayoutParams attrs = win != null ? win.getAttrs() : null;
+ if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+ clearableFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
+ }
+ return clearableFlags;
+ }
+
+ public static boolean disableImmersiveConfirmation(String pkg) {
+ return sImmersivePreconfirmationsFilter != null
+ && sImmersivePreconfirmationsFilter.matches(pkg);
+ }
+
+ public static void reloadFromSetting(Context context) {
+ if (DEBUG) Slog.d(TAG, "reloadFromSetting()");
+ String value = null;
+ try {
+ value = Settings.Global.getStringForUser(context.getContentResolver(),
+ Settings.Global.POLICY_CONTROL,
+ UserHandle.USER_CURRENT);
+ if (sSettingValue != null && sSettingValue.equals(value)) return;
+ setFilters(value);
+ sSettingValue = value;
+ } catch (Throwable t) {
+ Slog.w(TAG, "Error loading policy control, value=" + value, t);
+ }
+ }
+
+ public static void dump(String prefix, PrintWriter pw) {
+ dump("sImmersiveStatusFilter", sImmersiveStatusFilter, prefix, pw);
+ dump("sImmersiveNavigationFilter", sImmersiveNavigationFilter, prefix, pw);
+ dump("sImmersivePreconfirmationsFilter", sImmersivePreconfirmationsFilter, prefix, pw);
+ }
+
+ private static void dump(String name, Filter filter, String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("PolicyControl."); pw.print(name); pw.print('=');
+ if (filter == null) {
+ pw.println("null");
+ } else {
+ filter.dump(pw); pw.println();
+ }
+ }
+
+ private static void setFilters(String value) {
+ if (DEBUG) Slog.d(TAG, "setFilters: " + value);
+ sImmersiveStatusFilter = null;
+ sImmersiveNavigationFilter = null;
+ sImmersivePreconfirmationsFilter = null;
+ if (value != null) {
+ String[] nvps = value.split(":");
+ for (String nvp : nvps) {
+ int i = nvp.indexOf('=');
+ if (i == -1) continue;
+ String n = nvp.substring(0, i);
+ String v = nvp.substring(i + 1);
+ if (n.equals(NAME_IMMERSIVE_FULL)) {
+ Filter f = Filter.parse(v);
+ sImmersiveStatusFilter = sImmersiveNavigationFilter = f;
+ if (sImmersivePreconfirmationsFilter == null) {
+ sImmersivePreconfirmationsFilter = f;
+ }
+ } else if (n.equals(NAME_IMMERSIVE_STATUS)) {
+ Filter f = Filter.parse(v);
+ sImmersiveStatusFilter = f;
+ } else if (n.equals(NAME_IMMERSIVE_NAVIGATION)) {
+ Filter f = Filter.parse(v);
+ sImmersiveNavigationFilter = f;
+ if (sImmersivePreconfirmationsFilter == null) {
+ sImmersivePreconfirmationsFilter = f;
+ }
+ } else if (n.equals(NAME_IMMERSIVE_PRECONFIRMATIONS)) {
+ Filter f = Filter.parse(v);
+ sImmersivePreconfirmationsFilter = f;
+ }
+ }
+ }
+ if (DEBUG) {
+ Slog.d(TAG, "immersiveStatusFilter: " + sImmersiveStatusFilter);
+ Slog.d(TAG, "immersiveNavigationFilter: " + sImmersiveNavigationFilter);
+ Slog.d(TAG, "immersivePreconfirmationsFilter: " + sImmersivePreconfirmationsFilter);
+ }
+ }
+
+ private static class Filter {
+ private static final String ALL = "*";
+ private static final String APPS = "apps";
+
+ private final ArraySet<String> mWhitelist;
+ private final ArraySet<String> mBlacklist;
+
+ private Filter(ArraySet<String> whitelist, ArraySet<String> blacklist) {
+ mWhitelist = whitelist;
+ mBlacklist = blacklist;
+ }
+
+ boolean matches(LayoutParams attrs) {
+ if (attrs == null) return false;
+ boolean isApp = attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
+ && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+ if (isApp && mBlacklist.contains(APPS)) return false;
+ if (onBlacklist(attrs.packageName)) return false;
+ if (isApp && mWhitelist.contains(APPS)) return true;
+ return onWhitelist(attrs.packageName);
+ }
+
+ boolean matches(String packageName) {
+ return !onBlacklist(packageName) && onWhitelist(packageName);
+ }
+
+ private boolean onBlacklist(String packageName) {
+ return mBlacklist.contains(packageName) || mBlacklist.contains(ALL);
+ }
+
+ private boolean onWhitelist(String packageName) {
+ return mWhitelist.contains(ALL) || mWhitelist.contains(packageName);
+ }
+
+ void dump(PrintWriter pw) {
+ pw.print("Filter[");
+ dump("whitelist", mWhitelist, pw); pw.print(',');
+ dump("blacklist", mBlacklist, pw); pw.print(']');
+ }
+
+ private void dump(String name, ArraySet<String> set, PrintWriter pw) {
+ pw.print(name); pw.print("=(");
+ final int n = set.size();
+ for (int i = 0; i < n; i++) {
+ if (i > 0) pw.print(',');
+ pw.print(set.valueAt(i));
+ }
+ pw.print(')');
+ }
+
+ @Override
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ dump(new PrintWriter(sw, true));
+ return sw.toString();
+ }
+
+ // value = comma-delimited list of tokens, where token = (package name|apps|*)
+ // e.g. "com.package1", or "apps, com.android.keyguard" or "*"
+ static Filter parse(String value) {
+ if (value == null) return null;
+ ArraySet<String> whitelist = new ArraySet<String>();
+ ArraySet<String> blacklist = new ArraySet<String>();
+ for (String token : value.split(",")) {
+ token = token.trim();
+ if (token.startsWith("-") && token.length() > 1) {
+ token = token.substring(1);
+ blacklist.add(token);
+ } else {
+ whitelist.add(token);
+ }
+ }
+ return new Filter(whitelist, blacklist);
+ }
+ }
+}
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
index 8d87728..3490bd4 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
@@ -21,7 +21,6 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
diff --git a/policy/src/com/android/internal/policy/impl/ShortcutManager.java b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
index 75a1b01..bb898f7 100644
--- a/policy/src/com/android/internal/policy/impl/ShortcutManager.java
+++ b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
@@ -25,7 +25,6 @@ import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
import java.net.URISyntaxException;
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 e5af716..966924b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -12,7 +12,6 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
-import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -30,8 +29,8 @@ import com.android.internal.widget.LockPatternUtils;
*/
public class KeyguardServiceDelegate {
// TODO: propagate changes to these to {@link KeyguardTouchDelegate}
- public static final String KEYGUARD_PACKAGE = "com.android.keyguard";
- public static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
+ 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;
@@ -45,13 +44,13 @@ public class KeyguardServiceDelegate {
// the event something checks before the service is actually started.
// KeyguardService itself should default to this state until the real state is known.
showing = true;
- showingAndNotHidden = true;
+ showingAndNotOccluded = true;
secure = true;
}
boolean showing;
- boolean showingAndNotHidden;
+ boolean showingAndNotOccluded;
boolean inputRestricted;
- boolean hidden;
+ boolean occluded;
boolean secure;
boolean dreaming;
boolean systemIsReady;
@@ -110,7 +109,7 @@ public class KeyguardServiceDelegate {
Context.BIND_AUTO_CREATE, UserHandle.OWNER)) {
if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS);
mKeyguardState.showing = false;
- mKeyguardState.showingAndNotHidden = false;
+ mKeyguardState.showingAndNotOccluded = false;
mKeyguardState.secure = false;
} else {
if (DEBUG) Log.v(TAG, "*** Keyguard started");
@@ -149,11 +148,11 @@ public class KeyguardServiceDelegate {
return mKeyguardState.showing;
}
- public boolean isShowingAndNotHidden() {
+ public boolean isShowingAndNotOccluded() {
if (mKeyguardService != null) {
- mKeyguardState.showingAndNotHidden = mKeyguardService.isShowingAndNotHidden();
+ mKeyguardState.showingAndNotOccluded = mKeyguardService.isShowingAndNotOccluded();
}
- return mKeyguardState.showingAndNotHidden;
+ return mKeyguardState.showingAndNotOccluded;
}
public boolean isInputRestricted() {
@@ -175,11 +174,13 @@ public class KeyguardServiceDelegate {
}
}
- public void setHidden(boolean isHidden) {
+ public int setOccluded(boolean isOccluded) {
+ int result = 0;
if (mKeyguardService != null) {
- mKeyguardService.setHidden(isHidden);
+ result = mKeyguardService.setOccluded(isOccluded);
}
- mKeyguardState.hidden = isHidden;
+ mKeyguardState.occluded = isOccluded;
+ return result;
}
public void dismiss() {
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 9fb2a50..7cb48fa 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceWrapper.java
@@ -22,6 +22,7 @@ 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;
@@ -57,9 +58,9 @@ public class KeyguardServiceWrapper implements IKeyguardService {
return false; // TODO cache state
}
- public boolean isShowingAndNotHidden() {
+ public boolean isShowingAndNotOccluded() {
try {
- return mService.isShowingAndNotHidden();
+ return mService.isShowingAndNotOccluded();
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
}
@@ -100,11 +101,12 @@ public class KeyguardServiceWrapper implements IKeyguardService {
}
}
- public void setHidden(boolean isHidden) {
+ public int setOccluded(boolean isOccluded) {
try {
- mService.setHidden(isHidden);
+ return mService.setOccluded(isOccluded);
} catch (RemoteException e) {
Slog.w(TAG , "Remote Exception", e);
+ return IKeyguardServiceConstants.KEYGUARD_SERVICE_SET_OCCLUDED_RESULT_NONE;
}
}