diff options
21 files changed, 460 insertions, 170 deletions
diff --git a/api/current.txt b/api/current.txt index d11d70c..e4f31b0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -20716,6 +20716,7 @@ package android.provider { field public static final java.lang.String ACTION_MEMORY_CARD_SETTINGS = "android.settings.MEMORY_CARD_SETTINGS"; field public static final java.lang.String ACTION_NETWORK_OPERATOR_SETTINGS = "android.settings.NETWORK_OPERATOR_SETTINGS"; field public static final java.lang.String ACTION_NFCSHARING_SETTINGS = "android.settings.NFCSHARING_SETTINGS"; + field public static final java.lang.String ACTION_NFC_PAYMENT_SETTINGS = "android.settings.NFC_PAYMENT_SETTINGS"; field public static final java.lang.String ACTION_NFC_SETTINGS = "android.settings.NFC_SETTINGS"; field public static final java.lang.String ACTION_PRIVACY_SETTINGS = "android.settings.PRIVACY_SETTINGS"; field public static final java.lang.String ACTION_QUICK_LAUNCH_SETTINGS = "android.settings.QUICK_LAUNCH_SETTINGS"; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 17e8dd9..be831d7 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -1527,9 +1527,26 @@ public class DevicePolicyManager { */ public boolean setDeviceOwner(String packageName) throws IllegalArgumentException, IllegalStateException { + return setDeviceOwner(packageName, null); + } + + /** + * @hide + * Sets the given package as the device owner. The package must already be installed and there + * shouldn't be an existing device owner registered, for this call to succeed. Also, this + * method must be called before the device is provisioned. + * @param packageName the package name of the application to be registered as the device owner. + * @param ownerName the human readable name of the institution that owns this device. + * @return whether the package was successfully registered as the device owner. + * @throws IllegalArgumentException if the package name is null or invalid + * @throws IllegalStateException if a device owner is already registered or the device has + * already been provisioned. + */ + public boolean setDeviceOwner(String packageName, String ownerName) + throws IllegalArgumentException, IllegalStateException { if (mService != null) { try { - return mService.setDeviceOwner(packageName); + return mService.setDeviceOwner(packageName, ownerName); } catch (RemoteException re) { Log.w(TAG, "Failed to set device owner"); } @@ -1581,4 +1598,16 @@ public class DevicePolicyManager { } return null; } + + /** @hide */ + public String getDeviceOwnerName() { + if (mService != null) { + try { + return mService.getDeviceOwnerName(); + } catch (RemoteException re) { + Log.w(TAG, "Failed to get device owner"); + } + } + return null; + } } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index b2a65bf..9659a91 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -98,7 +98,8 @@ interface IDevicePolicyManager { void reportFailedPasswordAttempt(int userHandle); void reportSuccessfulPasswordAttempt(int userHandle); - boolean setDeviceOwner(String packageName); + boolean setDeviceOwner(String packageName, String ownerName); boolean isDeviceOwner(String packageName); String getDeviceOwner(); + String getDeviceOwnerName(); } diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java index ffa7d7e..3f7e3ef 100644 --- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -188,7 +188,8 @@ public final class ApduServiceInfo implements Parcelable { currentGroup != null) { final TypedArray a = res.obtainAttributes(attrs, com.android.internal.R.styleable.AidFilter); - String aid = a.getString(com.android.internal.R.styleable.AidFilter_name); + String aid = a.getString(com.android.internal.R.styleable.AidFilter_name). + toUpperCase(); if (isValidAid(aid) && !currentGroup.aids.contains(aid)) { currentGroup.aids.add(aid); mAids.add(aid); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 4865fd0..585115a 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -644,6 +644,23 @@ public final class Settings { "android.settings.NFCSHARING_SETTINGS"; /** + * Activity Action: Show NFC Tap & Pay settings + * <p> + * This shows UI that allows the user to configure Tap&Pay + * settings. + * <p> + * In some cases, a matching Activity may not exist, so ensure you + * safeguard against this. + * <p> + * Input: Nothing. + * <p> + * Output: Nothing + */ + @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) + public static final String ACTION_NFC_PAYMENT_SETTINGS = + "android.settings.NFC_PAYMENT_SETTINGS"; + + /** * Activity Action: Show Daydream settings. * <p> * In some cases, a matching Activity may not exist, so ensure you diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 20938f5..3dff1b0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12062,7 +12062,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Resolve padding depending on layout direction. + * Resolves padding depending on layout direction, if applicable, and + * recomputes internal padding values to adjust for scroll bars. * * @hide */ @@ -12102,11 +12103,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom; - internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, - mUserPaddingBottom); onRtlPropertiesChanged(resolvedLayoutDirection); } + internalSetPadding(mUserPaddingLeft, mPaddingTop, mUserPaddingRight, mUserPaddingBottom); + mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED; } @@ -14659,13 +14660,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ protected void resolveDrawables() { - if (canResolveLayoutDirection()) { - if (mBackground != null) { - mBackground.setLayoutDirection(getLayoutDirection()); - } - mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED; - onResolveDrawables(getLayoutDirection()); + // Drawables resolution may need to happen before resolving the layout direction (which is + // done only during the measure() call). + // If the layout direction is not resolved yet, we cannot resolve the Drawables except in + // one case: when the raw layout direction has not been defined as LAYOUT_DIRECTION_INHERIT. + // So, if the raw layout direction is LAYOUT_DIRECTION_LTR or LAYOUT_DIRECTION_RTL or + // LAYOUT_DIRECTION_LOCALE, we can "cheat" and we don't need to wait for the layout + // direction to be resolved as its resolved value will be the same as its raw value. + if (!isLayoutDirectionResolved() && + getRawLayoutDirection() == View.LAYOUT_DIRECTION_INHERIT) { + return; + } + + final int layoutDirection = isLayoutDirectionResolved() ? + getLayoutDirection() : getRawLayoutDirection(); + + if (mBackground != null) { + mBackground.setLayoutDirection(layoutDirection); } + mPrivateFlags2 |= PFLAG2_DRAWABLE_RESOLVED; + onResolveDrawables(layoutDirection); } /** diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 3f391ad..0ed846b 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -1243,6 +1243,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mFastScroller = new FastScroller(this); mFastScroller.setEnabled(true); } + + recomputePadding(); + + if (mFastScroller != null) { + mFastScroller.updateLayout(); + } } /** @@ -1303,7 +1309,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public int getVerticalScrollbarWidth() { - if (isFastScrollAlwaysVisible() && mFastScroller != null) { + if (mFastScroller != null && mFastScroller.isEnabled()) { return Math.max(super.getVerticalScrollbarWidth(), mFastScroller.getWidth()); } return super.getVerticalScrollbarWidth(); @@ -1327,6 +1333,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } + @Override + public void setScrollBarStyle(int style) { + super.setScrollBarStyle(style); + if (mFastScroller != null) { + mFastScroller.setScrollBarStyle(style); + } + } + /** * If fast scroll is enabled, then don't draw the vertical scrollbar. * @hide @@ -2787,7 +2801,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te @Override public void onRtlPropertiesChanged(int layoutDirection) { super.onRtlPropertiesChanged(layoutDirection); - if (mFastScroller != null) { mFastScroller.setScrollbarPosition(getVerticalScrollbarPosition()); } diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java index 393720f..c48955f 100644 --- a/core/java/android/widget/FastScroller.java +++ b/core/java/android/widget/FastScroller.java @@ -131,6 +131,9 @@ class FastScroller { /** Whether there is a track image to display. */ private final boolean mHasTrackImage; + /** Total width of decorations. */ + private final int mWidth; + /** Set containing decoration transition animations. */ private AnimatorSet mDecorAnimation; @@ -155,6 +158,9 @@ class FastScroller { /** The index of the current section. */ private int mCurrentSection = -1; + /** The current scrollbar position. */ + private int mScrollbarPosition = -1; + /** Whether the list is long enough to need a fast scroller. */ private boolean mLongList; @@ -194,6 +200,9 @@ class FastScroller { */ private int mOverlayPosition; + /** Current scrollbar style, including inset and overlay properties. */ + private int mScrollBarStyle; + /** Whether to precisely match the thumb position to the list. */ private boolean mMatchDragPosition; @@ -245,34 +254,44 @@ class FastScroller { final Resources res = context.getResources(); final TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS); - mTrackImage = new ImageView(context); + final ImageView trackImage = new ImageView(context); + mTrackImage = trackImage; + + int width = 0; // Add track to overlay if it has an image. - final int trackResId = ta.getResourceId(TRACK_DRAWABLE, 0); - if (trackResId != 0) { + final Drawable trackDrawable = ta.getDrawable(TRACK_DRAWABLE); + if (trackDrawable != null) { mHasTrackImage = true; - mTrackImage.setBackgroundResource(trackResId); - mOverlay.add(mTrackImage); + trackImage.setBackground(trackDrawable); + mOverlay.add(trackImage); + width = Math.max(width, trackDrawable.getIntrinsicWidth()); } else { mHasTrackImage = false; } - mThumbImage = new ImageView(context); + final ImageView thumbImage = new ImageView(context); + mThumbImage = thumbImage; // Add thumb to overlay if it has an image. final Drawable thumbDrawable = ta.getDrawable(THUMB_DRAWABLE); if (thumbDrawable != null) { - mThumbImage.setImageDrawable(thumbDrawable); - mOverlay.add(mThumbImage); + thumbImage.setImageDrawable(thumbDrawable); + mOverlay.add(thumbImage); + width = Math.max(width, thumbDrawable.getIntrinsicWidth()); } // If necessary, apply minimum thumb width and height. if (thumbDrawable.getIntrinsicWidth() <= 0 || thumbDrawable.getIntrinsicHeight() <= 0) { - mThumbImage.setMinimumWidth(res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width)); - mThumbImage.setMinimumHeight( + final int minWidth = res.getDimensionPixelSize(R.dimen.fastscroll_thumb_width); + thumbImage.setMinimumWidth(minWidth); + thumbImage.setMinimumHeight( res.getDimensionPixelSize(R.dimen.fastscroll_thumb_height)); + width = Math.max(width, minWidth); } + mWidth = width; + final int previewSize = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_size); mPreviewImage = new ImageView(context); mPreviewImage.setMinimumWidth(previewSize); @@ -297,10 +316,11 @@ class FastScroller { mOverlayPosition = ta.getInt(OVERLAY_POSITION, OVERLAY_FLOATING); ta.recycle(); + mScrollBarStyle = listView.getScrollBarStyle(); mScrollCompleted = true; mState = STATE_VISIBLE; - mMatchDragPosition = - context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB; + mMatchDragPosition = context.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.HONEYCOMB; getSectionsFromIndexer(); refreshDrawablePressedState(); @@ -362,6 +382,14 @@ class FastScroller { return mAlwaysShow; } + public void setScrollBarStyle(int style) { + if (mScrollBarStyle != style) { + mScrollBarStyle = style; + + updateLayout(); + } + } + /** * Immediately transitions the fast scroller decorations to a hidden state. */ @@ -375,25 +403,29 @@ class FastScroller { View.SCROLLBAR_POSITION_LEFT : View.SCROLLBAR_POSITION_RIGHT; } - mLayoutFromRight = position != View.SCROLLBAR_POSITION_LEFT; + if (mScrollbarPosition != position) { + mScrollbarPosition = position; + mLayoutFromRight = position != View.SCROLLBAR_POSITION_LEFT; - final int previewResId = mPreviewResId[mLayoutFromRight ? PREVIEW_RIGHT : PREVIEW_LEFT]; - mPreviewImage.setBackgroundResource(previewResId); + final int previewResId = mPreviewResId[mLayoutFromRight ? PREVIEW_RIGHT : PREVIEW_LEFT]; + mPreviewImage.setBackgroundResource(previewResId); - // Add extra padding for text. - final Drawable background = mPreviewImage.getBackground(); - if (background != null) { - final Rect padding = mTempBounds; - background.getPadding(padding); - padding.offset(mPreviewPadding, mPreviewPadding); - mPreviewImage.setPadding(padding.left, padding.top, padding.right, padding.bottom); - } + // Add extra padding for text. + final Drawable background = mPreviewImage.getBackground(); + if (background != null) { + final Rect padding = mTempBounds; + background.getPadding(padding); + padding.offset(mPreviewPadding, mPreviewPadding); + mPreviewImage.setPadding(padding.left, padding.top, padding.right, padding.bottom); + } - updateLayout(); + // Requires re-layout. + updateLayout(); + } } public int getWidth() { - return mThumbImage.getWidth(); + return mWidth; } public void onSizeChanged(int w, int h, int oldw, int oldh) { @@ -437,7 +469,7 @@ class FastScroller { /** * Measures and layouts the scrollbar and decorations. */ - private void updateLayout() { + public void updateLayout() { // Prevent re-entry when RTL properties change as a side-effect of // resolving padding. if (mUpdatingLayout) { @@ -594,21 +626,36 @@ class FastScroller { out.set(left, top, right, bottom); } + /** + * Updates the container rectangle used for layout. + */ private void updateContainerRect() { final AbsListView list = mList; + list.resolvePadding(); + final Rect container = mContainerRect; container.left = 0; container.top = 0; container.right = list.getWidth(); container.bottom = list.getHeight(); - final int scrollbarStyle = list.getScrollBarStyle(); + final int scrollbarStyle = mScrollBarStyle; if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET || scrollbarStyle == View.SCROLLBARS_INSIDE_OVERLAY) { container.left += list.getPaddingLeft(); container.top += list.getPaddingTop(); container.right -= list.getPaddingRight(); container.bottom -= list.getPaddingBottom(); + + // In inset mode, we need to adjust for padded scrollbar width. + if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET) { + final int width = getWidth(); + if (mScrollbarPosition == View.SCROLLBAR_POSITION_RIGHT) { + container.right += width; + } else { + container.left -= width; + } + } } } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3181164..9c21f0d 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1378,6 +1378,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } else { dr.mDrawableSizeEnd = dr.mDrawableHeightEnd = 0; } + resetResolvedDrawables(); + resolveDrawables(); } } diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java index 39c23cf..7eadbb5 100644 --- a/core/java/com/android/internal/app/ProcessStats.java +++ b/core/java/com/android/internal/app/ProcessStats.java @@ -31,6 +31,8 @@ import android.webkit.WebViewFactory; import com.android.internal.util.ArrayUtils; import dalvik.system.VMRuntime; +import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; @@ -212,6 +214,80 @@ public final class ProcessStats implements Parcelable { readFromParcel(in); } + public void add(ProcessStats other) { + ArrayMap<String, SparseArray<PackageState>> pkgMap = other.mPackages.getMap(); + for (int ip=0; ip<pkgMap.size(); ip++) { + String pkgName = pkgMap.keyAt(ip); + SparseArray<PackageState> uids = pkgMap.valueAt(ip); + for (int iu=0; iu<uids.size(); iu++) { + int uid = uids.keyAt(iu); + PackageState otherState = uids.valueAt(iu); + final int NPROCS = otherState.mProcesses.size(); + final int NSRVS = otherState.mServices.size(); + for (int iproc=0; iproc<NPROCS; iproc++) { + ProcessState otherProc = otherState.mProcesses.valueAt(iproc); + if (otherProc.mCommonProcess != otherProc) { + if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid + + " proc " + otherProc.mName); + ProcessState thisProc = getProcessStateLocked(pkgName, uid, + otherProc.mName); + if (thisProc.mCommonProcess == thisProc) { + if (DEBUG) Slog.d(TAG, "Existing process is single-package, splitting"); + thisProc.mMultiPackage = true; + long now = SystemClock.uptimeMillis(); + final PackageState pkgState = getPackageStateLocked(pkgName, uid); + thisProc = thisProc.clone(thisProc.mPackage, now); + pkgState.mProcesses.put(thisProc.mName, thisProc); + } + thisProc.add(otherProc); + } + } + for (int isvc=0; isvc<NSRVS; isvc++) { + ServiceState otherSvc = otherState.mServices.valueAt(isvc); + if (DEBUG) Slog.d(TAG, "Adding pkg " + pkgName + " uid " + uid + + " service " + otherSvc.mName); + ServiceState thisSvc = getServiceStateLocked(pkgName, uid, + null, otherSvc.mName); + thisSvc.add(otherSvc); + } + } + } + + ArrayMap<String, SparseArray<ProcessState>> procMap = other.mProcesses.getMap(); + for (int ip=0; ip<procMap.size(); ip++) { + SparseArray<ProcessState> uids = procMap.valueAt(ip); + for (int iu=0; iu<uids.size(); iu++) { + int uid = uids.keyAt(iu); + ProcessState otherProc = uids.valueAt(iu); + ProcessState thisProc = mProcesses.get(otherProc.mName, uid); + if (DEBUG) Slog.d(TAG, "Adding uid " + uid + " proc " + otherProc.mName); + if (thisProc == null) { + if (DEBUG) Slog.d(TAG, "Creating new process!"); + thisProc = new ProcessState(this, otherProc.mPackage, uid, otherProc.mName); + mProcesses.put(otherProc.mName, uid, thisProc); + PackageState thisState = getPackageStateLocked(otherProc.mPackage, uid); + if (!thisState.mProcesses.containsKey(otherProc.mName)) { + thisState.mProcesses.put(otherProc.mName, thisProc); + } + } + thisProc.add(otherProc); + } + } + + for (int i=0; i<ADJ_COUNT; i++) { + if (DEBUG) Slog.d(TAG, "Total duration #" + i + " inc by " + + other.mMemFactorDurations[i] + " from " + + mMemFactorDurations[i]); + mMemFactorDurations[i] += other.mMemFactorDurations[i]; + } + + if (other.mTimePeriodStartClock < mTimePeriodStartClock) { + mTimePeriodStartClock = other.mTimePeriodStartClock; + mTimePeriodStartClockStr = other.mTimePeriodStartClockStr; + } + mTimePeriodEndRealtime += other.mTimePeriodEndRealtime - other.mTimePeriodStartRealtime; + } + public static final Parcelable.Creator<ProcessStats> CREATOR = new Parcelable.Creator<ProcessStats>() { public ProcessStats createFromParcel(Parcel in) { @@ -1098,6 +1174,43 @@ public final class ProcessStats implements Parcelable { return true; } + static byte[] readFully(InputStream stream) throws IOException { + int pos = 0; + int avail = stream.available(); + byte[] data = new byte[avail]; + while (true) { + int amt = stream.read(data, pos, data.length-pos); + //Log.i("foo", "Read " + amt + " bytes at " + pos + // + " of avail " + data.length); + if (amt <= 0) { + //Log.i("foo", "**** FINISHED READING: pos=" + pos + // + " len=" + data.length); + return data; + } + pos += amt; + avail = stream.available(); + if (avail > data.length-pos) { + byte[] newData = new byte[pos+avail]; + System.arraycopy(data, 0, newData, 0, pos); + data = newData; + } + } + } + + public void read(InputStream stream) { + try { + byte[] raw = readFully(stream); + Parcel in = Parcel.obtain(); + in.unmarshall(raw, 0, raw.length); + in.setDataPosition(0); + stream.close(); + + readFromParcel(in); + } catch (IOException e) { + mReadError = "caught exception: " + e; + } + } + public void readFromParcel(Parcel in) { final boolean hadData = mPackages.getMap().size() > 0 || mProcesses.getMap().size() > 0; @@ -1289,7 +1402,7 @@ public final class ProcessStats implements Parcelable { } ServiceState serv = hadData ? pkgState.mServices.get(serviceName) : null; if (serv == null) { - serv = new ServiceState(this, pkgName, null); + serv = new ServiceState(this, pkgName, serviceName, null); } if (!serv.readFromParcel(in)) { return; @@ -1437,6 +1550,21 @@ public final class ProcessStats implements Parcelable { return ps; } + public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid, + String processName, String className) { + final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid); + ProcessStats.ServiceState ss = as.mServices.get(className); + if (ss != null) { + ss.makeActive(); + return ss; + } + final ProcessStats.ProcessState ps = processName != null + ? getProcessStateLocked(packageName, uid, processName) : null; + ss = new ProcessStats.ServiceState(this, packageName, className, ps); + as.mServices.put(className, ss); + return ss; + } + public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpAll) { long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor, mStartTime, now); @@ -1947,6 +2075,29 @@ public final class ProcessStats implements Parcelable { return pnew; } + void add(ProcessState other) { + for (int i=0; i<other.mDurationsTableSize; i++) { + int ent = other.mDurationsTable[i]; + int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK; + if (DEBUG) Slog.d(TAG, "Adding state " + state + " duration " + + other.mStats.getLong(ent, 0)); + addDuration(state, other.mStats.getLong(ent, 0)); + } + for (int i=0; i<other.mPssTableSize; i++) { + int ent = other.mPssTable[i]; + int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK; + addPss(state, (int) other.mStats.getLong(ent, PSS_SAMPLE_COUNT), + other.mStats.getLong(ent, PSS_MINIMUM), + other.mStats.getLong(ent, PSS_AVERAGE), + other.mStats.getLong(ent, PSS_MAXIMUM), + other.mStats.getLong(ent, PSS_USS_MINIMUM), + other.mStats.getLong(ent, PSS_USS_AVERAGE), + other.mStats.getLong(ent, PSS_USS_MAXIMUM)); + } + mNumExcessiveWake += other.mNumExcessiveWake; + mNumExcessiveCpu += other.mNumExcessiveCpu; + } + void resetSafely(long now) { mDurationsTable = null; mDurationsTableSize = 0; @@ -2043,24 +2194,30 @@ public final class ProcessStats implements Parcelable { if (mCurState != STATE_NOTHING) { long dur = now - mStartTime; if (dur > 0) { - int idx = binarySearch(mDurationsTable, mDurationsTableSize, mCurState); - int off; - if (idx >= 0) { - off = mDurationsTable[idx]; - } else { - mStats.mAddLongTable = mDurationsTable; - mStats.mAddLongTableSize = mDurationsTableSize; - off = mStats.addLongData(~idx, mCurState, 1); - mDurationsTable = mStats.mAddLongTable; - mDurationsTableSize = mStats.mAddLongTableSize; - } - long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK); - longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur; + addDuration(mCurState, dur); } } mStartTime = now; } + void addDuration(int state, long dur) { + int idx = binarySearch(mDurationsTable, mDurationsTableSize, state); + int off; + if (idx >= 0) { + off = mDurationsTable[idx]; + } else { + mStats.mAddLongTable = mDurationsTable; + mStats.mAddLongTableSize = mDurationsTableSize; + off = mStats.addLongData(~idx, state, 1); + mDurationsTable = mStats.mAddLongTable; + mDurationsTableSize = mStats.mAddLongTableSize; + } + long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK); + if (DEBUG) Slog.d(TAG, "Duration of " + mName + " state " + state + " inc by " + dur + + " from " + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK]); + longs[(off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK] += dur; + } + void incStartedServices(int memFactor, long now) { if (mCommonProcess != this) { mCommonProcess.incStartedServices(memFactor, now); @@ -2094,46 +2251,53 @@ public final class ProcessStats implements Parcelable { mLastPssState = mCurState; mLastPssTime = SystemClock.uptimeMillis(); if (mCurState != STATE_NOTHING) { - int idx = binarySearch(mPssTable, mPssTableSize, mCurState); - int off; - if (idx >= 0) { - off = mPssTable[idx]; - } else { - mStats.mAddLongTable = mPssTable; - mStats.mAddLongTableSize = mPssTableSize; - off = mStats.addLongData(~idx, mCurState, PSS_COUNT); - mPssTable = mStats.mAddLongTable; - mPssTableSize = mStats.mAddLongTableSize; + addPss(mCurState, 1, pss, pss, pss, uss, uss, uss); + } + } + + void addPss(int state, int inCount, long minPss, long avgPss, long maxPss, long minUss, + long avgUss, long maxUss) { + int idx = binarySearch(mPssTable, mPssTableSize, state); + int off; + if (idx >= 0) { + off = mPssTable[idx]; + } else { + mStats.mAddLongTable = mPssTable; + mStats.mAddLongTableSize = mPssTableSize; + off = mStats.addLongData(~idx, state, PSS_COUNT); + mPssTable = mStats.mAddLongTable; + mPssTableSize = mStats.mAddLongTableSize; + } + long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK); + idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK; + long count = longs[idx+PSS_SAMPLE_COUNT]; + if (count == 0) { + longs[idx+PSS_SAMPLE_COUNT] = inCount; + longs[idx+PSS_MINIMUM] = minPss; + longs[idx+PSS_AVERAGE] = avgPss; + longs[idx+PSS_MAXIMUM] = maxPss; + longs[idx+PSS_USS_MINIMUM] = minUss; + longs[idx+PSS_USS_AVERAGE] = avgUss; + longs[idx+PSS_USS_MAXIMUM] = maxUss; + } else { + longs[idx+PSS_SAMPLE_COUNT] = count+inCount; + if (longs[idx+PSS_MINIMUM] > minPss) { + longs[idx+PSS_MINIMUM] = minPss; } - long[] longs = mStats.mLongs.get((off>>OFFSET_ARRAY_SHIFT)&OFFSET_ARRAY_MASK); - idx = (off>>OFFSET_INDEX_SHIFT)&OFFSET_INDEX_MASK; - long count = longs[idx+PSS_SAMPLE_COUNT]; - if (count == 0) { - longs[idx+PSS_SAMPLE_COUNT] = 1; - longs[idx+PSS_MINIMUM] = pss; - longs[idx+PSS_AVERAGE] = pss; - longs[idx+PSS_MAXIMUM] = pss; - longs[idx+PSS_USS_MINIMUM] = uss; - longs[idx+PSS_USS_AVERAGE] = uss; - longs[idx+PSS_USS_MAXIMUM] = uss; - } else { - longs[idx+PSS_SAMPLE_COUNT] = count+1; - if (longs[idx+PSS_MINIMUM] > pss) { - longs[idx+PSS_MINIMUM] = pss; - } - longs[idx+PSS_AVERAGE] = (long)( - ((longs[idx+PSS_AVERAGE]*(double)count)+pss) / (count+1) ); - if (longs[idx+PSS_MAXIMUM] < pss) { - longs[idx+PSS_MAXIMUM] = pss; - } - if (longs[idx+PSS_USS_MINIMUM] > uss) { - longs[idx+PSS_USS_MINIMUM] = uss; - } - longs[idx+PSS_USS_AVERAGE] = (long)( - ((longs[idx+PSS_USS_AVERAGE]*(double)count)+uss) / (count+1) ); - if (longs[idx+PSS_USS_MAXIMUM] < uss) { - longs[idx+PSS_USS_MAXIMUM] = uss; - } + longs[idx+PSS_AVERAGE] = (long)( + ((longs[idx+PSS_AVERAGE]*(double)count)+(avgPss*(double)inCount)) + / (count+inCount) ); + if (longs[idx+PSS_MAXIMUM] < maxPss) { + longs[idx+PSS_MAXIMUM] = maxPss; + } + if (longs[idx+PSS_USS_MINIMUM] > minUss) { + longs[idx+PSS_USS_MINIMUM] = minUss; + } + longs[idx+PSS_USS_AVERAGE] = (long)( + ((longs[idx+PSS_USS_AVERAGE]*(double)count)+(avgUss*(double)inCount)) + / (count+inCount) ); + if (longs[idx+PSS_USS_MAXIMUM] < maxUss) { + longs[idx+PSS_USS_MAXIMUM] = maxUss; } } } @@ -2240,6 +2404,7 @@ public final class ProcessStats implements Parcelable { public static final class ServiceState { final ProcessStats mStats; final String mPackage; + final String mName; ProcessState mProc; int mActive = 1; @@ -2264,9 +2429,10 @@ public final class ProcessStats implements Parcelable { public int mExecState = STATE_NOTHING; long mExecStartTime; - public ServiceState(ProcessStats processStats, String pkg, ProcessState proc) { + public ServiceState(ProcessStats processStats, String pkg, String name, ProcessState proc) { mStats = processStats; mPackage = pkg; + mName = name; mProc = proc; } @@ -2287,6 +2453,17 @@ public final class ProcessStats implements Parcelable { return mActive > 0; } + void add(ServiceState other) { + for (int i=0; i<other.mDurationsTableSize; i++) { + int ent = other.mDurationsTable[i]; + int state = (ent>>OFFSET_TYPE_SHIFT)&OFFSET_TYPE_MASK; + addStateTime(state, other.mStats.getLong(ent, 0)); + } + mStartedCount += other.mStartedCount; + mBoundCount += other.mBoundCount; + mExecCount += other.mExecCount; + } + void resetSafely(long now) { mDurationsTable = null; mDurationsTableSize = 0; @@ -2321,9 +2498,8 @@ public final class ProcessStats implements Parcelable { return true; } - void addStateTime(int opType, int memFactor, long time) { + void addStateTime(int state, long time) { if (time > 0) { - int state = opType + (memFactor*SERVICE_COUNT); int idx = binarySearch(mDurationsTable, mDurationsTableSize, state); int off; if (idx >= 0) { @@ -2342,15 +2518,16 @@ public final class ProcessStats implements Parcelable { void commitStateTime(long now) { if (mStartedState != STATE_NOTHING) { - addStateTime(SERVICE_STARTED, mStartedState, now - mStartedStartTime); + addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT), + now - mStartedStartTime); mStartedStartTime = now; } if (mBoundState != STATE_NOTHING) { - addStateTime(SERVICE_BOUND, mBoundState, now - mBoundStartTime); + addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), now - mBoundStartTime); mBoundStartTime = now; } if (mExecState != STATE_NOTHING) { - addStateTime(SERVICE_EXEC, mExecState, now - mExecStartTime); + addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime); mExecStartTime = now; } } @@ -2362,7 +2539,8 @@ public final class ProcessStats implements Parcelable { int state = started ? memFactor : STATE_NOTHING; if (mStartedState != state) { if (mStartedState != STATE_NOTHING) { - addStateTime(SERVICE_STARTED, mStartedState, now - mStartedStartTime); + addStateTime(SERVICE_STARTED + (mStartedState*SERVICE_COUNT), + now - mStartedStartTime); } else if (started) { mStartedCount++; } @@ -2386,7 +2564,8 @@ public final class ProcessStats implements Parcelable { int state = bound ? memFactor : STATE_NOTHING; if (mBoundState != state) { if (mBoundState != STATE_NOTHING) { - addStateTime(SERVICE_BOUND, mBoundState, now - mBoundStartTime); + addStateTime(SERVICE_BOUND + (mBoundState*SERVICE_COUNT), + now - mBoundStartTime); } else if (bound) { mBoundCount++; } @@ -2402,7 +2581,7 @@ public final class ProcessStats implements Parcelable { int state = executing ? memFactor : STATE_NOTHING; if (mExecState != state) { if (mExecState != STATE_NOTHING) { - addStateTime(SERVICE_EXEC, mExecState, now - mExecStartTime); + addStateTime(SERVICE_EXEC + (mExecState*SERVICE_COUNT), now - mExecStartTime); } else if (executing) { mExecCount++; } diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 2c482ea..bacfdf6 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -18,6 +18,9 @@ #include <stdio.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + #include <gui/GLConsumer.h> #include <gui/Surface.h> diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index 61ace4a..f5eb389 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -220,6 +220,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } else { whichHeap = HEAP_ASHMEM; } + } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) { + whichHeap = HEAP_NATIVE; } else if (strncmp(name, "[stack", 6) == 0) { whichHeap = HEAP_STACK; } else if (strncmp(name, "/dev/", 5) == 0) { @@ -246,6 +248,8 @@ static void read_mapinfo(FILE *fp, stats_t* stats) } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { whichHeap = HEAP_ART; is_swappable = true; + } else if (strncmp(name, "[anon:", 6) == 0) { + whichHeap = HEAP_UNKNOWN; } else if (nameLen > 0) { whichHeap = HEAP_UNKNOWN_MAP; } else if (start == prevEnd && prevHeap == HEAP_SO) { diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 1cdc6f5..0ea4074 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -114,9 +114,13 @@ public class Canvas { * canvas. */ public Canvas() { - // 0 means no native bitmap - mNativeCanvas = initRaster(0); - mFinalizer = new CanvasFinalizer(mNativeCanvas); + if (!isHardwareAccelerated()) { + // 0 means no native bitmap + mNativeCanvas = initRaster(0); + mFinalizer = new CanvasFinalizer(mNativeCanvas); + } else { + mFinalizer = null; + } } /** diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 331cf6e..69d9916 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -431,6 +431,8 @@ public class Paint { mRasterizer = paint.mRasterizer; if (paint.mShader != null) { mShader = paint.mShader.copy(); + } else { + mShader = null; } mTypeface = paint.mTypeface; mXfermode = paint.mXfermode; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index d1bae1e..707f662 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1112,8 +1112,6 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); - - finishDrawTexture(); } void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) { @@ -1256,8 +1254,6 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { GL_UNSIGNED_SHORT, NULL)); } - finishDrawTexture(); - #if DEBUG_LAYERS_AS_REGIONS drawRegionRects(layer->region); #endif @@ -2021,9 +2017,6 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { mCaches.bindPositionVertexPointer(force, vertices, gVertexStride); } -void OpenGLRenderer::finishDrawTexture() { -} - /////////////////////////////////////////////////////////////////////////////// // Drawing /////////////////////////////////////////////////////////////////////////////// @@ -2308,8 +2301,6 @@ status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int mes glDrawArrays(GL_TRIANGLES, 0, count); - finishDrawTexture(); - int slot = mCaches.currentProgram->getAttrib("colors"); if (slot >= 0) { glDisableVertexAttribArray(slot); @@ -3134,8 +3125,6 @@ status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { mesh += (drawCount / 6) * 4; } - finishDrawTexture(); - #if DEBUG_LAYERS_AS_REGIONS drawRegionRects(layer->region); #endif @@ -3270,8 +3259,6 @@ void OpenGLRenderer::drawPathTexture(const PathTexture* texture, setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset); glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount); - - finishDrawTexture(); } // Same values used by Skia @@ -3488,8 +3475,6 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b setupDrawMesh(vertices, texCoords, vbo); glDrawArrays(drawMode, 0, elementsCount); - - finishDrawTexture(); } void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom, @@ -3515,8 +3500,6 @@ void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, setupDrawMeshIndices(vertices, texCoords, vbo); glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL); - - finishDrawTexture(); } void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom, @@ -3546,8 +3529,6 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f setupDrawMesh(vertices, texCoords); glDrawArrays(drawMode, 0, elementsCount); - - finishDrawTexture(); } void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 2f8a2f0..1c3bfdc 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -1003,7 +1003,6 @@ private: void setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors); void setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo = 0); void setupDrawIndexedVertices(GLvoid* vertices); - void finishDrawTexture(); void accountForClear(SkXfermode::Mode mode); bool updateLayer(Layer* layer, bool inFrame); diff --git a/media/mca/filterfw/native/core/gl_env.cpp b/media/mca/filterfw/native/core/gl_env.cpp index fdecda3..84dad8c 100644 --- a/media/mca/filterfw/native/core/gl_env.cpp +++ b/media/mca/filterfw/native/core/gl_env.cpp @@ -26,6 +26,8 @@ #include <string> #include <EGL/eglext.h> +#include <gui/GLConsumer.h> + namespace android { namespace filterfw { diff --git a/media/mca/filterfw/native/core/gl_env.h b/media/mca/filterfw/native/core/gl_env.h index 81e1e9d..a709638 100644 --- a/media/mca/filterfw/native/core/gl_env.h +++ b/media/mca/filterfw/native/core/gl_env.h @@ -31,6 +31,9 @@ #include <gui/Surface.h> namespace android { + +class GLConsumer; + namespace filterfw { class ShaderProgram; diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java index 4c81006..43f95c3 100644 --- a/services/java/com/android/server/DevicePolicyManagerService.java +++ b/services/java/com/android/server/DevicePolicyManagerService.java @@ -2378,7 +2378,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override - public boolean setDeviceOwner(String packageName) { + public boolean setDeviceOwner(String packageName, String ownerName) { if (packageName == null || !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) { throw new IllegalArgumentException("Invalid package name " + packageName @@ -2386,7 +2386,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } synchronized (this) { if (mDeviceOwner == null && !isDeviceProvisioned()) { - mDeviceOwner = new DeviceOwner(packageName); + mDeviceOwner = new DeviceOwner(packageName, ownerName); mDeviceOwner.writeOwnerFile(); return true; } else { @@ -2415,6 +2415,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } + @Override + public String getDeviceOwnerName() { + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); + synchronized (this) { + if (mDeviceOwner != null) { + return mDeviceOwner.getName(); + } + } + return null; + } + private boolean isDeviceProvisioned() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) > 0; @@ -2488,15 +2499,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { static class DeviceOwner { private static final String DEVICE_OWNER_XML = "device_owner.xml"; private static final String TAG_DEVICE_OWNER = "device-owner"; + private static final String ATTR_NAME = "name"; private static final String ATTR_PACKAGE = "package"; private String mPackageName; + private String mOwnerName; DeviceOwner() { readOwnerFile(); } - DeviceOwner(String packageName) { + DeviceOwner(String packageName, String ownerName) { this.mPackageName = packageName; + this.mOwnerName = ownerName; } static boolean isRegistered() { @@ -2508,6 +2522,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return mPackageName; } + String getName() { + return mOwnerName; + } + static boolean isInstalled(String packageName, PackageManager pm) { try { PackageInfo pi; @@ -2539,6 +2557,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { "Device Owner file does not start with device-owner tag: found " + tag); } mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE); + mOwnerName = parser.getAttributeValue(null, ATTR_NAME); input.close(); } catch (XmlPullParserException xppe) { Slog.e(TAG, "Error parsing device-owner file\n" + xppe); @@ -2563,6 +2582,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.startDocument(null, true); out.startTag(null, TAG_DEVICE_OWNER); out.attribute(null, ATTR_PACKAGE, mPackageName); + if (mOwnerName != null) { + out.attribute(null, ATTR_NAME, mOwnerName); + } out.endTag(null, TAG_DEVICE_OWNER); out.endDocument(); out.flush(); diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java index 81b5618..6611a24 100644 --- a/services/java/com/android/server/am/ProcessStatsService.java +++ b/services/java/com/android/server/am/ProcessStatsService.java @@ -103,17 +103,7 @@ public final class ProcessStatsService extends IProcessStats.Stub { public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid, String processName, String className) { - final ProcessStats.PackageState as = mProcessStats.getPackageStateLocked(packageName, uid); - ProcessStats.ServiceState ss = as.mServices.get(className); - if (ss != null) { - ss.makeActive(); - return ss; - } - final ProcessStats.ProcessState ps = mProcessStats.getProcessStateLocked(packageName, - uid, processName); - ss = new ProcessStats.ServiceState(mProcessStats, packageName, ps); - as.mServices.put(className, ss); - return ss; + return mProcessStats.getServiceStateLocked(packageName, uid, processName, className); } public boolean isMemFactorLowered() { @@ -271,40 +261,11 @@ public final class ProcessStatsService extends IProcessStats.Stub { } } - static byte[] readFully(FileInputStream stream) throws java.io.IOException { - int pos = 0; - int avail = stream.available(); - byte[] data = new byte[avail]; - while (true) { - int amt = stream.read(data, pos, data.length-pos); - //Log.i("foo", "Read " + amt + " bytes at " + pos - // + " of avail " + data.length); - if (amt <= 0) { - //Log.i("foo", "**** FINISHED READING: pos=" + pos - // + " len=" + data.length); - return data; - } - pos += amt; - avail = stream.available(); - if (avail > data.length-pos) { - byte[] newData = new byte[pos+avail]; - System.arraycopy(data, 0, newData, 0, pos); - data = newData; - } - } - } - boolean readLocked(ProcessStats stats, AtomicFile file) { try { FileInputStream stream = file.openRead(); - - byte[] raw = readFully(stream); - Parcel in = Parcel.obtain(); - in.unmarshall(raw, 0, raw.length); - in.setDataPosition(0); + stats.read(stream); stream.close(); - - stats.readFromParcel(in); if (stats.mReadError != null) { Slog.w(TAG, "Ignoring existing stats; " + stats.mReadError); if (DEBUG) { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 6fa9cd0..73325cb 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -1272,6 +1272,11 @@ class WindowStateAnimator { if (mIsWallpaper) { mService.dispatchWallpaperVisibility(w, true); } + // This draw means the difference between unique content and mirroring. + // Run another pass through performLayout to set mHasContent in the + // LogicalDisplay. + mAnimator.setPendingLayoutChanges(w.getDisplayId(), + WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); } else { w.mOrientationChanging = false; } |
