am f8c2ffef: am c8fd50b1: am 29b98884: Merge "Revert "During early boot, send LOCALE_CHANGED only to registered receivers"" into lmp-mr1-dev
* commit 'f8c2ffef5caca1b07bcb6160f4baf9363c5bfe87':
Revert "During early boot, send LOCALE_CHANGED only to registered receivers"
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index a7864f4..3018fe2 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -24,7 +24,10 @@
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.SurfaceTexture;
+import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
+import android.os.Message;
import android.os.OperationCanceledException;
import android.os.RemoteException;
import android.util.AttributeSet;
@@ -48,7 +51,9 @@
private static final String TAG = "ActivityView";
private static final boolean DEBUG = false;
- DisplayMetrics mMetrics;
+ private static final int MSG_SET_SURFACE = 1;
+
+ DisplayMetrics mMetrics = new DisplayMetrics();
private final TextureView mTextureView;
private ActivityContainerWrapper mActivityContainer;
private Activity mActivity;
@@ -58,6 +63,9 @@
private int mLastVisibility;
private ActivityViewCallback mActivityViewCallback;
+ private HandlerThread mThread = new HandlerThread("ActivityViewThread");
+ private Handler mHandler;
+
public ActivityView(Context context) {
this(context, null);
}
@@ -89,12 +97,27 @@
+ e);
}
+ mThread.start();
+ mHandler = new Handler(mThread.getLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ if (msg.what == MSG_SET_SURFACE) {
+ try {
+ mActivityContainer.setSurface((Surface) msg.obj, msg.arg1, msg.arg2,
+ mMetrics.densityDpi);
+ } catch (RemoteException e) {
+ throw new RuntimeException(
+ "ActivityView: Unable to set surface of ActivityContainer. " + e);
+ }
+ }
+ }
+ };
mTextureView = new TextureView(context);
mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
addView(mTextureView);
WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
- mMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(mMetrics);
mLastVisibility = getVisibility();
@@ -111,18 +134,12 @@
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
- if (mSurface != null) {
- try {
- if (visibility == View.GONE) {
- mActivityContainer.setSurface(null, mWidth, mHeight, mMetrics.densityDpi);
- } else if (mLastVisibility == View.GONE) {
- // Don't change surface when going between View.VISIBLE and View.INVISIBLE.
- mActivityContainer.setSurface(mSurface, mWidth, mHeight, mMetrics.densityDpi);
- }
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to set surface of ActivityContainer. " + e);
- }
+ if (mSurface != null && (visibility == View.GONE || mLastVisibility == View.GONE)) {
+ Message msg = Message.obtain(mHandler, MSG_SET_SURFACE);
+ msg.obj = (visibility == View.GONE) ? null : mSurface;
+ msg.arg1 = mWidth;
+ msg.arg2 = mHeight;
+ mHandler.sendMessage(msg);
}
mLastVisibility = visibility;
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index c125544..c23e7b2 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -272,7 +272,7 @@
window.setStartPosition(position);
window.setNumColumns(numColumns);
if (cursor.moveToPosition(position)) {
- do {
+ rowloop: do {
if (!window.allocRow()) {
break;
}
@@ -309,7 +309,7 @@
}
if (!success) {
window.freeLastRow();
- break;
+ break rowloop;
}
}
position += 1;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 016541f..5420cad 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -18,7 +18,6 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
-import android.os.SystemProperties;
import android.view.WindowInsets;
import com.android.internal.R;
@@ -161,9 +160,11 @@
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
+ final Rect mOutsets = new Rect();
final Rect mDispatchedOverscanInsets = new Rect();
final Rect mDispatchedContentInsets = new Rect();
final Rect mDispatchedStableInsets = new Rect();
+ final Rect mDispatchedOutsets = new Rect();
final Rect mFinalSystemInsets = new Rect();
final Rect mFinalStableInsets = new Rect();
final Configuration mConfiguration = new Configuration();
@@ -270,7 +271,7 @@
final BaseIWindow mWindow = new BaseIWindow() {
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
Message msg = mCaller.obtainMessageI(MSG_WINDOW_RESIZED,
reportDraw ? 1 : 0);
@@ -661,30 +662,35 @@
mInputEventReceiver = new WallpaperInputEventReceiver(
mInputChannel, Looper.myLooper());
}
-
+
mSurfaceHolder.mSurfaceLock.lock();
mDrawingAllowed = true;
if (!fixedSize) {
mLayout.surfaceInsets.set(mIWallpaperEngine.mDisplayPadding);
+ mLayout.surfaceInsets.left += mOutsets.left;
+ mLayout.surfaceInsets.top += mOutsets.top;
+ mLayout.surfaceInsets.right += mOutsets.right;
+ mLayout.surfaceInsets.bottom += mOutsets.bottom;
} else {
mLayout.surfaceInsets.set(0, 0, 0, 0);
}
final int relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets,
- mVisibleInsets, mStableInsets, mConfiguration, mSurfaceHolder.mSurface);
+ mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
+ mSurfaceHolder.mSurface);
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
+ ", frame=" + mWinFrame);
-
+
int w = mWinFrame.width();
int h = mWinFrame.height();
if (!fixedSize) {
final Rect padding = mIWallpaperEngine.mDisplayPadding;
- w += padding.left + padding.right;
- h += padding.top + padding.bottom;
+ w += padding.left + padding.right + mOutsets.left + mOutsets.right;
+ h += padding.top + padding.bottom + mOutsets.top + mOutsets.bottom;
mOverscanInsets.left += padding.left;
mOverscanInsets.top += padding.top;
mOverscanInsets.right += padding.right;
@@ -708,9 +714,14 @@
mCurHeight = h;
}
+ if (DEBUG) {
+ Log.v(TAG, "Wallpaper size has changed: (" + mCurWidth + ", " + mCurHeight);
+ }
+
insetsChanged |= !mDispatchedOverscanInsets.equals(mOverscanInsets);
insetsChanged |= !mDispatchedContentInsets.equals(mContentInsets);
insetsChanged |= !mDispatchedStableInsets.equals(mStableInsets);
+ insetsChanged |= !mDispatchedOutsets.equals(mOutsets);
mSurfaceHolder.setSurfaceFrameSize(w, h);
mSurfaceHolder.mSurfaceLock.unlock();
@@ -770,13 +781,20 @@
if (insetsChanged) {
mDispatchedOverscanInsets.set(mOverscanInsets);
+ mDispatchedOverscanInsets.left += mOutsets.left;
+ mDispatchedOverscanInsets.top += mOutsets.top;
+ mDispatchedOverscanInsets.right += mOutsets.right;
+ mDispatchedOverscanInsets.bottom += mOutsets.bottom;
mDispatchedContentInsets.set(mContentInsets);
mDispatchedStableInsets.set(mStableInsets);
+ mDispatchedOutsets.set(mOutsets);
mFinalSystemInsets.set(mDispatchedOverscanInsets);
mFinalStableInsets.set(mDispatchedStableInsets);
- mFinalSystemInsets.bottom = mIWallpaperEngine.mDisplayPadding.bottom;
WindowInsets insets = new WindowInsets(mFinalSystemInsets,
null, mFinalStableInsets, mWindowIsRound);
+ if (DEBUG) {
+ Log.v(TAG, "dispatching insets=" + insets);
+ }
onApplyWindowInsets(insets);
}
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 9fc80fc..b738ba0 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -46,7 +46,7 @@
void executeCommand(String command, String parameters, in ParcelFileDescriptor descriptor);
void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets,
- in Rect visibleInsets, in Rect stableInsets, boolean reportDraw,
+ in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw,
in Configuration newConfig);
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 63e1a85..ed60985 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -79,11 +79,13 @@
* contents to make sure the user can see it. This is different than
* <var>outContentInsets</var> in that these insets change transiently,
* so complex relayout of the window should not happen based on them.
+ * @param outOutsets Rect in which is placed the dead area of the screen that we would like to
+ * treat as real display. Example of such area is a chin in some models of wearable devices.
* @param outConfiguration New configuration of window, if it is now
* becoming visible and the global configuration has changed since it
* was last displayed.
* @param outSurface Object in which is placed the new display surface.
- *
+ *
* @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
* {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
*/
@@ -91,7 +93,7 @@
int requestedWidth, int requestedHeight, int viewVisibility,
int flags, out Rect outFrame, out Rect outOverscanInsets,
out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
- out Configuration outConfig, out Surface outSurface);
+ out Rect outOutsets, out Configuration outConfig, out Surface outSurface);
/**
* If a call to relayout() asked to have the surface destroy deferred,
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 49be57d..160c662 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -106,6 +106,7 @@
final Rect mOverscanInsets = new Rect();
final Rect mContentInsets = new Rect();
final Rect mStableInsets = new Rect();
+ final Rect mOutsets = new Rect();
final Configuration mConfiguration = new Configuration();
static final int KEEP_SCREEN_ON_MSG = 1;
@@ -519,7 +520,8 @@
visible ? VISIBLE : GONE,
WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
mWinFrame, mOverscanInsets, mContentInsets,
- mVisibleInsets, mStableInsets, mConfiguration, mNewSurface);
+ mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
+ mNewSurface);
if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportDrawNeeded = true;
}
@@ -654,7 +656,7 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
SurfaceView surfaceView = mSurfaceView.get();
if (surfaceView != null) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 3c05872..aeb4ac6e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6667,6 +6667,15 @@
}
/**
+ * Returns the outsets, which areas of the device that aren't a surface, but we would like to
+ * treat them as such.
+ * @hide
+ */
+ public void getOutsets(Rect outOutsetRect) {
+ outOutsetRect.set(mAttachInfo.mOutsets);
+ }
+
+ /**
* Returns the visibility status for this view.
*
* @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}.
@@ -20312,6 +20321,12 @@
final Rect mStableInsets = new Rect();
/**
+ * For windows that include areas that are not covered by real surface these are the outsets
+ * for real surface.
+ */
+ final Rect mOutsets = new Rect();
+
+ /**
* The internal insets given by this window. This value is
* supplied by the client (through
* {@link ViewTreeObserver.OnComputeInternalInsetsListener}) and will
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 113ad8d..a182ef1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -261,6 +261,7 @@
final Rect mPendingVisibleInsets = new Rect();
final Rect mPendingStableInsets = new Rect();
final Rect mPendingContentInsets = new Rect();
+ final Rect mPendingOutsets = new Rect();
final ViewTreeObserver.InternalInsetsInfo mLastGivenInsets
= new ViewTreeObserver.InternalInsetsInfo();
@@ -1222,8 +1223,14 @@
void dispatchApplyInsets(View host) {
mDispatchContentInsets.set(mAttachInfo.mContentInsets);
mDispatchStableInsets.set(mAttachInfo.mStableInsets);
- host.dispatchApplyWindowInsets(new WindowInsets(
- mDispatchContentInsets, null /* windowDecorInsets */,
+ Rect outsets = mAttachInfo.mOutsets;
+ Rect contentInsets = mDispatchContentInsets;
+ if (outsets.left > 0 || outsets.top > 0 || outsets.right > 0 || outsets.bottom > 0) {
+ contentInsets = new Rect(contentInsets.left + outsets.left,
+ contentInsets.top + outsets.top, contentInsets.right + outsets.right,
+ contentInsets.bottom + outsets.bottom);
+ }
+ host.dispatchApplyWindowInsets(new WindowInsets(contentInsets, null /* windowDecorInsets */,
mDispatchStableInsets, mWindowIsRound));
}
@@ -1369,6 +1376,9 @@
if (DEBUG_LAYOUT) Log.v(TAG, "Visible insets changing to: "
+ mAttachInfo.mVisibleInsets);
}
+ if (!mPendingOutsets.equals(mAttachInfo.mOutsets)) {
+ insetsChanged = true;
+ }
if (lp.width == ViewGroup.LayoutParams.WRAP_CONTENT
|| lp.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
windowSizeMayChange = true;
@@ -1545,6 +1555,7 @@
mAttachInfo.mVisibleInsets);
final boolean stableInsetsChanged = !mPendingStableInsets.equals(
mAttachInfo.mStableInsets);
+ final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
if (contentInsetsChanged) {
if (mWidth > 0 && mHeight > 0 && lp != null &&
((lp.systemUiVisibility|lp.subtreeSystemUiVisibility)
@@ -1628,9 +1639,11 @@
}
if (contentInsetsChanged || mLastSystemUiVisibility !=
mAttachInfo.mSystemUiVisibility || mApplyInsetsRequested
- || mLastOverscanRequested != mAttachInfo.mOverscanRequested) {
+ || mLastOverscanRequested != mAttachInfo.mOverscanRequested
+ || outsetsChanged) {
mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility;
mLastOverscanRequested = mAttachInfo.mOverscanRequested;
+ mAttachInfo.mOutsets.set(mPendingOutsets);
mApplyInsetsRequested = false;
dispatchApplyInsets(host);
}
@@ -3201,6 +3214,7 @@
&& mPendingContentInsets.equals(args.arg2)
&& mPendingStableInsets.equals(args.arg6)
&& mPendingVisibleInsets.equals(args.arg3)
+ && mPendingOutsets.equals(args.arg7)
&& args.arg4 == null) {
break;
}
@@ -3219,6 +3233,7 @@
mPendingContentInsets.set((Rect) args.arg2);
mPendingStableInsets.set((Rect) args.arg6);
mPendingVisibleInsets.set((Rect) args.arg3);
+ mPendingOutsets.set((Rect) args.arg7);
args.recycle();
@@ -5317,7 +5332,7 @@
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
- mPendingStableInsets, mPendingConfiguration, mSurface);
+ mPendingStableInsets, mPendingOutsets, mPendingConfiguration, mSurface);
//Log.d(TAG, "<<<<<< BACK FROM relayout");
if (restore) {
params.restore();
@@ -5593,7 +5608,8 @@
}
public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
+ Configuration newConfig) {
if (DEBUG_LAYOUT) Log.v(TAG, "Resizing " + this + ": frame=" + frame.toShortString()
+ " contentInsets=" + contentInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
@@ -5613,6 +5629,7 @@
args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig;
args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
+ args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
msg.obj = args;
mHandler.sendMessage(msg);
}
@@ -6492,12 +6509,12 @@
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw,
+ Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
Configuration newConfig) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
viewAncestor.dispatchResized(frame, overscanInsets, contentInsets,
- visibleInsets, stableInsets, reportDraw, newConfig);
+ visibleInsets, stableInsets, outsets, reportDraw, newConfig);
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 780ca99..71cb889 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -158,10 +158,12 @@
* @param decorFrame The decor frame specified by policy specific to this window,
* to use for proper cropping during animation.
* @param stableFrame The frame around which stable system decoration is positioned.
+ * @param outsetFrame The frame that includes areas that aren't part of the surface but we
+ * want to treat them as such.
*/
public void computeFrameLw(Rect parentFrame, Rect displayFrame,
Rect overlayFrame, Rect contentFrame, Rect visibleFrame, Rect decorFrame,
- Rect stableFrame);
+ Rect stableFrame, Rect outsetFrame);
/**
* Retrieve the current frame of the window that has been assigned by
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index c977997..b0d24fd 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -46,6 +46,7 @@
public Object arg4;
public Object arg5;
public Object arg6;
+ public Object arg7;
public int argi1;
public int argi2;
public int argi3;
@@ -97,6 +98,7 @@
arg4 = null;
arg5 = null;
arg6 = null;
+ arg7 = null;
argi1 = 0;
argi2 = 0;
argi3 = 0;
diff --git a/core/java/com/android/internal/util/ScreenShapeHelper.java b/core/java/com/android/internal/util/ScreenShapeHelper.java
index 1bcc7a0..e06bec5 100644
--- a/core/java/com/android/internal/util/ScreenShapeHelper.java
+++ b/core/java/com/android/internal/util/ScreenShapeHelper.java
@@ -18,20 +18,14 @@
/**
* Return the bottom pixel window outset of a window given its style attributes.
- * @param displayMetrics Display metrics of the current device
- * @param windowStyle Window style attributes for the window.
* @return An outset dimension in pixels or 0 if no outset should be applied.
*/
- public static int getWindowOutsetBottomPx(DisplayMetrics displayMetrics,
- TypedArray windowStyle) {
+ public static int getWindowOutsetBottomPx(Resources resources) {
if (IS_EMULATOR) {
return SystemProperties.getInt(ViewRootImpl.PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX, 0);
- } else if (windowStyle.hasValue(R.styleable.Window_windowOutsetBottom)) {
- TypedValue outsetBottom = new TypedValue();
- windowStyle.getValue(R.styleable.Window_windowOutsetBottom, outsetBottom);
- return (int) outsetBottom.getDimension(displayMetrics);
+ } else {
+ return resources.getInteger(com.android.internal.R.integer.config_windowOutsetBottom);
}
- return 0;
}
/**
@@ -41,8 +35,7 @@
if (IS_EMULATOR) {
return SystemProperties.getBoolean(ViewRootImpl.PROPERTY_EMULATOR_CIRCULAR, false);
} else {
- return resources.getBoolean(
- com.android.internal.R.bool.config_windowIsRound);
+ return resources.getBoolean(com.android.internal.R.bool.config_windowIsRound);
}
}
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 993ab58..b55aabb 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -34,8 +34,8 @@
}
@Override
- public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
+ public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
+ Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig) {
if (reportDraw) {
try {
mSession.finishDrawing(this);
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 6d4e058..35ed63b 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -16,9 +16,11 @@
package com.android.internal.widget;
-import android.animation.TimeInterpolator;
import android.app.Activity;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
@@ -28,8 +30,6 @@
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
/**
@@ -62,10 +62,6 @@
// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
- private int mMaxFlingVelocity;
- private long mAnimationTime;
- private TimeInterpolator mCancelInterpolator;
- private TimeInterpolator mDismissInterpolator;
// Transient properties
private int mActiveTouchId;
@@ -92,6 +88,18 @@
}
}
};
+ private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mDismissed) {
+ dismiss();
+ } else {
+ cancel();
+ }
+ resetMembers();
+ }
+ };
+ private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
private float mLastX;
@@ -114,11 +122,6 @@
ViewConfiguration vc = ViewConfiguration.get(context);
mSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
- mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
- mAnimationTime = getContext().getResources().getInteger(
- android.R.integer.config_shortAnimTime);
- mCancelInterpolator = new DecelerateInterpolator(1.5f);
- mDismissInterpolator = new AccelerateInterpolator(1.5f);
TypedArray a = context.getTheme().obtainStyledAttributes(
com.android.internal.R.styleable.Theme);
mUseDynamicTranslucency = !a.hasValue(
@@ -141,15 +144,17 @@
getViewTreeObserver().addOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter);
}
@Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ getContext().unregisterReceiver(mScreenOffReceiver);
if (getContext() instanceof Activity) {
getViewTreeObserver().removeOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ super.onDetachedFromWindow();
}
@Override
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index 6b99de8..912968a 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -212,13 +212,9 @@
android::Parcel* p = android::parcelForJavaObject(env, parcel);
- const size_t size = p->readInt32();
- const void* regionData = p->readInplace(size);
- if (regionData == NULL) {
- return NULL;
- }
SkRegion* region = new SkRegion;
- region->readFromMemory(regionData, size);
+ size_t size = p->readInt32();
+ region->readFromMemory(p->readInplace(size), size);
return reinterpret_cast<jlong>(region);
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f923d50..251e3af 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1826,6 +1826,11 @@
<!-- default window inset isRound property -->
<bool name="config_windowIsRound">false</bool>
+ <!-- Override this value if the device has a chin, i.e. area that is not actual part of the
+ screen but you would like to be treated as a real display. The value is the height of the
+ chin. -->
+ <integer name="config_windowOutsetBottom">0</integer>
+
<!-- Package name for default network scorer app; overridden by product overlays. -->
<string name="config_defaultNetworkScorerPackageName"></string>
@@ -2100,6 +2105,10 @@
<!-- Keyguard component -->
<string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
+ <!-- This config is used to force VoiceInteractionService to start on certain low ram devices.
+ It declares the package name of VoiceInteractionService that should be started. -->
+ <string translatable="false" name="config_forceVoiceInteractionServicePackage"></string>
+
<!-- This config is ued to determine whether animations are allowed in low power mode. -->
<bool name="config_allowAnimationsInLowPowerMode">false</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f0e56e7..3049544 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -374,6 +374,7 @@
<java-symbol type="integer" name="config_wifi_supplicant_scan_interval" />
<java-symbol type="integer" name="config_wifi_disconnected_scan_interval" />
<java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" />
+ <java-symbol type="integer" name="config_windowOutsetBottom" />
<java-symbol type="integer" name="db_connection_pool_size" />
<java-symbol type="integer" name="db_journal_size_limit" />
<java-symbol type="integer" name="db_wal_autocheckpoint" />
@@ -552,6 +553,7 @@
<java-symbol type="string" name="chooseActivity" />
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
+ <java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
<java-symbol type="string" name="config_ntpServer" />
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index 112afa6..8bf635e 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
<resources>
- <style name="Theme.Micro" parent="Theme.Material.NoActionBar">
+ <style name="Theme.MicroBase" parent="Theme.Material.NoActionBar">
<item name="alertDialogTheme">@style/Theme.Micro.Dialog.Alert</item>
<item name="alertDialogStyle">@style/AlertDialog.Micro</item>
<item name="dialogTheme">@style/Theme.Micro.Dialog</item>
@@ -29,7 +29,10 @@
<item name="windowOverscan">true</item>
</style>
- <style name="Theme.Micro.Light" parent="Theme.Material.Light.NoActionBar">
+ <style name="Theme.Micro" parent="Theme.MicroBase">
+ </style>
+
+ <style name="Theme.Micro.LightBase" parent="Theme.Material.Light.NoActionBar">
<item name="alertDialogTheme">@style/Theme.Micro.Dialog.Alert</item>
<item name="alertDialogStyle">@style/AlertDialog.Micro</item>
<item name="dialogTheme">@style/Theme.Micro.Dialog</item>
@@ -44,7 +47,11 @@
<item name="windowOverscan">true</item>
</style>
- <style name="Theme.Micro.Dialog" parent="Theme.Material.Light.Dialog">
+ <!-- Indirection needed for overlays to make sure there is a common base parent -->
+ <style name="Theme.Micro.Light" parent="Theme.Micro.LightBase">
+ </style>
+
+ <style name="Theme.Micro.DialogBase" parent="Theme.Material.Light.Dialog">
<item name="windowTitleStyle">@android:style/DialogWindowTitle.Micro</item>
<item name="windowIsFloating">false</item>
<item name="windowFullscreen">true</item>
@@ -54,6 +61,10 @@
<item name="windowOverscan">true</item>
</style>
+ <!-- Indirection needed for overlays to make sure there is a common base parent -->
+ <style name="Theme.Micro.Dialog" parent="Theme.Micro.DialogBase">
+ </style>
+
<style name="Theme.Micro.Dialog.Alert">
<item name="windowTitleStyle">@style/DialogWindowTitle.Micro</item>
<item name="alertDialogStyle">@style/AlertDialog.Micro</item>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index c9028c4..09766e4 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -25,7 +25,6 @@
import android.app.SearchManager;
import android.os.UserHandle;
import com.android.internal.R;
-import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
import com.android.internal.view.menu.ContextMenuBuilder;
@@ -62,7 +61,6 @@
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.SystemProperties;
import android.transition.Scene;
import android.transition.Transition;
import android.transition.TransitionInflater;
@@ -76,7 +74,6 @@
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.ContextThemeWrapper;
-import android.view.Display;
import android.view.Gravity;
import android.view.IRotationWatcher;
import android.view.IWindowManager;
@@ -280,6 +277,7 @@
private Boolean mSharedElementsUseOverlay;
private Rect mTempRect;
+ private Rect mOutsets = new Rect();
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
@@ -2380,19 +2378,6 @@
}
@Override
- public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- if (mOutsetBottomPx != 0) {
- WindowInsets newInsets = insets.replaceSystemWindowInsets(
- insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
- insets.getSystemWindowInsetRight(), mOutsetBottomPx);
- return super.dispatchApplyWindowInsets(newInsets);
- } else {
- return super.dispatchApplyWindowInsets(insets);
- }
- }
-
-
- @Override
public boolean onTouchEvent(MotionEvent event) {
return onInterceptTouchEvent(event);
}
@@ -2603,11 +2588,21 @@
}
}
- if (mOutsetBottomPx != 0) {
+ getOutsets(mOutsets);
+ if (mOutsets.top > 0 || mOutsets.bottom > 0) {
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (mode != MeasureSpec.UNSPECIFIED) {
int height = MeasureSpec.getSize(heightMeasureSpec);
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + mOutsetBottomPx, mode);
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ height + mOutsets.top + mOutsets.bottom, mode);
+ }
+ }
+ if (mOutsets.left > 0 || mOutsets.right > 0) {
+ int mode = MeasureSpec.getMode(widthMeasureSpec);
+ if (mode != MeasureSpec.UNSPECIFIED) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ width + mOutsets.left + mOutsets.right, mode);
}
}
@@ -2645,6 +2640,18 @@
}
@Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ getOutsets(mOutsets);
+ if (mOutsets.left > 0) {
+ offsetLeftAndRight(-mOutsets.left);
+ }
+ if (mOutsets.top > 0) {
+ offsetTopAndBottom(-mOutsets.top);
+ }
+ }
+
+ @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -3433,19 +3440,6 @@
requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
}
- final WindowManager windowService = (WindowManager) getContext().getSystemService(
- Context.WINDOW_SERVICE);
- if (windowService != null) {
- final Display display = windowService.getDefaultDisplay();
- final boolean shouldUseBottomOutset =
- display.getDisplayId() == Display.DEFAULT_DISPLAY
- || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0;
- if (shouldUseBottomOutset) {
- mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
- getContext().getResources().getDisplayMetrics(), a);
- }
- }
-
final Context context = getContext();
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a509706..37e1109 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -109,6 +109,7 @@
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate;
import com.android.internal.policy.impl.keyguard.KeyguardServiceDelegate.ShowListener;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.widget.PointerLocationView;
import com.android.server.LocalServices;
@@ -459,6 +460,7 @@
static final Rect mTmpDecorFrame = new Rect();
static final Rect mTmpStableFrame = new Rect();
static final Rect mTmpNavigationFrame = new Rect();
+ static final Rect mTmpOutsetFrame = new Rect();
WindowState mTopFullscreenOpaqueWindowState;
HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
@@ -3328,6 +3330,7 @@
final Rect of = mTmpOverscanFrame;
final Rect vf = mTmpVisibleFrame;
final Rect dcf = mTmpDecorFrame;
+ final Rect osf = mTmpOutsetFrame;
pf.left = df.left = of.left = vf.left = mDockLeft;
pf.top = df.top = of.top = vf.top = mDockTop;
pf.right = df.right = of.right = vf.right = mDockRight;
@@ -3439,7 +3442,7 @@
// And compute the final frame.
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf,
- mTmpNavigationFrame);
+ mTmpNavigationFrame, mTmpNavigationFrame);
if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + mTmpNavigationFrame);
if (mNavigationBarController.checkHiddenLw()) {
updateSysUiVisibility = true;
@@ -3464,7 +3467,7 @@
mStatusBarLayer = mStatusBar.getSurfaceLayer();
// Let the status bar determine its size.
- mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf, vf);
+ mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf, vf, osf);
// For layout, the status bar is always at the top with our fixed height.
mStableTop = mUnrestrictedScreenTop + mStatusBarHeight;
@@ -3638,6 +3641,7 @@
final Rect vf = mTmpVisibleFrame;
final Rect dcf = mTmpDecorFrame;
final Rect sf = mTmpStableFrame;
+ Rect osf = null;
dcf.setEmpty();
final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
@@ -4022,6 +4026,37 @@
}
}
+ // If the device has a chin (e.g. some watches), a dead area at the bottom of the screen we
+ // need to provide information to the clients that want to pretend that you can draw there.
+ // We only want to apply outsets to certain types of windows. For example, we never want to
+ // apply the outsets to floating dialogs, because they wouldn't make sense there.
+ final boolean useOutsets = attrs.type == TYPE_WALLPAPER
+ || (fl & (WindowManager.LayoutParams.FLAG_FULLSCREEN
+ | WindowManager.LayoutParams.FLAG_LAYOUT_IN_OVERSCAN)) != 0;
+ if (isDefaultDisplay && useOutsets) {
+ osf = mTmpOutsetFrame;
+ osf.set(cf.left, cf.top, cf.right, cf.bottom);
+ int outset = ScreenShapeHelper.getWindowOutsetBottomPx(mContext.getResources());
+ if (outset > 0) {
+ int rotation = Surface.ROTATION_0;
+ try {
+ rotation = mWindowManager.getRotation();
+ } catch (RemoteException e) {
+ }
+ if (rotation == Surface.ROTATION_0) {
+ osf.bottom += outset;
+ } else if (rotation == Surface.ROTATION_90) {
+ osf.right += outset;
+ } else if (rotation == Surface.ROTATION_180) {
+ osf.top -= outset;
+ } else if (rotation == Surface.ROTATION_270) {
+ osf.left -= outset;
+ }
+ if (DEBUG_LAYOUT) Slog.v(TAG, "applying bottom outset of " + outset
+ + " with rotation " + rotation + ", result: " + osf);
+ }
+ }
+
if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()
+ ": sim=#" + Integer.toHexString(sim)
+ " attach=" + attached + " type=" + attrs.type
@@ -4030,9 +4065,10 @@
+ " of=" + of.toShortString()
+ " cf=" + cf.toShortString() + " vf=" + vf.toShortString()
+ " dcf=" + dcf.toShortString()
- + " sf=" + sf.toShortString());
+ + " sf=" + sf.toShortString()
+ + " osf=" + (osf == null ? "null" : osf.toShortString()));
- win.computeFrameLw(pf, df, of, cf, vf, dcf, sf);
+ win.computeFrameLw(pf, df, of, cf, vf, dcf, sf, osf);
// Dock windows carve out the bottom of the screen, so normal windows
// can't appear underneath them.
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 61631d4..0d5e6bc 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -47,6 +47,10 @@
// within a transaction from performTraversalInTransactionLocked.
private Surface mCurrentSurface;
+ // DEBUG STATE: Last device info which was written to the log, or null if none.
+ // Do not use for any other purpose.
+ DisplayDeviceInfo mDebugLastLoggedDeviceInfo;
+
public DisplayDevice(DisplayAdapter displayAdapter, IBinder displayToken, String uniqueId) {
mDisplayAdapter = displayAdapter;
mDisplayToken = displayToken;
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index d1e73f0..ebf6e4e 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -104,6 +104,16 @@
public static final int TOUCH_EXTERNAL = 2;
/**
+ * Diff result: The {@link #state} fields differ.
+ */
+ public static final int DIFF_STATE = 1 << 0;
+
+ /**
+ * Diff result: Other fields differ.
+ */
+ public static final int DIFF_OTHER = 1 << 1;
+
+ /**
* Gets the name of the display device, which may be derived from EDID or
* other sources. The name may be localized and displayed to the user.
*/
@@ -238,26 +248,39 @@
}
public boolean equals(DisplayDeviceInfo other) {
- return other != null
- && Objects.equal(name, other.name)
- && Objects.equal(uniqueId, other.uniqueId)
- && width == other.width
- && height == other.height
- && refreshRate == other.refreshRate
- && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
- && densityDpi == other.densityDpi
- && xDpi == other.xDpi
- && yDpi == other.yDpi
- && appVsyncOffsetNanos == other.appVsyncOffsetNanos
- && presentationDeadlineNanos == other.presentationDeadlineNanos
- && flags == other.flags
- && touch == other.touch
- && rotation == other.rotation
- && type == other.type
- && Objects.equal(address, other.address)
- && state == other.state
- && ownerUid == other.ownerUid
- && Objects.equal(ownerPackageName, other.ownerPackageName);
+ return other != null && diff(other) == 0;
+ }
+
+ /**
+ * Computes the difference between display device infos.
+ * Assumes other is not null.
+ */
+ public int diff(DisplayDeviceInfo other) {
+ int diff = 0;
+ if (state != other.state) {
+ diff |= DIFF_STATE;
+ }
+ if (!Objects.equal(name, other.name)
+ || !Objects.equal(uniqueId, other.uniqueId)
+ || width != other.width
+ || height != other.height
+ || refreshRate != other.refreshRate
+ || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
+ || densityDpi != other.densityDpi
+ || xDpi != other.xDpi
+ || yDpi != other.yDpi
+ || appVsyncOffsetNanos != other.appVsyncOffsetNanos
+ || presentationDeadlineNanos != other.presentationDeadlineNanos
+ || flags != other.flags
+ || touch != other.touch
+ || rotation != other.rotation
+ || type != other.type
+ || !Objects.equal(address, other.address)
+ || ownerUid != other.ownerUid
+ || !Objects.equal(ownerPackageName, other.ownerPackageName)) {
+ diff |= DIFF_OTHER;
+ }
+ return diff;
}
@Override
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 5f0ad9f..96ff702 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -640,13 +640,14 @@
}
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if (mDisplayDevices.contains(device)) {
- Slog.w(TAG, "Attempted to add already added display device: "
- + device.getDisplayDeviceInfoLocked());
+ Slog.w(TAG, "Attempted to add already added display device: " + info);
return;
}
- Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
+ Slog.i(TAG, "Display device added: " + info);
+ device.mDebugLastLoggedDeviceInfo = info;
mDisplayDevices.add(device);
addLogicalDisplayLocked(device);
@@ -659,13 +660,20 @@
private void handleDisplayDeviceChanged(DisplayDevice device) {
synchronized (mSyncRoot) {
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if (!mDisplayDevices.contains(device)) {
- Slog.w(TAG, "Attempted to change non-existent display device: "
- + device.getDisplayDeviceInfoLocked());
+ Slog.w(TAG, "Attempted to change non-existent display device: " + info);
return;
}
- Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
+ int diff = device.mDebugLastLoggedDeviceInfo.diff(info);
+ if (diff == DisplayDeviceInfo.DIFF_STATE) {
+ Slog.i(TAG, "Display device changed state: \"" + info.name
+ + "\", " + Display.stateToString(info.state));
+ } else if (diff != 0) {
+ Slog.i(TAG, "Display device changed: " + info);
+ }
+ device.mDebugLastLoggedDeviceInfo = info;
device.applyPendingDisplayDeviceInfoChangesLocked();
if (updateLogicalDisplaysLocked()) {
@@ -680,13 +688,14 @@
}
}
private void handleDisplayDeviceRemovedLocked(DisplayDevice device) {
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if (!mDisplayDevices.remove(device)) {
- Slog.w(TAG, "Attempted to remove non-existent display device: "
- + device.getDisplayDeviceInfoLocked());
+ Slog.w(TAG, "Attempted to remove non-existent display device: " + info);
return;
}
- Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
+ Slog.i(TAG, "Display device removed: " + info);
+ device.mDebugLastLoggedDeviceInfo = info;
updateLogicalDisplaysLocked();
scheduleTraversalLocked(false);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index a1d145c..40e6d58 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -190,14 +190,15 @@
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
- Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
+ Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Configuration
+ outConfig,
Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
- outStableInsets, outConfig, outSurface);
+ outStableInsets, outsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
@@ -536,4 +537,4 @@
public String toString() {
return mStringName;
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ad6aa75..b75622b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3012,7 +3012,7 @@
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
- Rect outVisibleInsets, Rect outStableInsets, Configuration outConfig,
+ Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
Surface outSurface) {
boolean toBeDisplayed = false;
boolean inTouchMode;
@@ -3293,6 +3293,7 @@
outContentInsets.set(win.mContentInsets);
outVisibleInsets.set(win.mVisibleInsets);
outStableInsets.set(win.mStableInsets);
+ outOutsets.set(win.mOutsets);
if (localLOGV) Slog.v(
TAG, "Relayout given client " + client.asBinder()
+ ", requestedWidth=" + requestedWidth
@@ -9456,6 +9457,7 @@
w.mLastContentInsets.set(w.mContentInsets);
w.mLastVisibleInsets.set(w.mVisibleInsets);
w.mLastStableInsets.set(w.mStableInsets);
+ w.mLastOutsets.set(w.mOutsets);
makeWindowFreezingScreenIfNeededLocked(w);
// If the orientation is changing, then we need to
// hold off on unfreezing the display until this
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index b621c52..9b3bc6c 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -179,6 +179,14 @@
boolean mStableInsetsChanged;
/**
+ * Outsets determine the area outside of the surface where we want to pretend that it's possible
+ * to draw anyway.
+ */
+ final Rect mOutsets = new Rect();
+ final Rect mLastOutsets = new Rect();
+ boolean mOutsetsChanged = false;
+
+ /**
* Set to true if we are waiting for this window to receive its
* given internal insets before laying out other windows based on it.
*/
@@ -259,6 +267,10 @@
// displays hint text.
final Rect mVisibleFrame = new Rect();
+ // Frame that includes dead area outside of the surface but where we want to pretend that it's
+ // possible to draw.
+ final Rect mOutsetFrame = new Rect();
+
boolean mContentChanged;
// If a window showing a wallpaper: the requested offset for the
@@ -517,7 +529,8 @@
}
@Override
- public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf) {
+ public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf,
+ Rect osf) {
mHaveFrame = true;
TaskStack stack = mAppToken != null ? getStack() : null;
@@ -585,6 +598,10 @@
mVisibleFrame.set(vf);
mDecorFrame.set(dcf);
mStableFrame.set(sf);
+ final boolean hasOutsets = osf != null;
+ if (hasOutsets) {
+ mOutsetFrame.set(osf);
+ }
final int fw = mFrame.width();
final int fh = mFrame.height();
@@ -647,6 +664,15 @@
Math.max(mFrame.right - mStableFrame.right, 0),
Math.max(mFrame.bottom - mStableFrame.bottom, 0));
+ if (hasOutsets) {
+ mOutsets.set(Math.max(mContentFrame.left - mOutsetFrame.left, 0),
+ Math.max(mContentFrame.top - mOutsetFrame.top, 0),
+ Math.max(mOutsetFrame.right - mContentFrame.right, 0),
+ Math.max(mOutsetFrame.bottom - mContentFrame.bottom, 0));
+ } else {
+ mOutsets.set(0, 0, 0, 0);
+ }
+
mCompatFrame.set(mFrame);
if (mEnforceSizeCompat) {
// If there is a size compatibility scale being applied to the
@@ -656,6 +682,7 @@
mContentInsets.scale(mInvGlobalScale);
mVisibleInsets.scale(mInvGlobalScale);
mStableInsets.scale(mInvGlobalScale);
+ mOutsets.scale(mInvGlobalScale);
// Also the scaled frame that we report to the app needs to be
// adjusted to be in its coordinate space.
@@ -678,7 +705,8 @@
+ "): frame=" + mFrame.toShortString()
+ " ci=" + mContentInsets.toShortString()
+ " vi=" + mVisibleInsets.toShortString()
- + " vi=" + mStableInsets.toShortString());
+ + " vi=" + mStableInsets.toShortString()
+ + " of=" + mOutsets.toShortString());
}
@Override
@@ -784,7 +812,9 @@
mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets);
mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets);
mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets);
- return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged;
+ mOutsetsChanged |= !mLastOutsets.equals(mOutsets);
+ return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged
+ || mOutsetsChanged;
}
public DisplayContent getDisplayContent() {
@@ -1329,7 +1359,7 @@
}
return displayContent.isDefaultDisplay;
}
-
+
public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) {
mShowToOwnerOnly = showToOwnerOnly;
}
@@ -1439,6 +1469,7 @@
final Rect contentInsets = mLastContentInsets;
final Rect visibleInsets = mLastVisibleInsets;
final Rect stableInsets = mLastStableInsets;
+ final Rect outsets = mLastOutsets;
final boolean reportDraw = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING;
final Configuration newConfig = configChanged ? mConfiguration : null;
if (mAttrs.type != WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
@@ -1449,7 +1480,7 @@
public void run() {
try {
mClient.resized(frame, overscanInsets, contentInsets,
- visibleInsets, stableInsets, reportDraw, newConfig);
+ visibleInsets, stableInsets, outsets, reportDraw, newConfig);
} catch (RemoteException e) {
// Not a remote call, RemoteException won't be raised.
}
@@ -1457,7 +1488,7 @@
});
} else {
mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets,
- reportDraw, newConfig);
+ outsets, reportDraw, newConfig);
}
//TODO (multidisplay): Accessibility supported only for the default display.
@@ -1470,6 +1501,7 @@
mContentInsetsChanged = false;
mVisibleInsetsChanged = false;
mStableInsetsChanged = false;
+ mOutsetsChanged = false;
mWinAnimator.mSurfaceResized = false;
} catch (RemoteException e) {
mOrientationChanging = false;
@@ -1615,17 +1647,22 @@
pw.println();
pw.print(prefix); pw.print(" decor="); mDecorFrame.printShortString(pw);
pw.println();
+ pw.print(prefix); pw.print(" outset="); mOutsetFrame.printShortString(pw);
+ pw.println();
pw.print(prefix); pw.print("Cur insets: overscan=");
mOverscanInsets.printShortString(pw);
pw.print(" content="); mContentInsets.printShortString(pw);
pw.print(" visible="); mVisibleInsets.printShortString(pw);
pw.print(" stable="); mStableInsets.printShortString(pw);
+ pw.print(" outsets="); mOutsets.printShortString(pw);
pw.println();
pw.print(prefix); pw.print("Lst insets: overscan=");
mLastOverscanInsets.printShortString(pw);
pw.print(" content="); mLastContentInsets.printShortString(pw);
pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
pw.print(" stable="); mLastStableInsets.printShortString(pw);
+ pw.print(" physical="); mLastOutsets.printShortString(pw);
+ pw.print(" outset="); mLastOutsets.printShortString(pw);
pw.println();
}
pw.print(prefix); pw.print(mWinAnimator); pw.println(":");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index f5d4867..2fe36707 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -28,6 +28,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.hardware.soundtrigger.IRecognitionStatusCallback;
import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
@@ -79,6 +80,7 @@
mResolver = context.getContentResolver();
mDbHelper = new DatabaseHelper(context);
mSoundTriggerHelper = new SoundTriggerHelper(context);
+ mServiceStub = new VoiceInteractionManagerServiceStub();
}
@Override
@@ -104,8 +106,7 @@
}
// implementation entry point and binder service
- private final VoiceInteractionManagerServiceStub mServiceStub
- = new VoiceInteractionManagerServiceStub();
+ private final VoiceInteractionManagerServiceStub mServiceStub;
class VoiceInteractionManagerServiceStub extends IVoiceInteractionManagerService.Stub {
@@ -113,6 +114,11 @@
private boolean mSafeMode;
private int mCurUser;
+ private final boolean mEnableService;
+
+ VoiceInteractionManagerServiceStub() {
+ mEnableService = shouldEnableService(mContext.getResources());
+ }
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
@@ -136,15 +142,14 @@
Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle);
ComponentName curRecognizer = getCurRecognizer(userHandle);
VoiceInteractionServiceInfo curInteractorInfo = null;
- if (curInteractorStr == null && curRecognizer != null
- && !ActivityManager.isLowRamDeviceStatic()) {
+ if (curInteractorStr == null && curRecognizer != null && mEnableService) {
// If there is no interactor setting, that means we are upgrading
// from an older platform version. If the current recognizer is not
// set or matches the preferred recognizer, then we want to upgrade
// the user to have the default voice interaction service enabled.
// Note that we don't do this for low-RAM devices, since we aren't
// supporting voice interaction services there.
- curInteractorInfo = findAvailInteractor(userHandle, curRecognizer);
+ curInteractorInfo = findAvailInteractor(userHandle, curRecognizer.getPackageName());
if (curInteractorInfo != null) {
// Looks good! We'll apply this one. To make it happen, we clear the
// recognizer so that we don't think we have anything set and will
@@ -153,9 +158,21 @@
}
}
+ // If forceInteractorPackage exists, try to apply the interactor from this package if
+ // possible and ignore the regular interactor setting.
+ String forceInteractorPackage =
+ getForceVoiceInteractionServicePackage(mContext.getResources());
+ if (forceInteractorPackage != null) {
+ curInteractorInfo = findAvailInteractor(userHandle, forceInteractorPackage);
+ if (curInteractorInfo != null) {
+ // We'll apply this one. Clear the recognizer and re-apply the settings.
+ curRecognizer = null;
+ }
+ }
+
// If we are on a svelte device, make sure an interactor is not currently
// enabled; if it is, turn it off.
- if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) {
+ if (!mEnableService && curInteractorStr != null) {
if (!TextUtils.isEmpty(curInteractorStr)) {
setCurInteractor(null, userHandle);
curInteractorStr = "";
@@ -184,7 +201,7 @@
}
// Initializing settings, look for an interactor first (but only on non-svelte).
- if (curInteractorInfo == null && !ActivityManager.isLowRamDeviceStatic()) {
+ if (curInteractorInfo == null && mEnableService) {
curInteractorInfo = findAvailInteractor(userHandle, null);
}
@@ -210,6 +227,18 @@
}
}
+ private boolean shouldEnableService(Resources res) {
+ // VoiceInteractionService should not be enabled on low ram devices unless it has the config flag.
+ return !ActivityManager.isLowRamDeviceStatic() ||
+ getForceVoiceInteractionServicePackage(res) != null;
+ }
+
+ private String getForceVoiceInteractionServicePackage(Resources res) {
+ String interactorPackage =
+ res.getString(com.android.internal.R.string.config_forceVoiceInteractionServicePackage);
+ return TextUtils.isEmpty(interactorPackage) ? null : interactorPackage;
+ }
+
public void systemRunning(boolean safeMode) {
mSafeMode = safeMode;
@@ -260,7 +289,7 @@
}
}
- VoiceInteractionServiceInfo findAvailInteractor(int userHandle, ComponentName recognizer) {
+ VoiceInteractionServiceInfo findAvailInteractor(int userHandle, String packageName) {
List<ResolveInfo> available =
mContext.getPackageManager().queryIntentServicesAsUser(
new Intent(VoiceInteractionService.SERVICE_INTERFACE), 0, userHandle);
@@ -281,8 +310,8 @@
VoiceInteractionServiceInfo info = new VoiceInteractionServiceInfo(
mContext.getPackageManager(), comp, userHandle);
if (info.getParseError() == null) {
- if (recognizer == null || info.getServiceInfo().packageName.equals(
- recognizer.getPackageName())) {
+ if (packageName == null || info.getServiceInfo().packageName.equals(
+ packageName)) {
if (foundInfo == null) {
foundInfo = info;
} else {
@@ -659,6 +688,7 @@
}
synchronized (this) {
pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+ pw.println(" mEnableService: " + mEnableService);
if (mImpl == null) {
pw.println(" (No active implementation)");
return;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 4c4454d..fb5d44f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -47,8 +47,8 @@
}
@Override
- public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, boolean b,
- Configuration configuration) throws RemoteException {
+ public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6,
+ boolean b, Configuration configuration) throws RemoteException {
// pass for now.
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index 25f7078..8575839 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -89,7 +89,7 @@
@Override
public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2,
int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5,
- Configuration configuration, Surface surface) throws RemoteException {
+ Rect rect6, Configuration configuration, Surface surface) throws RemoteException {
// pass for now.
return 0;
}