summaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
Diffstat (limited to 'policy')
-rw-r--r--policy/src/com/android/internal/policy/impl/BarController.java12
-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.java126
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java622
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java541
-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/RecentApplicationsDialog.java2
-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
13 files changed, 1129 insertions, 536 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..bfbd60d 100644
--- a/policy/src/com/android/internal/policy/impl/BarController.java
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -108,13 +108,20 @@ 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) {
+ int fl = PolicyControl.getWindowFlags(win, null);
+ if ((fl & mTranslucentWmFlag) != 0) {
vis |= mTranslucentFlag;
} else {
vis &= ~mTranslucentFlag;
}
+ if ((fl & WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
+ vis |= View.SYSTEM_UI_TRANSPARENT;
+ } else {
+ vis &= ~View.SYSTEM_UI_TRANSPARENT;
+ }
} else {
vis = (vis & ~mTranslucentFlag) | (oldVis & mTranslucentFlag);
+ vis = (vis & ~View.SYSTEM_UI_TRANSPARENT) | (oldVis & View.SYSTEM_UI_TRANSPARENT);
}
}
return vis;
@@ -230,7 +237,8 @@ public class BarController {
vis |= mTransientFlag; // ignore clear requests until transition completes
vis &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE; // never show transient bars in low profile
}
- if ((vis & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0) {
+ if ((vis & mTranslucentFlag) != 0 || (oldVis & mTranslucentFlag) != 0 ||
+ ((vis | oldVis) & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0) {
mLastTranslucent = SystemClock.uptimeMillis();
}
return vis;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 371fa0f..673ce0b 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -423,36 +423,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);
+ }
}
}
}
@@ -651,7 +653,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);
@@ -741,7 +743,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..a4c2ddd 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,85 @@ 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;
- }
+ public void immersiveModeChanged(String pkg, boolean isImmersiveMode,
+ boolean userSetupComplete) {
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) && userSetupComplete) {
+ 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 +298,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 +313,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 c670b5c..2fea785 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;
@@ -38,8 +36,10 @@ import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarOverlayLayout;
import com.android.internal.widget.ActionBarView;
+import com.android.internal.widget.DecorContentParent;
import com.android.internal.widget.SwipeDismissLayout;
+import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -48,23 +48,26 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
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.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
import android.util.AndroidRuntimeException;
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;
@@ -82,6 +85,7 @@ 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;
@@ -113,7 +117,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).
@@ -136,19 +139,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 DecorContentParent mDecorContentParent;
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;
@@ -197,6 +203,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private int mFrameResource = 0;
private int mTextColor = 0;
+ private int mStatusBarColor = 0;
+ private int mNavigationBarColor = 0;
+ private boolean mForcedStatusBarColor = false;
+ private boolean mForcedNavigationBarColor = false;
private CharSequence mTitle = null;
@@ -229,6 +239,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"));
@@ -298,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();
@@ -318,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();
@@ -335,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()) {
@@ -342,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;
@@ -351,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;
@@ -376,13 +442,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
public void setTitle(CharSequence title) {
if (mTitleView != null) {
mTitleView.setText(title);
- } else if (mActionBar != null) {
- mActionBar.setWindowTitle(title);
+ } else if (mDecorContentParent != null) {
+ mDecorContentParent.setWindowTitle(title);
}
mTitle = title;
}
@Override
+ @Deprecated
public void setTitleColor(int textColor) {
if (mTitleView != null) {
mTitleView.setTextColor(textColor);
@@ -423,10 +490,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final boolean isActionBarMenu =
(st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR);
- if (isActionBarMenu && mActionBar != null) {
+ if (isActionBarMenu && mDecorContentParent != null) {
// Enforce ordering guarantees around events so that the action bar never
// dispatches menu-related events before the panel is prepared.
- mActionBar.setMenuPrepared();
+ mDecorContentParent.setMenuPrepared();
}
if (st.createdPanelView == null) {
@@ -438,11 +505,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- if (isActionBarMenu && mActionBar != null) {
+ if (isActionBarMenu && mDecorContentParent != null) {
if (mActionMenuPresenterCallback == null) {
mActionMenuPresenterCallback = new ActionMenuPresenterCallback();
}
- mActionBar.setMenu(st.menu, mActionMenuPresenterCallback);
+ mDecorContentParent.setMenu(st.menu, mActionMenuPresenterCallback);
}
// Call callback, and return if it doesn't want to display menu.
@@ -454,9 +521,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Ditch the menu created above
st.setMenu(null);
- if (isActionBarMenu && mActionBar != null) {
+ if (isActionBarMenu && mDecorContentParent != null) {
// Don't show it in the action bar either
- mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
}
return false;
@@ -479,10 +546,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
- if (isActionBarMenu && mActionBar != null) {
+ if (isActionBarMenu && mDecorContentParent != null) {
// The app didn't want to show the menu for now but it still exists.
// Clear it out of the action bar.
- mActionBar.setMenu(null, mActionMenuPresenterCallback);
+ mDecorContentParent.setMenu(null, mActionMenuPresenterCallback);
}
st.menu.startDispatchingItemsChanged();
return false;
@@ -507,7 +574,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public void onConfigurationChanged(Configuration newConfig) {
// Action bars handle their own menu state
- if (mActionBar == null) {
+ if (mDecorContentParent == null) {
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
if ((st != null) && (st.menu != null)) {
if (st.isOpen) {
@@ -559,12 +626,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public final void openPanel(int featureId, KeyEvent event) {
- if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
- mActionBar.isOverflowReserved() &&
+ if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
+ mDecorContentParent.canShowOverflowMenu() &&
!ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
- if (mActionBar.getVisibility() == View.VISIBLE) {
- mActionBar.showOverflowMenu();
- }
+ mDecorContentParent.showOverflowMenu();
} else {
openPanel(getPanelState(featureId, true), event);
}
@@ -641,7 +706,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();
@@ -693,10 +758,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
@Override
public final void closePanel(int featureId) {
- if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
- mActionBar.isOverflowReserved() &&
+ if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
+ mDecorContentParent.canShowOverflowMenu() &&
!ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
- mActionBar.hideOverflowMenu();
+ mDecorContentParent.hideOverflowMenu();
} else if (featureId == FEATURE_CONTEXT_MENU) {
closeContextMenu();
} else {
@@ -718,7 +783,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
public final void closePanel(PanelFeatureState st, boolean doCallback) {
// System.out.println("Close panel: isOpen=" + st.isOpen);
if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
- mActionBar != null && mActionBar.isOverflowMenuShowing()) {
+ mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
checkCloseActionMenu(st.menu);
return;
}
@@ -764,7 +829,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
mClosingActionMenu = true;
- mActionBar.dismissPopupMenus();
+ mDecorContentParent.dismissPopups();
Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
cb.onPanelClosed(FEATURE_ACTION_BAR, menu);
@@ -810,7 +875,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Prepare the options panel if we have an action bar
if ((featureId == FEATURE_ACTION_BAR || featureId == FEATURE_OPTIONS_PANEL)
- && mActionBar != null) {
+ && mDecorContentParent != null) {
st = getPanelState(Window.FEATURE_OPTIONS_PANEL, false);
if (st != null) {
st.isPrepared = false;
@@ -857,17 +922,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean playSoundEffect = false;
final PanelFeatureState st = getPanelState(featureId, true);
- if (featureId == FEATURE_OPTIONS_PANEL && mActionBar != null &&
- mActionBar.isOverflowReserved() &&
+ if (featureId == FEATURE_OPTIONS_PANEL && mDecorContentParent != null &&
+ mDecorContentParent.canShowOverflowMenu() &&
!ViewConfiguration.get(getContext()).hasPermanentMenuKey()) {
- if (mActionBar.getVisibility() == View.VISIBLE) {
- if (!mActionBar.isOverflowMenuShowing()) {
- if (!isDestroyed() && preparePanel(st, event)) {
- playSoundEffect = mActionBar.showOverflowMenu();
- }
- } else {
- playSoundEffect = mActionBar.hideOverflowMenu();
+ if (!mDecorContentParent.isOverflowMenuShowing()) {
+ if (!isDestroyed() && preparePanel(st, event)) {
+ playSoundEffect = mDecorContentParent.showOverflowMenu();
}
+ } else {
+ playSoundEffect = mDecorContentParent.hideOverflowMenu();
}
} else {
if (st.isOpen || st.isHandled) {
@@ -980,7 +1043,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
st.isHandled = true;
// Only close down the menu if we don't have an action bar keeping it open.
- if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mActionBar == null) {
+ if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0 && mDecorContentParent == null) {
closePanel(st, true);
}
}
@@ -1002,7 +1065,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean res = st.menu.performIdentifierAction(id, flags);
// Only close down the menu if we don't have an action bar keeping it open.
- if (mActionBar == null) {
+ if (mDecorContentParent == null) {
closePanel(st, true);
}
@@ -1037,12 +1100,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
private void reopenMenu(boolean toggleMenuMode) {
- if (mActionBar != null && mActionBar.isOverflowReserved() &&
+ if (mDecorContentParent != null && mDecorContentParent.canShowOverflowMenu() &&
(!ViewConfiguration.get(getContext()).hasPermanentMenuKey() ||
- mActionBar.isOverflowMenuShowPending())) {
+ mDecorContentParent.isOverflowMenuShowPending())) {
final Callback cb = getCallback();
- if (!mActionBar.isOverflowMenuShowing() || !toggleMenuMode) {
- if (cb != null && !isDestroyed() && mActionBar.getVisibility() == View.VISIBLE) {
+ if (!mDecorContentParent.isOverflowMenuShowing() || !toggleMenuMode) {
+ if (cb != null && !isDestroyed()) {
// If we have a menu invalidation pending, do it now.
if (mInvalidatePanelMenuPosted &&
(mInvalidatePanelMenuFeatures & (1 << FEATURE_OPTIONS_PANEL)) != 0) {
@@ -1057,11 +1120,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (st.menu != null && !st.refreshMenuContent &&
cb.onPreparePanel(FEATURE_OPTIONS_PANEL, st.createdPanelView, st.menu)) {
cb.onMenuOpened(FEATURE_ACTION_BAR, st.menu);
- mActionBar.showOverflowMenu();
+ mDecorContentParent.showOverflowMenu();
}
}
} else {
- mActionBar.hideOverflowMenu();
+ mDecorContentParent.hideOverflowMenu();
if (cb != null && !isDestroyed()) {
final PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true);
cb.onPanelClosed(FEATURE_ACTION_BAR, st.menu);
@@ -1098,7 +1161,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// If we have an action bar, initialize the menu with a context themed for it.
if ((st.featureId == FEATURE_OPTIONS_PANEL || st.featureId == FEATURE_ACTION_BAR) &&
- mActionBar != null) {
+ mDecorContentParent != null) {
TypedValue outValue = new TypedValue();
Resources.Theme currentTheme = context.getTheme();
currentTheme.resolveAttribute(com.android.internal.R.attr.actionBarWidgetTheme,
@@ -1226,7 +1289,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 {
@@ -1443,8 +1506,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mIconRes = resId;
mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON;
mResourcesSetFlags &= ~FLAG_RESOURCE_SET_ICON_FALLBACK;
- if (mActionBar != null) {
- mActionBar.setIcon(resId);
+ if (mDecorContentParent != null) {
+ mDecorContentParent.setIcon(resId);
}
}
@@ -1454,13 +1517,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return;
}
mIconRes = resId;
- if (mActionBar != null && (!mActionBar.hasIcon() ||
+ if (mDecorContentParent != null && (!mDecorContentParent.hasIcon() ||
(mResourcesSetFlags & FLAG_RESOURCE_SET_ICON_FALLBACK) != 0)) {
if (resId != 0) {
- mActionBar.setIcon(resId);
+ mDecorContentParent.setIcon(resId);
mResourcesSetFlags &= ~FLAG_RESOURCE_SET_ICON_FALLBACK;
} else {
- mActionBar.setIcon(getContext().getPackageManager().getDefaultActivityIcon());
+ mDecorContentParent.setIcon(
+ getContext().getPackageManager().getDefaultActivityIcon());
mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
}
}
@@ -1470,8 +1534,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
public void setLogo(int resId) {
mLogoRes = resId;
mResourcesSetFlags |= FLAG_RESOURCE_SET_LOGO;
- if (mActionBar != null) {
- mActionBar.setLogo(resId);
+ if (mDecorContentParent != null) {
+ mDecorContentParent.setLogo(resId);
}
}
@@ -1481,8 +1545,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return;
}
mLogoRes = resId;
- if (mActionBar != null && !mActionBar.hasLogo()) {
- mActionBar.setLogo(resId);
+ if (mDecorContentParent != null && !mDecorContentParent.hasLogo()) {
+ mDecorContentParent.setLogo(resId);
}
}
@@ -1739,9 +1803,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
outState.putSparseParcelableArray(PANELS_TAG, panelStates);
}
- if (mActionBar != null) {
+ if (mDecorContentParent != null) {
SparseArray<Parcelable> actionBarStates = new SparseArray<Parcelable>();
- mActionBar.saveHierarchyState(actionBarStates);
+ mDecorContentParent.saveToolbarHierarchyState(actionBarStates);
outState.putSparseParcelableArray(ACTION_BAR_TAG, actionBarStates);
}
@@ -1780,11 +1844,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
restorePanelState(panelStates);
}
- if (mActionBar != null) {
+ if (mDecorContentParent != null) {
SparseArray<Parcelable> actionBarStates =
savedInstanceState.getSparseParcelableArray(ACTION_BAR_TAG);
if (actionBarStates != null) {
- mActionBar.restoreHierarchyState(actionBarStates);
+ mDecorContentParent.restoreToolbarHierarchyState(actionBarStates);
} else {
Log.w(TAG, "Missing saved instance states for action bar views! " +
"State will not be restored.");
@@ -1914,7 +1978,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- private final class DecorView extends FrameLayout implements RootViewSurfaceTaker {
+ private final class DecorView extends FrameLayout implements RootViewSurfaceTaker,
+ View.OnSystemUiVisibilityChangeListener {
/* package */int mDefaultOpacity = PixelFormat.OPAQUE;
/** The feature ID of the panel, or -1 if this is the application's DecorView */
@@ -1944,6 +2009,14 @@ 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 int mLastTopInset = 0;
+ private int mLastBottomInset = 0;
+ private int mLastSystemUiVisibility = 0;
+
+
public DecorView(Context context, int featureId) {
super(context);
mFeatureId = featureId;
@@ -2049,12 +2122,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
public boolean superDispatchKeyEvent(KeyEvent event) {
- if (super.dispatchKeyEvent(event)) {
- return true;
- }
-
- // Not handled by the view hierarchy, does the action bar want it
- // to cancel out of something special?
+ // Give priority to closing action modes if applicable.
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
final int action = event.getAction();
// Back cancels action modes first.
@@ -2064,17 +2132,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
return true;
}
-
- // Next collapse any expanded action views.
- if (mActionBar != null && mActionBar.hasExpandedActionView()) {
- if (action == KeyEvent.ACTION_UP) {
- mActionBar.collapseActionView();
- }
- return true;
- }
}
- return false;
+ return super.dispatchKeyEvent(event);
}
public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
@@ -2242,7 +2302,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) {
@@ -2509,8 +2569,15 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ public void onSystemUiVisibilityChange(int visible) {
+ mLastSystemUiVisibility = visible;
+ updateColorViews(null /* insets */);
+ }
+
+ @Override
protected boolean fitSystemWindows(Rect insets) {
mFrameOffsets.set(insets);
+ updateColorViews(insets);
updateStatusGuard(insets);
updateNavigationGuard(insets);
if (getForeground() != null) {
@@ -2519,6 +2586,57 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return super.fitSystemWindows(insets);
}
+ @Override
+ public boolean isTransitionGroup() {
+ return false;
+ }
+
+ private void updateColorViews(Rect insets) {
+ if (mIsFloating || !ActivityManager.isHighEndGfx()) {
+ // No colors on floating windows or low end devices :(
+ return;
+ }
+ if (insets != null) {
+ mLastTopInset = insets.top;
+ mLastBottomInset = insets.bottom;
+ }
+ mStatusColorView = updateColorViewInt(mStatusColorView,
+ SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
+ mStatusBarColor, mLastTopInset, Gravity.TOP);
+ mNavigationColorView = updateColorViewInt(mNavigationColorView,
+ SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
+ mNavigationBarColor, mLastBottomInset, Gravity.BOTTOM);
+ }
+
+ private View updateColorViewInt(View view, int systemUiHideFlag, int translucentFlag,
+ int color, int height, int verticalGravity) {
+ boolean show = height > 0 && (mLastSystemUiVisibility & systemUiHideFlag) == 0
+ && (getAttributes().flags & translucentFlag) == 0
+ && (color & Color.BLACK) != 0
+ && (getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
+
+ if (view == null) {
+ if (show) {
+ view = new View(mContext);
+ view.setBackgroundColor(color);
+ addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
+ Gravity.START | verticalGravity));
+ }
+ } else {
+ int vis = show ? VISIBLE : INVISIBLE;
+ view.setVisibility(vis);
+ if (show) {
+ LayoutParams lp = (LayoutParams) view.getLayoutParams();
+ if (lp.height != height) {
+ lp.height = height;
+ view.setLayoutParams(lp);
+ }
+ view.setBackgroundColor(color);
+ }
+ }
+ return view;
+ }
+
private void updateStatusGuard(Rect insets) {
boolean showStatusGuard = false;
// Show the status guard when the non-overlay contextual action bar is showing
@@ -2538,9 +2656,9 @@ 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, new LayoutParams(
- LayoutParams.MATCH_PARENT, mlp.topMargin,
- Gravity.START | Gravity.TOP));
+ addView(mStatusGuard, indexOfChild(mStatusColorView),
+ new LayoutParams(LayoutParams.MATCH_PARENT, mlp.topMargin,
+ Gravity.START | Gravity.TOP));
} else {
LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams();
if (lp.height != mlp.topMargin) {
@@ -2585,7 +2703,7 @@ 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, new LayoutParams(
+ addView(mNavigationGuard, indexOfChild(mNavigationColorView), new LayoutParams(
LayoutParams.MATCH_PARENT, insets.bottom,
Gravity.START | Gravity.BOTTOM));
} else {
@@ -2711,8 +2829,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
cb.onDetachedFromWindow();
}
- if (mActionBar != null) {
- mActionBar.dismissPopupMenus();
+ if (mDecorContentParent != null) {
+ mDecorContentParent.dismissPopups();
}
if (mActionModePopup != null) {
@@ -2919,6 +3037,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);
@@ -2928,6 +3049,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
final boolean targetPreIcs = targetSdk < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
+ final boolean targetPreL = targetSdk < android.os.Build.VERSION_CODES.L;
final boolean targetHcNeedsOptions = context.getResources().getBoolean(
com.android.internal.R.bool.target_honeycomb_needs_options_menu);
final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE);
@@ -2937,7 +3059,25 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
} else {
clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
}
-
+
+ // Non-floating windows on high end devices must put up decor beneath the system bars and
+ // therefore must know about visibility changes of those.
+ if (!mIsFloating && ActivityManager.isHighEndGfx()) {
+ if (!targetPreL && a.getBoolean(
+ com.android.internal.R.styleable.Window_windowDrawsSystemBarBackgrounds,
+ false)) {
+ setFlags(FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
+ FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS & ~getForcedWindowFlags());
+ }
+ decor.setOnSystemUiVisibilityChangeListener(decor);
+ }
+ if (!mForcedStatusBarColor) {
+ mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);
+ }
+ if (!mForcedNavigationBarColor) {
+ mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);
+ }
+
if (mAlwaysReadCloseOnTouchAttr || getContext().getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.HONEYCOMB) {
if (a.getBoolean(
@@ -3078,12 +3218,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);
@@ -3126,105 +3266,127 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// Set up decor part of UI to ignore fitsSystemWindows if appropriate.
mDecor.makeOptionalFitsSystemWindows();
- mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
- if (mTitleView != null) {
- mTitleView.setLayoutDirection(mDecor.getLayoutDirection());
- if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
- View titleContainer = findViewById(com.android.internal.R.id.title_container);
- if (titleContainer != null) {
- titleContainer.setVisibility(View.GONE);
- } else {
- mTitleView.setVisibility(View.GONE);
- }
- if (mContentParent instanceof FrameLayout) {
- ((FrameLayout)mContentParent).setForeground(null);
- }
- } else {
- mTitleView.setText(mTitle);
+ final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(
+ com.android.internal.R.id.decor_content_parent);
+
+ if (decorContentParent != null) {
+ mDecorContentParent = decorContentParent;
+ mDecorContentParent.setWindowCallback(getCallback());
+ if (mDecorContentParent.getTitle() == null) {
+ mDecorContentParent.setWindowTitle(mTitle);
}
- } else {
- mActionBar = (ActionBarView) findViewById(com.android.internal.R.id.action_bar);
- if (mActionBar != null) {
- mActionBar.setWindowCallback(getCallback());
- if (mActionBar.getTitle() == null) {
- mActionBar.setWindowTitle(mTitle);
- }
- final int localFeatures = getLocalFeatures();
- if ((localFeatures & (1 << FEATURE_PROGRESS)) != 0) {
- mActionBar.initProgress();
- }
- if ((localFeatures & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) {
- mActionBar.initIndeterminateProgress();
- }
- final ActionBarOverlayLayout abol = (ActionBarOverlayLayout) findViewById(
- com.android.internal.R.id.action_bar_overlay_layout);
- if (abol != null) {
- abol.setOverlayMode(
- (localFeatures & (1 << FEATURE_ACTION_BAR_OVERLAY)) != 0);
+ final int localFeatures = getLocalFeatures();
+ for (int i = 0; i < FEATURE_MAX; i++) {
+ if ((localFeatures & (1 << i)) != 0) {
+ mDecorContentParent.initFeature(i);
}
+ }
- boolean splitActionBar = false;
- final boolean splitWhenNarrow =
- (mUiOptions & ActivityInfo.UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW) != 0;
- if (splitWhenNarrow) {
- splitActionBar = getContext().getResources().getBoolean(
- com.android.internal.R.bool.split_action_bar_is_narrow);
- } else {
- splitActionBar = getWindowStyle().getBoolean(
- com.android.internal.R.styleable.Window_windowSplitActionBar, false);
+ mDecorContentParent.setUiOptions(mUiOptions);
+
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
+ (mIconRes != 0 && !mDecorContentParent.hasIcon())) {
+ mDecorContentParent.setIcon(mIconRes);
+ } else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&
+ mIconRes == 0 && !mDecorContentParent.hasIcon()) {
+ mDecorContentParent.setIcon(
+ getContext().getPackageManager().getDefaultActivityIcon());
+ mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
+ }
+ if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
+ (mLogoRes != 0 && !mDecorContentParent.hasLogo())) {
+ mDecorContentParent.setLogo(mLogoRes);
+ }
+
+ // Post the panel invalidate for later; avoid application onCreateOptionsMenu
+ // being called in the middle of onCreate or similar.
+ mDecor.post(new Runnable() {
+ public void run() {
+ // Invalidate if the panel menu hasn't been created before this.
+ PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
+ if (!isDestroyed() && (st == null || st.menu == null)) {
+ invalidatePanelMenu(FEATURE_ACTION_BAR);
+ }
}
- final ActionBarContainer splitView = (ActionBarContainer) findViewById(
- com.android.internal.R.id.split_action_bar);
- if (splitView != null) {
- mActionBar.setSplitView(splitView);
- mActionBar.setSplitActionBar(splitActionBar);
- mActionBar.setSplitWhenNarrow(splitWhenNarrow);
-
- final ActionBarContextView cab = (ActionBarContextView) findViewById(
- com.android.internal.R.id.action_context_bar);
- cab.setSplitView(splitView);
- cab.setSplitActionBar(splitActionBar);
- cab.setSplitWhenNarrow(splitWhenNarrow);
- } else if (splitActionBar) {
- Log.e(TAG, "Requested split action bar with " +
- "incompatible window decor! Ignoring request.");
+ });
+ } else {
+ mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
+ if (mTitleView != null) {
+ mTitleView.setLayoutDirection(mDecor.getLayoutDirection());
+ if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
+ View titleContainer = findViewById(
+ com.android.internal.R.id.title_container);
+ if (titleContainer != null) {
+ titleContainer.setVisibility(View.GONE);
+ } else {
+ mTitleView.setVisibility(View.GONE);
+ }
+ if (mContentParent instanceof FrameLayout) {
+ ((FrameLayout)mContentParent).setForeground(null);
+ }
+ } else {
+ mTitleView.setText(mTitle);
}
+ }
+ }
- if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||
- (mIconRes != 0 && !mActionBar.hasIcon())) {
- mActionBar.setIcon(mIconRes);
- } else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&
- mIconRes == 0 && !mActionBar.hasIcon()) {
- mActionBar.setIcon(
- getContext().getPackageManager().getDefaultActivityIcon());
- mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;
- }
- if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||
- (mLogoRes != 0 && !mActionBar.hasLogo())) {
- mActionBar.setLogo(mLogoRes);
+ // 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();
}
+ }
- // Post the panel invalidate for later; avoid application onCreateOptionsMenu
- // being called in the middle of onCreate or similar.
- mDecor.post(new Runnable() {
- public void run() {
- // Invalidate if the panel menu hasn't been created before this.
- PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
- if (!isDestroyed() && (st == null || st.menu == null)) {
- invalidatePanelMenu(FEATURE_ACTION_BAR);
- }
- }
- });
+ 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);
}
@@ -3391,6 +3553,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return (mLeftIconView = (ImageView)findViewById(com.android.internal.R.id.left_icon));
}
+ @Override
+ protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
+ super.dispatchWindowAttributesChanged(attrs);
+ if (mDecor != null) {
+ mDecor.updateColorViews(null /* insets */);
+ }
+ }
+
private ProgressBar getCircularProgressBar(boolean shouldInstallDecor) {
if (mCircularProgressBar != null) {
return mCircularProgressBar;
@@ -3536,6 +3706,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;
@@ -3969,4 +4205,32 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
void sendCloseSystemWindows(String reason) {
PhoneWindowManager.sendCloseSystemWindows(getContext(), reason);
}
+
+ @Override
+ public int getStatusBarColor() {
+ return mStatusBarColor;
+ }
+
+ @Override
+ public void setStatusBarColor(int color) {
+ mStatusBarColor = color;
+ mForcedStatusBarColor = true;
+ if (mDecor != null) {
+ mDecor.updateColorViews(null);
+ }
+ }
+
+ @Override
+ public int getNavigationBarColor() {
+ return mNavigationBarColor;
+ }
+
+ @Override
+ public void setNavigationBarColor(int color) {
+ mNavigationBarColor = color;
+ mForcedNavigationBarColor = true;
+ if (mDecor != null) {
+ mDecor.updateColorViews(null);
+ }
+ }
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 524cf69..99dd2f4 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -46,6 +46,7 @@ import android.media.AudioSystem;
import android.media.IAudioService;
import android.media.Ringtone;
import android.media.RingtoneManager;
+import android.media.session.MediaSessionLegacyHelper;
import android.os.Bundle;
import android.os.FactoryTest;
import android.os.Handler;
@@ -91,10 +92,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;
@@ -134,6 +138,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+ // Whether to use the new Session APIs
+ static final boolean USE_SESSIONS = true;
+
static final int SHORT_PRESS_POWER_NOTHING = 0;
static final int SHORT_PRESS_POWER_GO_TO_SLEEP = 1;
static final int SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP = 2;
@@ -172,12 +179,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.STATUS_BAR_TRANSLUCENT
- | View.NAVIGATION_BAR_TRANSLUCENT;
+ | View.NAVIGATION_BAR_TRANSLUCENT
+ | View.SYSTEM_UI_TRANSPARENT;
/**
* Keyguard stuff
*/
private WindowState mKeyguardScrim;
+ private boolean mKeyguardHidden;
+ private boolean mKeyguardDrawn;
/* Table of Application Launch keys. Maps from key codes to intent categories.
*
@@ -218,6 +228,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;
@@ -228,6 +239,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;
@@ -248,7 +262,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
@@ -257,13 +270,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
WindowState mLastInputMethodWindow = null;
WindowState mLastInputMethodTargetWindow = null;
- static final int RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS = 0;
- static final int RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW = 1;
- static final int RECENT_APPS_BEHAVIOR_DISMISS = 2;
- static final int RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH = 3;
-
- RecentApplicationsDialog mRecentAppsDialog;
- int mRecentAppsDialogHeldModifiers;
+ int mRecentAppsHeldModifiers;
boolean mLanguageSwitchKeyPressed;
int mLidState = LID_ABSENT;
@@ -303,7 +310,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
@@ -312,17 +318,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
@@ -540,9 +535,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();
}
@@ -810,6 +808,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
}
+ boolean isUserSetupComplete() {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+ }
+
private void handleLongPressOnHome() {
if (mLongPressOnHomeBehavior != LONG_PRESS_HOME_NOTHING) {
mHomeConsumed = true;
@@ -840,52 +843,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
- /**
- * Create (if necessary) and show or dismiss the recent apps dialog according
- * according to the requested behavior.
- */
- void showOrHideRecentAppsDialog(final int behavior) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- if (mRecentAppsDialog == null) {
- mRecentAppsDialog = new RecentApplicationsDialog(mContext);
- }
- if (mRecentAppsDialog.isShowing()) {
- switch (behavior) {
- case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
- case RECENT_APPS_BEHAVIOR_DISMISS:
- mRecentAppsDialog.dismiss();
- break;
- case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
- mRecentAppsDialog.dismissAndSwitch();
- break;
- case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
- default:
- break;
- }
- } else {
- switch (behavior) {
- case RECENT_APPS_BEHAVIOR_SHOW_OR_DISMISS:
- mRecentAppsDialog.show();
- break;
- case RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW:
- try {
- mWindowManager.setInTouchMode(false);
- } catch (RemoteException e) {
- }
- mRecentAppsDialog.show();
- break;
- case RECENT_APPS_BEHAVIOR_DISMISS:
- case RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH:
- default:
- break;
- }
- }
- }
- });
- }
-
/** {@inheritDoc} */
@Override
public void init(Context context, IWindowManager windowManager,
@@ -945,6 +902,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);
@@ -1005,6 +965,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(),
@@ -1019,7 +981,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);
@@ -1143,7 +1105,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
@@ -1212,8 +1175,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
updateRotation = true;
}
if (mImmersiveModeConfirmation != null) {
- mImmersiveModeConfirmation.loadSetting();
+ mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
}
+ PolicyControl.reloadFromSetting(mContext);
}
if (updateRotation) {
updateRotation(true);
@@ -1224,7 +1188,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);
@@ -1244,22 +1207,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;
}
@@ -1351,7 +1306,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:
@@ -1388,13 +1342,36 @@ 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;
+ }
+
+ if (ActivityManager.isHighEndGfx()
+ && (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0) {
+ attrs.subtreeSystemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
}
}
-
+
void readLidState() {
mLidState = mWindowManagerFuncs.getLidState();
}
-
+
private boolean isHidden(int accessibilityMode) {
switch (accessibilityMode) {
case 1:
@@ -1474,54 +1451,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;
@@ -1591,7 +1564,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
@@ -1602,7 +1575,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:
@@ -1746,16 +1718,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/**
* Preflight adding a window to the system.
- *
+ *
* Currently enforces that three window types are singletons:
* <ul>
* <li>STATUS_BAR_TYPE</li>
* <li>KEYGUARD_TYPE</li>
* </ul>
- *
+ *
* @param win The window to be added
* @param attrs Information about the window to be added
- *
+ *
* @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons,
* WindowManagerImpl.ADD_MULTIPLE_SINGLETON
*/
@@ -1801,12 +1773,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;
@@ -1823,9 +1789,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");
@@ -1837,19 +1800,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
static final boolean PRINT_ANIM = false;
-
+
/** {@inheritDoc} */
@Override
public int selectAnimationLw(WindowState win, int transit) {
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.
@@ -2070,9 +2034,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;
}
@@ -2287,21 +2251,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Display task switcher for ALT-TAB or Meta-TAB.
if (down && repeatCount == 0 && keyCode == KeyEvent.KEYCODE_TAB) {
- if (mRecentAppsDialogHeldModifiers == 0 && !keyguardOn) {
+ if (mRecentAppsHeldModifiers == 0 && !keyguardOn) {
final int shiftlessModifiers = event.getModifiers() & ~KeyEvent.META_SHIFT_MASK;
if (KeyEvent.metaStateHasModifiers(shiftlessModifiers, KeyEvent.META_ALT_ON)
|| KeyEvent.metaStateHasModifiers(
shiftlessModifiers, KeyEvent.META_META_ON)) {
- mRecentAppsDialogHeldModifiers = shiftlessModifiers;
- showOrHideRecentAppsDialog(RECENT_APPS_BEHAVIOR_EXIT_TOUCH_MODE_AND_SHOW);
+ mRecentAppsHeldModifiers = shiftlessModifiers;
+ showRecentApps(true);
return -1;
}
}
- } else if (!down && mRecentAppsDialogHeldModifiers != 0
- && (metaState & mRecentAppsDialogHeldModifiers) == 0) {
- mRecentAppsDialogHeldModifiers = 0;
- showOrHideRecentAppsDialog(keyguardOn ? RECENT_APPS_BEHAVIOR_DISMISS :
- RECENT_APPS_BEHAVIOR_DISMISS_AND_SWITCH);
+ } else if (!down && mRecentAppsHeldModifiers != 0
+ && (metaState & mRecentAppsHeldModifiers) == 0) {
+ mRecentAppsHeldModifiers = 0;
+ hideRecentApps(true);
}
// Handle keyboard language switching.
@@ -2416,7 +2379,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
- // TODO: This only stops the factory-installed search manager.
+ // TODO: This only stops the factory-installed search manager.
// Need to formalize an API to handle others
SearchManager searchManager = getSearchManager();
if (searchManager != null) {
@@ -2474,7 +2437,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
statusbar.cancelPreloadRecentApps();
}
} catch (RemoteException e) {
- Slog.e(TAG, "RemoteException when showing recent apps", e);
+ Slog.e(TAG, "RemoteException when cancelling recent apps preload", e);
// re-acquire status bar service next time it is needed.
mStatusBarService = null;
}
@@ -2483,25 +2446,52 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private void toggleRecentApps() {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
try {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
statusbar.toggleRecentApps();
}
} catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when toggling recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ }
+
+ private void showRecentApps(boolean triggeredFromAltTab) {
+ mPreloadedRecentApps = false; // preloading no longer needs to be canceled
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.showRecentApps(triggeredFromAltTab);
+ }
+ } catch (RemoteException e) {
Slog.e(TAG, "RemoteException when showing recent apps", e);
// re-acquire status bar service next time it is needed.
mStatusBarService = null;
}
}
+ private void hideRecentApps(boolean triggeredFromAltTab) {
+ mPreloadedRecentApps = false; // preloading no longer needs to be canceled
+ try {
+ IStatusBarService statusbar = getStatusBarService();
+ if (statusbar != null) {
+ statusbar.hideRecentApps(triggeredFromAltTab);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "RemoteException when closing recent apps", e);
+ // re-acquire status bar service next time it is needed.
+ mStatusBarService = null;
+ }
+ }
+
/**
* A home key -> launch home action was detected. Take the appropriate action
* 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
@@ -2621,8 +2611,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)) {
@@ -2741,7 +2732,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// drive nav being hidden only by whether it is requested.
final int sysui = mLastSystemUiFlags;
boolean navVisible = (sysui & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
- boolean navTranslucent = (sysui & View.NAVIGATION_BAR_TRANSLUCENT) != 0;
+ boolean navTranslucent = (sysui
+ & (View.NAVIGATION_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0;
boolean immersive = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE) != 0;
boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
boolean navAllowedHidden = immersive || immersiveSticky;
@@ -2794,7 +2786,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
@@ -2866,7 +2859,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0;
- boolean statusBarTranslucent = (sysui & View.STATUS_BAR_TRANSLUCENT) != 0;
+ boolean statusBarTranslucent = (sysui
+ & (View.STATUS_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0;
statusBarTranslucent &= areTranslucentBarsAllowed();
// If the status bar is hidden, we don't want to cause
@@ -3003,9 +2997,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;
@@ -3062,12 +3056,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (isAppWindow && !inheritTranslucentDecor && !topAtRest) {
if ((sysUiFl & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0
&& (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0
- && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0) {
+ && (fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) == 0
+ && (fl & WindowManager.LayoutParams.
+ FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes status bar
dcf.top = mStableTop;
}
if ((fl & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0
- && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) {
+ && (sysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0
+ && (fl & WindowManager.LayoutParams.
+ FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0) {
// Ensure policy decor includes navigation bar
dcf.bottom = mStableBottom;
dcf.right = mStableRight;
@@ -3076,7 +3074,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
== (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ if (DEBUG_LAYOUT) Slog.v(TAG, "layoutWindowLw(" + attrs.getTitle()
+ "): IN_SCREEN, INSET_DECOR");
// This is the case for a normal activity window: we want it
// to cover all of the screen space, and it can take care of
@@ -3121,9 +3119,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
@@ -3361,7 +3358,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
+ ": sim=#" + Integer.toHexString(sim)
- + " attach=" + attached + " type=" + attrs.type
+ + " attach=" + attached + " type=" + attrs.type
+ String.format(" flags=0x%08x", fl)
+ " pf=" + pf.toShortString() + " df=" + df.toShortString()
+ " of=" + of.toShortString()
@@ -3410,7 +3407,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mForceStatusBarFromKeyguard = false;
mForcingShowNavBar = false;
mForcingShowNavBarLayer = -1;
-
+
mHideLockScreen = false;
mAllowLockscreenWhenOn = false;
mDismissKeyguard = DISMISS_KEYGUARD_NONE;
@@ -3424,21 +3421,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
@@ -3453,8 +3454,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());
@@ -3474,14 +3475,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;
}
}
@@ -3524,13 +3526,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
@@ -3566,11 +3569,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;
@@ -3584,24 +3588,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() {
@@ -3611,12 +3613,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);
}
}
@@ -3631,9 +3633,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;
}
@@ -3855,15 +3887,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
@@ -3877,8 +3903,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;
@@ -4008,8 +4034,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;
@@ -4027,7 +4056,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();
@@ -4222,12 +4251,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
if (ActivityManagerNative.isSystemReady()) {
- IAudioService audioService = getAudioService();
- if (audioService != null) {
- try {
- audioService.dispatchMediaKeyEventUnderWakelock(event);
- } catch (RemoteException e) {
- Log.e(TAG, "dispatchMediaKeyEvent threw exception " + e);
+ if (USE_SESSIONS) {
+ MediaSessionLegacyHelper.getHelper(mContext).sendMediaButtonEvent(event, true);
+ } else {
+ IAudioService audioService = getAudioService();
+ if (audioService != null) {
+ try {
+ audioService.dispatchMediaKeyEventUnderWakelock(event);
+ } catch (RemoteException e) {
+ Log.e(TAG, "dispatchMediaKeyEvent threw exception " + e);
+ }
}
}
}
@@ -4290,8 +4323,19 @@ 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()) {
+ if (!isUserSetupComplete()) {
+ // Swipe-up for navigation bar is disabled during setup
+ return;
+ }
boolean sb = mStatusBarController.checkShowTransientBarLw();
boolean nb = mNavigationBarController.checkShowTransientBarLw();
if (sb || nb) {
@@ -4344,21 +4388,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,
@@ -4371,6 +4410,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void sendResult(Bundle data) {
Slog.i(TAG, "Lock screen displayed!");
finishScreenTurningOn(screenOnListener);
+ setKeyguardDrawn();
}
})) {
return;
@@ -4384,6 +4424,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Slog.i(TAG, "No lock screen! windowToken=" + windowToken);
finishScreenTurningOn(screenOnListener);
+ setKeyguardDrawn();
}
private void finishScreenTurningOn(ScreenOnListener screenOnListener) {
@@ -4427,7 +4468,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private boolean keyguardIsShowingTq() {
if (mKeyguardDelegate == null) return false;
- return mKeyguardDelegate.isShowingAndNotHidden();
+ return mKeyguardDelegate.isShowingAndNotOccluded();
}
@@ -4449,7 +4490,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
public void dismissKeyguardLw() {
- if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
+ if (mKeyguardDelegate != null && mKeyguardDelegate.isShowing()) {
mHandler.post(new Runnable() {
public void run() {
if (mKeyguardDelegate.isDismissable()) {
@@ -4464,6 +4505,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);
}
@@ -4747,6 +4805,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
synchronized (mLock) {
mSystemBooted = true;
}
+ waitForKeyguard(null);
}
ProgressDialog mBootMsgDialog = null;
@@ -4756,9 +4815,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
mHandler.post(new Runnable() {
@Override public void run() {
if (mBootMsgDialog == null) {
- int theme = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WATCH) ?
- com.android.internal.R.style.Theme_Micro_Dialog_Alert : 0;
+ int theme;
+ if (mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WATCH)) {
+ theme = com.android.internal.R.style.Theme_Micro_Dialog_Alert;
+ } else if (mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_TELEVISION)) {
+ theme = com.android.internal.R.style.Theme_Leanback_Dialog_Alert;
+ } else {
+ theme = 0;
+ }
mBootMsgDialog = new ProgressDialog(mContext, theme) {
// This dialog will consume all events coming in to
@@ -5077,7 +5143,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;
@@ -5091,6 +5157,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;
@@ -5111,10 +5180,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;
}
@@ -5125,8 +5194,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);
}
}
@@ -5138,7 +5206,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
@@ -5148,11 +5216,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;
@@ -5184,8 +5252,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);
@@ -5196,14 +5264,16 @@ 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);
}
if (!areTranslucentBarsAllowed()) {
- vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT);
+ vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT
+ | View.SYSTEM_UI_TRANSPARENT);
}
// update status bar
@@ -5211,7 +5281,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;
@@ -5244,7 +5314,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
boolean newImmersiveMode = isImmersiveMode(vis);
if (win != null && oldImmersiveMode != newImmersiveMode) {
final String pkg = win.getOwningPackage();
- mImmersiveModeConfirmation.immersiveModeChanged(pkg, newImmersiveMode);
+ mImmersiveModeConfirmation.immersiveModeChanged(pkg, newImmersiveMode,
+ isUserSetupComplete());
}
vis = mNavigationBarController.updateVisibilityLw(transientNavBarAllowed, oldVis, vis);
@@ -5275,7 +5346,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
@@ -5292,6 +5364,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
@Override
+ public int getInputMethodWindowVisibleHeightLw() {
+ return mDockBottom - mCurBottom;
+ }
+
+ @Override
public void setCurrentUserLw(int newUserId) {
mCurrentUserId = newUserId;
if (mKeyguardDelegate != null) {
@@ -5321,11 +5398,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) {
@@ -5443,15 +5515,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);
@@ -5496,5 +5566,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/RecentApplicationsDialog.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
index 2f0d7d6..bc55ed1 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsDialog.java
@@ -123,7 +123,7 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
}
@Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
+ 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.
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;
}
}