Merge "Fix issue #30601353: Don't warn of non-protected explicit intent broadcasts" into nyc-mr1-dev
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index b58ff1f..d299672 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -147,7 +147,7 @@
}
final long traceTag = me.mTraceTag;
- if (traceTag != 0) {
+ if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
}
try {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 69f1747..0cdf5e1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -821,6 +821,17 @@
static boolean sTextureViewIgnoresDrawableSetters = false;
/**
+ * Prior to N, some ViewGroups would not convert LayoutParams properly even though both extend
+ * MarginLayoutParams. For instance, converting LinearLayout.LayoutParams to
+ * RelativeLayout.LayoutParams would lose margin information. This is fixed on N but target API
+ * check is implemented for backwards compatibility.
+ *
+ * {@hide}
+ */
+ protected static boolean sPreserveMarginParamsInLayoutParamConversion;
+
+
+ /**
* This view does not want keystrokes. Use with TAKES_FOCUS_MASK when
* calling setFlags.
*/
@@ -4052,6 +4063,10 @@
// On N+, we throw, but that breaks compatibility with apps that use these methods.
sTextureViewIgnoresDrawableSetters = targetSdkVersion <= M;
+ // Prior to N, we would drop margins in LayoutParam conversions. The fix triggers bugs
+ // in apps so we target check it to avoid breaking existing apps.
+ sPreserveMarginParamsInLayoutParamConversion = targetSdkVersion >= N;
+
sCompatibilityDone = true;
}
}
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 029313c..b8c74d8 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -382,13 +382,14 @@
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
- if (lp instanceof LayoutParams) {
- return new LayoutParams((LayoutParams) lp);
- } else if (lp instanceof MarginLayoutParams) {
- return new LayoutParams((MarginLayoutParams) lp);
- } else {
- return new LayoutParams(lp);
+ if (sPreserveMarginParamsInLayoutParamConversion) {
+ if (lp instanceof LayoutParams) {
+ return new LayoutParams((LayoutParams) lp);
+ } else if (lp instanceof MarginLayoutParams) {
+ return new LayoutParams((MarginLayoutParams) lp);
+ }
}
+ return new LayoutParams(lp);
}
@Override
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 726586e..af2852c 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -868,13 +868,14 @@
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
- if (lp instanceof LayoutParams) {
- return new LayoutParams((LayoutParams) lp);
- } else if (lp instanceof MarginLayoutParams) {
- return new LayoutParams((MarginLayoutParams) lp);
- } else {
- return new LayoutParams(lp);
+ if (sPreserveMarginParamsInLayoutParamConversion) {
+ if (lp instanceof LayoutParams) {
+ return new LayoutParams((LayoutParams) lp);
+ } else if (lp instanceof MarginLayoutParams) {
+ return new LayoutParams((MarginLayoutParams) lp);
+ }
}
+ return new LayoutParams(lp);
}
// Draw grid
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index 38d7cd4..f897372 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1844,13 +1844,14 @@
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
- if (lp instanceof LayoutParams) {
- return new LayoutParams((LayoutParams) lp);
- } else if (lp instanceof MarginLayoutParams) {
- return new LayoutParams((MarginLayoutParams) lp);
- } else {
- return new LayoutParams(lp);
+ if (sPreserveMarginParamsInLayoutParamConversion) {
+ if (lp instanceof LayoutParams) {
+ return new LayoutParams((LayoutParams) lp);
+ } else if (lp instanceof MarginLayoutParams) {
+ return new LayoutParams((MarginLayoutParams) lp);
+ }
}
+ return new LayoutParams(lp);
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 0136542..a189d3c 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1104,13 +1104,14 @@
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
- if (lp instanceof LayoutParams) {
- return new LayoutParams((LayoutParams) lp);
- } else if (lp instanceof MarginLayoutParams) {
- return new LayoutParams((MarginLayoutParams) lp);
- } else {
- return new LayoutParams(lp);
+ if (sPreserveMarginParamsInLayoutParamConversion) {
+ if (lp instanceof LayoutParams) {
+ return new LayoutParams((LayoutParams) lp);
+ } else if (lp instanceof MarginLayoutParams) {
+ return new LayoutParams((MarginLayoutParams) lp);
+ }
}
+ return new LayoutParams(lp);
}
/** @hide */
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 00a7edd..fd54b7d 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -819,8 +819,8 @@
to: /about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client
- from: /shareables/...
to: https://commondatastorage.googleapis.com/androiddevelopers/shareables/...
-- from: /downloads/
- to: https://commondatastorage.googleapis.com/androiddevelopers/
+- from: /downloads/...
+ to: https://commondatastorage.googleapis.com/androiddevelopers/...
- from: /training/performance/battery/network/action-any-traffic.html
to: /topic/performance/power/network/action-any-traffic.html
- from: /training/performance/battery/network/action-app-traffic.html
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 6facf20..bdcad79 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -422,7 +422,6 @@
pushStagingDisplayListChanges(info);
}
prepareSubTree(info, childFunctorsNeedLayer, mDisplayList);
- pushLayerUpdate(info);
if (mDisplayList) {
for (auto& vectorDrawable : mDisplayList->getVectorDrawables()) {
@@ -433,6 +432,7 @@
vectorDrawable->setPropertyChangeWillBeConsumed(true);
}
}
+ pushLayerUpdate(info);
info.damageAccumulator->popTransform();
}
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index f04df4b..5a75f40 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -60,6 +60,8 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.hardware.display.DisplayManagerGlobal;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -78,6 +80,8 @@
import android.util.Log;
import android.util.Patterns;
import android.util.SparseArray;
+import android.view.Display;
+import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnFocusChangeListener;
@@ -771,7 +775,6 @@
}
msg = mContext.getString(R.string.bugreport_screenshot_taken);
} else {
- // TODO: try again using Framework APIs instead of relying on screencap.
msg = mContext.getString(R.string.bugreport_screenshot_failed);
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
@@ -1350,22 +1353,24 @@
/**
* Takes a screenshot and save it to the given location.
*/
- private static boolean takeScreenshot(Context context, String screenshotFile) {
- final ProcessBuilder screencap = new ProcessBuilder()
- .command("/system/bin/screencap", "-p", screenshotFile);
- Log.d(TAG, "Taking screenshot using " + screencap.command());
- try {
- final int exitValue = screencap.start().waitFor();
- if (exitValue == 0) {
+ private static boolean takeScreenshot(Context context, String path) {
+ final Bitmap bitmap = Screenshooter.takeScreenshot();
+ if (bitmap == null) {
+ return false;
+ }
+ boolean status;
+ try (final FileOutputStream fos = new FileOutputStream(path)) {
+ if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(150);
return true;
+ } else {
+ Log.e(TAG, "Failed to save screenshot on " + path);
}
- Log.e(TAG, "screencap (" + screencap.command() + ") failed: " + exitValue);
- } catch (IOException e) {
- Log.e(TAG, "screencap (" + screencap.command() + ") failed", e);
- } catch (InterruptedException e) {
- Log.w(TAG, "Thread interrupted while screencap still running");
- Thread.currentThread().interrupt();
+ } catch (IOException e ) {
+ Log.e(TAG, "Failed to save screenshot on " + path, e);
+ return false;
+ } finally {
+ bitmap.recycle();
}
return false;
}
diff --git a/packages/Shell/src/com/android/shell/Screenshooter.java b/packages/Shell/src/com/android/shell/Screenshooter.java
new file mode 100644
index 0000000..3f4895b
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/Screenshooter.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.shell;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Point;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+/**
+ * Helper class used to take screenshots.
+ *
+ * TODO: logic below was copied and pasted from UiAutomation; it should be refactored into a common
+ * component that could be used by both (Shell and UiAutomation).
+ */
+final class Screenshooter {
+
+ private static final String TAG = "Screenshooter";
+
+ /** Rotation constant: Freeze rotation to 0 degrees (natural orientation) */
+ public static final int ROTATION_FREEZE_0 = Surface.ROTATION_0;
+
+ /** Rotation constant: Freeze rotation to 90 degrees . */
+ public static final int ROTATION_FREEZE_90 = Surface.ROTATION_90;
+
+ /** Rotation constant: Freeze rotation to 180 degrees . */
+ public static final int ROTATION_FREEZE_180 = Surface.ROTATION_180;
+
+ /** Rotation constant: Freeze rotation to 270 degrees . */
+ public static final int ROTATION_FREEZE_270 = Surface.ROTATION_270;
+
+ /**
+ * Takes a screenshot.
+ *
+ * @return The screenshot bitmap on success, null otherwise.
+ */
+ static Bitmap takeScreenshot() {
+ Display display = DisplayManagerGlobal.getInstance()
+ .getRealDisplay(Display.DEFAULT_DISPLAY);
+ Point displaySize = new Point();
+ display.getRealSize(displaySize);
+ final int displayWidth = displaySize.x;
+ final int displayHeight = displaySize.y;
+
+ final float screenshotWidth;
+ final float screenshotHeight;
+
+ final int rotation = display.getRotation();
+ switch (rotation) {
+ case ROTATION_FREEZE_0: {
+ screenshotWidth = displayWidth;
+ screenshotHeight = displayHeight;
+ } break;
+ case ROTATION_FREEZE_90: {
+ screenshotWidth = displayHeight;
+ screenshotHeight = displayWidth;
+ } break;
+ case ROTATION_FREEZE_180: {
+ screenshotWidth = displayWidth;
+ screenshotHeight = displayHeight;
+ } break;
+ case ROTATION_FREEZE_270: {
+ screenshotWidth = displayHeight;
+ screenshotHeight = displayWidth;
+ } break;
+ default: {
+ throw new IllegalArgumentException("Invalid rotation: "
+ + rotation);
+ }
+ }
+
+ Log.d(TAG, "Taking screenshot of dimensions " + displayWidth + " x " + displayHeight);
+ // Take the screenshot
+ Bitmap screenShot =
+ SurfaceControl.screenshot((int) screenshotWidth, (int) screenshotHeight);
+ if (screenShot == null) {
+ Log.e(TAG, "Failed to take screenshot of dimensions " + screenshotWidth + " x "
+ + screenshotHeight);
+ return null;
+ }
+
+ // Rotate the screenshot to the current orientation
+ if (rotation != ROTATION_FREEZE_0) {
+ Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight,
+ Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(unrotatedScreenShot);
+ canvas.translate(unrotatedScreenShot.getWidth() / 2,
+ unrotatedScreenShot.getHeight() / 2);
+ canvas.rotate(getDegreesForRotation(rotation));
+ canvas.translate(- screenshotWidth / 2, - screenshotHeight / 2);
+ canvas.drawBitmap(screenShot, 0, 0, null);
+ canvas.setBitmap(null);
+ screenShot.recycle();
+ screenShot = unrotatedScreenShot;
+ }
+
+ // Optimization
+ screenShot.setHasAlpha(false);
+
+ return screenShot;
+ }
+
+ private static float getDegreesForRotation(int value) {
+ switch (value) {
+ case Surface.ROTATION_90: {
+ return 360f - 90f;
+ }
+ case Surface.ROTATION_180: {
+ return 360f - 180f;
+ }
+ case Surface.ROTATION_270: {
+ return 360f - 270f;
+ } default: {
+ return 0;
+ }
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 9eb768c..7c8d0f6 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -57,8 +57,9 @@
private static SummaryStats sEmergencyCallStats;
private static SummaryStats[][] sProxStats; // [reason][near/far]
- public static void tracePickupPulse(boolean withinVibrationThreshold) {
+ public static void tracePickupPulse(Context context, boolean withinVibrationThreshold) {
if (!ENABLED) return;
+ init(context);
log("pickupPulse withinVibrationThreshold=" + withinVibrationThreshold);
(withinVibrationThreshold ? sPickupPulseNearVibrationStats
: sPickupPulseNotNearVibrationStats).append();
@@ -76,8 +77,9 @@
log("pulseFinish");
}
- public static void traceNotificationPulse(long instance) {
+ public static void traceNotificationPulse(Context context, long instance) {
if (!ENABLED) return;
+ init(context);
log("notificationPulse instance=" + instance);
sNotificationPulseStats.append();
}
@@ -153,9 +155,9 @@
public static void traceProximityResult(Context context, boolean near, long millis,
int pulseReason) {
if (!ENABLED) return;
+ init(context);
log("proximityResult reason=" + pulseReasonToString(pulseReason) + " near=" + near
+ " millis=" + millis);
- init(context);
sProxStats[pulseReason][near ? 0 : 1].append();
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 661b347..fc0d8bb 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -373,7 +373,7 @@
if (DEBUG) Log.d(mTag, "mScheduleResetsRemaining = " + mScheduleResetsRemaining);
mNotificationPulseTime = notificationTimeMs;
if (pulseImmediately) {
- DozeLog.traceNotificationPulse(0);
+ DozeLog.traceNotificationPulse(mContext, 0);
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
}
// schedule the rest of the pulses
@@ -442,7 +442,7 @@
if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
final long instance = intent.getLongExtra(EXTRA_INSTANCE, -1);
if (DEBUG) Log.d(mTag, "Received notification pulse intent instance=" + instance);
- DozeLog.traceNotificationPulse(instance);
+ DozeLog.traceNotificationPulse(mContext, instance);
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
rescheduleNotificationPulse(mNotificationLightOn);
}
@@ -576,7 +576,7 @@
resetNotificationResets();
}
if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
- DozeLog.tracePickupPulse(withinVibrationThreshold);
+ DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
}
} finally {
mWakeLock.release();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 998f50f..cb77d7b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -31,6 +31,7 @@
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Handler;
+import android.os.Message;
import android.util.AttributeSet;
import android.view.Display;
import android.view.DisplayInfo;
@@ -106,6 +107,11 @@
private static final Interpolator IME_ADJUST_INTERPOLATOR =
new PathInterpolator(0.2f, 0f, 0.1f, 1f);
+ private static final long ONE_MS_IN_NS = 1000000;
+ private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000;
+
+ private static final int MSG_RESIZE_STACK = 0;
+
private DividerHandleView mHandle;
private View mBackground;
private MinimizedDockShadow mMinimizedShadow;
@@ -150,7 +156,25 @@
private boolean mDockedStackMinimized;
private boolean mAdjustedForIme;
private DividerState mState;
- private final Handler mHandler = new Handler();
+
+ /**
+ * The offset between vsync-app and vsync-surfaceflinger. See
+ * {@link #calculateAppSurfaceFlingerVsyncOffsetMs} why this is necessary.
+ */
+ private long mSurfaceFlingerOffsetMs;
+
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_RESIZE_STACK:
+ resizeStack(msg.arg1, msg.arg2, (SnapTarget) msg.obj);
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ };
private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() {
@Override
@@ -290,6 +314,7 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
EventBus.getDefault().register(this);
+ mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs();
}
@Override
@@ -298,6 +323,25 @@
EventBus.getDefault().unregister(this);
}
+ /**
+ * This method calculates the offset between vsync-surfaceflinger and vsync-app. If vsync-app
+ * is a couple of milliseconds before vsync-sf, a touch or animation event that causes the
+ * stacks to be resized are sometimes processed before the vsync-sf tick, and sometimes after,
+ * which leads to jank. Figure out this difference here and then post all the touch/animation
+ * events to start being processed at vsync-sf.
+ *
+ * @return The offset between vsync-app and vsync-sf, or 0 if vsync app happens after vsync-sf.
+ */
+ private long calculateAppSurfaceFlingerVsyncOffsetMs() {
+ Display display = getDisplay();
+
+ // Calculate vsync offset from SurfaceFlinger.
+ // See frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:getDisplayConfigs
+ long vsyncPeriod = (long) (ONE_S_IN_NS / display.getRefreshRate());
+ long sfVsyncOffset = vsyncPeriod - (display.getPresentationDeadlineNanos() - ONE_MS_IN_NS);
+ return Math.max(0, (sfVsyncOffset - display.getAppVsyncOffsetNanos()) / ONE_MS_IN_NS);
+ }
+
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (mStableInsets.left != insets.getStableInsetLeft()
@@ -453,7 +497,7 @@
if (mMoving && mDockSide != WindowManager.DOCKED_INVALID) {
SnapTarget snapTarget = mSnapAlgorithm.calculateSnapTarget(
mStartPosition, 0 /* velocity */, false /* hardDismiss */);
- resizeStack(calculatePosition(x, y), mStartPosition, snapTarget);
+ resizeStackDelayed(calculatePosition(x, y), mStartPosition, snapTarget);
}
break;
case MotionEvent.ACTION_UP:
@@ -532,10 +576,11 @@
final long endDelay) {
final boolean taskPositionSameAtEnd = snapTarget.flag == SnapTarget.FLAG_NONE;
ValueAnimator anim = ValueAnimator.ofInt(position, snapTarget.position);
- anim.addUpdateListener(animation -> resizeStack((Integer) animation.getAnimatedValue(),
+ anim.addUpdateListener(animation -> resizeStackDelayed((int) animation.getAnimatedValue(),
taskPositionSameAtEnd && animation.getAnimatedFraction() == 1f
? TASK_POSITION_SAME
- : snapTarget.taskPosition, snapTarget));
+ : snapTarget.taskPosition,
+ snapTarget));
Runnable endAction = () -> {
commitSnapFlags(snapTarget);
mWindowManagerProxy.setResizing(false);
@@ -551,15 +596,24 @@
@Override
public void onAnimationCancel(Animator animation) {
+ mHandler.removeMessages(MSG_RESIZE_STACK);
mCancelled = true;
}
@Override
public void onAnimationEnd(Animator animation) {
- if (endDelay == 0 || mCancelled) {
+ long delay = 0;
+ if (endDelay != 0) {
+ delay = endDelay;
+ } else if (mCancelled) {
+ delay = 0;
+ } else if (mSurfaceFlingerOffsetMs != 0) {
+ delay = mSurfaceFlingerOffsetMs;
+ }
+ if (delay == 0) {
endAction.run();
} else {
- mHandler.postDelayed(endAction, endDelay);
+ mHandler.postDelayed(endAction, delay);
}
}
});
@@ -793,6 +847,17 @@
mDisplayHeight, mDividerSize);
}
+ public void resizeStackDelayed(int position, int taskPosition, SnapTarget taskSnapTarget) {
+ if (mSurfaceFlingerOffsetMs != 0) {
+ Message message = mHandler.obtainMessage(MSG_RESIZE_STACK, position, taskPosition,
+ taskSnapTarget);
+ message.setAsynchronous(true);
+ mHandler.sendMessageDelayed(message, mSurfaceFlingerOffsetMs);
+ } else {
+ resizeStack(position, taskPosition, taskSnapTarget);
+ }
+ }
+
public void resizeStack(int position, int taskPosition, SnapTarget taskSnapTarget) {
calculateBoundsForPosition(position, mDockSide, mDockedRect);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 628cfd5..c575417 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -961,7 +961,6 @@
mNotificationGutsExposed = entry.row.getGuts();
bindGuts(entry.row);
}
- entry.cacheContentViews(mContext, null /* updatedNotification */);
inflateViews(entry, mStackScroller);
}
}
@@ -1585,7 +1584,12 @@
entry.notification.getUser().getIdentifier());
final StatusBarNotification sbn = entry.notification;
- entry.cacheContentViews(mContext, null);
+ try {
+ entry.cacheContentViews(mContext, null);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Unable to get notification remote views", e);
+ return false;
+ }
final RemoteViews contentView = entry.cachedContentView;
final RemoteViews bigContentView = entry.cachedBigContentView;
@@ -2354,7 +2358,13 @@
Notification n = notification.getNotification();
mNotificationData.updateRanking(ranking);
- boolean applyInPlace = entry.cacheContentViews(mContext, notification.getNotification());
+ boolean applyInPlace;
+ try {
+ applyInPlace = entry.cacheContentViews(mContext, notification.getNotification());
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Unable to get notification remote views", e);
+ applyInPlace = false;
+ }
boolean shouldPeek = shouldPeek(entry, notification);
boolean alertAgain = alertAgain(entry, n);
if (DEBUG) {
@@ -2406,7 +2416,10 @@
StatusBarIconView.contentDescForNotification(mContext, n));
entry.icon.setNotification(n);
entry.icon.set(ic);
- inflateViews(entry, mStackScroller);
+ if (!inflateViews(entry, mStackScroller)) {
+ handleNotificationError(notification, "Couldn't update remote views for: "
+ + notification);
+ }
}
updateHeadsUp(key, entry, shouldPeek, alertAgain);
updateNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 64f205d2..768e5f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -81,8 +81,8 @@
private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
- private static final String COUNTER_PANEL_OPEN = "panel_open";
- private static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
+ static final String COUNTER_PANEL_OPEN = "panel_open";
+ static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
private static final Rect mDummyDirtyRect = new Rect(0, 0, 1, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b623f19..c703128 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -2628,12 +2628,16 @@
if (!mUserSetup) return;
if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP == key) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_UP);
mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */);
} else if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN == key) {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_SYSTEM_NAVIGATION_KEY_DOWN);
if (mNotificationPanel.isFullyCollapsed()) {
mNotificationPanel.expand(true /* animate */);
+ MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN, 1);
} else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
mNotificationPanel.flingSettings(0 /* velocity */, true /* expand */);
+ MetricsLogger.count(mContext, NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
}
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0106f7f0..d9f2bac 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2197,6 +2197,12 @@
// Night Light on
SETTINGS_CONDITION_NIGHT_DISPLAY = 492;
+ // System navigation key up.
+ ACTION_SYSTEM_NAVIGATION_KEY_UP = 493;
+
+ // System navigation key down.
+ ACTION_SYSTEM_NAVIGATION_KEY_DOWN = 494;
+
// ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index c9283b2..4bc148b 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -279,6 +279,7 @@
*/
private void finishUserUnlocking(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
+ boolean proceedWithUnlock = false;
synchronized (mService) {
// Bail if we ended up with a stale user
if (mStartedUsers.get(uss.mHandle.getIdentifier()) != uss) return;
@@ -288,20 +289,24 @@
if (uss.setState(STATE_RUNNING_LOCKED, STATE_RUNNING_UNLOCKING)) {
getUserManagerInternal().setUserState(userId, uss.state);
- uss.mUnlockProgress.start();
-
- // Prepare app storage before we go any further
- uss.mUnlockProgress.setProgress(5,
- mService.mContext.getString(R.string.android_start_title));
- mUserManager.onBeforeUnlockUser(userId);
- uss.mUnlockProgress.setProgress(20);
-
- // Dispatch unlocked to system services; when fully dispatched,
- // that calls through to the next "unlocked" phase
- mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
- .sendToTarget();
+ proceedWithUnlock = true;
}
}
+
+ if (proceedWithUnlock) {
+ uss.mUnlockProgress.start();
+
+ // Prepare app storage before we go any further
+ uss.mUnlockProgress.setProgress(5,
+ mService.mContext.getString(R.string.android_start_title));
+ mUserManager.onBeforeUnlockUser(userId);
+ uss.mUnlockProgress.setProgress(20);
+
+ // Dispatch unlocked to system services; when fully dispatched,
+ // that calls through to the next "unlocked" phase
+ mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0, uss)
+ .sendToTarget();
+ }
}
/**
@@ -962,6 +967,7 @@
boolean unlockUserCleared(final int userId, byte[] token, byte[] secret,
IProgressListener listener) {
+ UserState uss;
synchronized (mService) {
// TODO Move this block outside of synchronized if it causes lock contention
if (!StorageManager.isUserKeyUnlocked(userId)) {
@@ -976,7 +982,7 @@
}
// Bail if user isn't actually running, otherwise register the given
// listener to watch for unlock progress
- final UserState uss = mStartedUsers.get(userId);
+ uss = mStartedUsers.get(userId);
if (uss == null) {
notifyFinished(userId, listener);
return false;
@@ -984,8 +990,12 @@
uss.mUnlockProgress.addListener(listener);
uss.tokenProvided = (token != null);
}
+ }
- finishUserUnlocking(uss);
+ finishUserUnlocking(uss);
+
+ final ArraySet<Integer> childProfilesToUnlock = new ArraySet<>();
+ synchronized (mService) {
// We just unlocked a user, so let's now attempt to unlock any
// managed profiles under that user.
@@ -995,11 +1005,16 @@
if (parent != null && parent.id == userId && testUserId != userId) {
Slog.d(TAG, "User " + testUserId + " (parent " + parent.id
+ "): attempting unlock because parent was just unlocked");
- maybeUnlockUser(testUserId);
+ childProfilesToUnlock.add(testUserId);
}
}
}
+ final int size = childProfilesToUnlock.size();
+ for (int i = 0; i < size; i++) {
+ maybeUnlockUser(childProfilesToUnlock.valueAt(i));
+ }
+
return true;
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b22a084..8f9cc47 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2818,7 +2818,6 @@
for (int j = mPowerSaveTempWhitelistAppIds.size() - 1; j >= 0; j--) {
int appId = mPowerSaveTempWhitelistAppIds.keyAt(j);
int uid = UserHandle.getUid(user.id, appId);
- updateRulesForRestrictPowerUL();
// Update external firewall rules.
updateRuleForAppIdleUL(uid);
updateRuleForDeviceIdleUL(uid);
diff --git a/services/core/java/com/android/server/pm/ShortcutUser.java b/services/core/java/com/android/server/pm/ShortcutUser.java
index 21e4165..ce3ed9c 100644
--- a/services/core/java/com/android/server/pm/ShortcutUser.java
+++ b/services/core/java/com/android/server/pm/ShortcutUser.java
@@ -57,7 +57,9 @@
private static final String ATTR_VALUE = "value";
private static final String ATTR_KNOWN_LOCALES = "locales";
- private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time";
+
+ // Suffix "2" was added to force rescan all packages after the next OTA.
+ private static final String ATTR_LAST_APP_SCAN_TIME = "last-app-scan-time2";
private static final String KEY_USER_ID = "userId";
private static final String KEY_LAUNCHERS = "launchers";
private static final String KEY_PACKAGES = "packages";