Merge "Count app launch correctly." into pi-dev
diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java
index 17687c9..a4550af 100644
--- a/core/java/android/view/textclassifier/TextSelection.java
+++ b/core/java/android/view/textclassifier/TextSelection.java
@@ -154,8 +154,8 @@
          * Sets an id for the TextSelection object.
          */
         @NonNull
-        public Builder setId(@NonNull String id) {
-            mId = Preconditions.checkNotNull(id);
+        public Builder setId(@Nullable String id) {
+            mId = id;
             return this;
         }
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a353070..268bc9c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3424,4 +3424,7 @@
     <!-- Whether or not swipe up gesture is enabled by default -->
     <bool name="config_swipe_up_gesture_default">false</bool>
 
+    <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
+    <bool name="config_swipe_up_gesture_setting_available">false</bool>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index fb275ba..6d4bbe2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3301,6 +3301,7 @@
   <java-symbol type="string" name="shortcut_restore_unknown_issue" />
 
   <java-symbol type="bool" name="config_swipe_up_gesture_default" />
+  <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" />
 
   <!-- From media projection -->
   <java-symbol type="string" name="config_mediaProjectionPermissionDialogComponent" />
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
index 660521e..573504a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/AbstractPreferenceController.java
@@ -37,6 +37,13 @@
      * Updates the current status of preference (summary, switch state, etc)
      */
     public void updateState(Preference preference) {
+        refreshSummary(preference);
+    }
+
+    /**
+     * Refresh preference summary with getSummary()
+     */
+    protected void refreshSummary(Preference preference) {
         if (preference == null) {
             return;
         }
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 24d662b..cd8ffa8 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -61,6 +61,7 @@
     <item type="id" name="notification_temperature"/>
     <item type="id" name="notification_plugin"/>
     <item type="id" name="transformation_start_x_tag"/>
+    <item type="id" name="doze_intensity_tag"/>
     <item type="id" name="transformation_start_y_tag"/>
     <item type="id" name="transformation_start_actual_width"/>
     <item type="id" name="transformation_start_actual_height"/>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 174dcab..f399667 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -373,7 +373,6 @@
 
     @Override
     public void onResume(int reason) {
-        reset();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java b/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
deleted file mode 100644
index 2c96e31..0000000
--- a/packages/SystemUI/src/com/android/systemui/ViewInvertHelper.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * Helper to invert the colors of views and fade between the states.
- */
-public class ViewInvertHelper {
-
-    private final Paint mDarkPaint = new Paint();
-    private final ColorMatrix mMatrix = new ColorMatrix();
-    private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
-    private final long mFadeDuration;
-    private final ArrayList<View> mTargets = new ArrayList<>();
-
-    public ViewInvertHelper(View v, long fadeDuration) {
-        this(v.getContext(), fadeDuration);
-        addTarget(v);
-    }
-    public ViewInvertHelper(Context context, long fadeDuration) {
-        mFadeDuration = fadeDuration;
-    }
-
-    private static ArrayList<View> constructArray(View target) {
-        final ArrayList<View> views = new ArrayList<>();
-        views.add(target);
-        return views;
-    }
-
-    public void clearTargets() {
-        mTargets.clear();
-    }
-
-    public void addTarget(View target) {
-        mTargets.add(target);
-    }
-
-    public void fade(final boolean invert, long delay) {
-        float startIntensity = invert ? 0f : 1f;
-        float endIntensity = invert ? 1f : 0f;
-        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
-        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateInvertPaint((Float) animation.getAnimatedValue());
-                for (int i = 0; i < mTargets.size(); i++) {
-                    mTargets.get(i).setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
-                }
-            }
-        });
-        animator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!invert) {
-                    for (int i = 0; i < mTargets.size(); i++) {
-                        mTargets.get(i).setLayerType(View.LAYER_TYPE_NONE, null);
-                    }
-                }
-            }
-        });
-        animator.setDuration(mFadeDuration);
-        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        animator.setStartDelay(delay);
-        animator.start();
-    }
-
-    public void update(boolean invert) {
-        if (invert) {
-            updateInvertPaint(1f);
-            for (int i = 0; i < mTargets.size(); i++) {
-                mTargets.get(i).setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
-            }
-        } else {
-            for (int i = 0; i < mTargets.size(); i++) {
-                mTargets.get(i).setLayerType(View.LAYER_TYPE_NONE, null);
-            }
-        }
-    }
-
-    private void updateInvertPaint(float intensity) {
-        float components = 1 - 2 * intensity;
-        final float[] invert = {
-                components, 0f,         0f,         0f, 255f * intensity,
-                0f,         components, 0f,         0f, 255f * intensity,
-                0f,         0f,         components, 0f, 255f * intensity,
-                0f,         0f,         0f,         1f, 0f
-        };
-        mMatrix.set(invert);
-        mGrayscaleMatrix.setSaturation(1 - intensity);
-        mMatrix.preConcat(mGrayscaleMatrix);
-        mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
-    }
-
-    public void setInverted(boolean invert, boolean fade, long delay) {
-        if (fade) {
-            fade(invert, delay);
-        } else {
-            update(invert);
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index b2a80f4..4a67868 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.media;
 
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
@@ -36,6 +38,7 @@
 import android.text.TextUtils;
 import android.text.style.StyleSpan;
 import android.util.Log;
+import android.view.Window;
 import android.view.WindowManager;
 import android.widget.CheckBox;
 import android.widget.CompoundButton;
@@ -146,7 +149,9 @@
         mDialog.getButton(DialogInterface.BUTTON_POSITIVE).setFilterTouchesWhenObscured(true);
 
         ((CheckBox) mDialog.findViewById(R.id.remember)).setOnCheckedChangeListener(this);
-        mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        final Window w = mDialog.getWindow();
+        w.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        w.addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         mDialog.show();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 08d530b..724bd22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -422,7 +422,6 @@
         mContractedChild = child;
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child,
                 mContainingNotification);
-        mContractedWrapper.setDark(mDark, false /* animate */, 0 /* delay */);
     }
 
     private NotificationViewWrapper getWrapperForView(View child) {
@@ -1106,18 +1105,6 @@
             return;
         }
         mDark = dark;
-        if (mVisibleType == VISIBLE_TYPE_CONTRACTED || !dark) {
-            mContractedWrapper.setDark(dark, fade, delay);
-        }
-        if (mVisibleType == VISIBLE_TYPE_EXPANDED || (mExpandedChild != null && !dark)) {
-            mExpandedWrapper.setDark(dark, fade, delay);
-        }
-        if (mVisibleType == VISIBLE_TYPE_HEADSUP || (mHeadsUpChild != null && !dark)) {
-            mHeadsUpWrapper.setDark(dark, fade, delay);
-        }
-        if (mSingleLineView != null && (mVisibleType == VISIBLE_TYPE_SINGLELINE || !dark)) {
-            mSingleLineView.setDark(dark, fade, delay);
-        }
         selectLayout(!dark && fade /* animate */, false /* force */);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d3caf03..3063199 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -33,10 +33,8 @@
 
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.phone.NotificationIconContainer;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 import com.android.systemui.statusbar.stack.AmbientState;
 import com.android.systemui.statusbar.stack.AnimationProperties;
 import com.android.systemui.statusbar.stack.ExpandableViewState;
@@ -60,7 +58,6 @@
     private static final String TAG = "NotificationShelf";
     private static final long SHELF_IN_TRANSLATION_DURATION = 200;
 
-    private ViewInvertHelper mViewInvertHelper;
     private boolean mDark;
     private NotificationIconContainer mShelfIcons;
     private ShelfState mShelfState;
@@ -105,8 +102,6 @@
         setClipChildren(false);
         setClipToPadding(false);
         mShelfIcons.setIsStaticLayout(false);
-        mViewInvertHelper = new ViewInvertHelper(mShelfIcons,
-                NotificationPanelView.DOZE_ANIMATION_DURATION);
         mShelfState = new ShelfState();
         setBottomRoundness(1.0f, false /* animate */);
         initDimens();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 4fc18ad..0b941c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -806,7 +806,7 @@
             updateDecorColor();
             updateIconColor();
             updateAllowAnimation();
-        }, dark, fade, delay);
+        }, dark, fade, delay, this);
     }
 
     private void updateAllowAnimation() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
index a096508..ec94df1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridGroupManager.java
@@ -166,7 +166,7 @@
         mDozer.setIntensityDark((f)->{
             mDarkAmount = f;
             updateOverFlowNumberColor(view);
-        }, dark, fade, delay);
+        }, dark, fade, delay, view);
         view.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                 dark ? mOverflowNumberSizeDark : mOverflowNumberSize);
         int paddingEnd = dark ? mOverflowNumberPaddingDark : mOverflowNumberPadding;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
index 0a1795f..85f2a63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HybridNotificationView.java
@@ -25,11 +25,9 @@
 
 import com.android.keyguard.AlphaOptimizedLinearLayout;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * A hybrid view which may contain information about one ore more notifications.
@@ -41,7 +39,6 @@
 
     protected TextView mTitleView;
     protected TextView mTextView;
-    private ViewInvertHelper mInvertHelper;
 
     public HybridNotificationView(Context context) {
         this(context, null);
@@ -73,7 +70,6 @@
         super.onFinishInflate();
         mTitleView = (TextView) findViewById(R.id.notification_title);
         mTextView = (TextView) findViewById(R.id.notification_text);
-        mInvertHelper = new ViewInvertHelper(this, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
         mTransformationHelper.setCustomTransformation(
                 new ViewTransformationHelper.CustomTransformation() {
@@ -126,10 +122,6 @@
         requestLayout();
     }
 
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mInvertHelper.setInverted(dark, fade, delay);
-    }
-
     @Override
     public TransformState getCurrentState(int fadingView) {
         return mTransformationHelper.getCurrentState(fadingView);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index adc0914..7a51fe1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -16,82 +16,26 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.content.Context;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Paint;
 import android.view.View;
 
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Wraps a notification containing a custom view.
  */
 public class NotificationCustomViewWrapper extends NotificationViewWrapper {
 
-    private final ViewInvertHelper mInvertHelper;
-    private final Paint mGreyPaint = new Paint();
     private boolean mIsLegacy;
     private int mLegacyColor;
 
     protected NotificationCustomViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(ctx, view, row);
-        mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        if (!mIsLegacy && mShouldInvertDark) {
-            if (fade) {
-                mInvertHelper.fade(dark, delay);
-            } else {
-                mInvertHelper.update(dark);
-            }
-        } else {
-            mView.setLayerType(dark ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE, null);
-            if (fade) {
-                fadeGrayscale(dark, delay);
-            } else {
-                updateGrayscale(dark);
-            }
-        }
-    }
-
-    protected void fadeGrayscale(final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            getDozer().updateGrayscaleMatrix((float) animation.getAnimatedValue());
-            mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
-            mView.setLayerPaint(mGreyPaint);
-        }, dark, delay, new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!dark) {
-                    mView.setLayerType(View.LAYER_TYPE_NONE, null);
-                }
-            }
-        });
-    }
-
-    protected void updateGrayscale(boolean dark) {
-        if (dark) {
-            getDozer().updateGrayscaleMatrix(1f);
-            mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
-            mView.setLayerPaint(mGreyPaint);
-        }
-    }
-
-    @Override
     public void setVisible(boolean visible) {
         super.setVisible(visible);
         mView.setAlpha(visible ? 1.0f : 0.0f);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index 0b3b3cb..fb362c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -21,14 +21,17 @@
 import android.animation.ValueAnimator;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
+import android.view.View;
 import android.widget.ImageView;
 
 import com.android.systemui.Interpolators;
+import com.android.systemui.R;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 import java.util.function.Consumer;
 
 public class NotificationDozeHelper {
+    private static final int DOZE_ANIMATOR_TAG = R.id.doze_intensity_tag;
     private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
 
     public void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
@@ -76,11 +79,26 @@
     }
 
     public void setIntensityDark(Consumer<Float> listener, boolean dark,
-            boolean animate, long delay) {
+            boolean animate, long delay, View view) {
         if (animate) {
             startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
-                    null /* listener */);
+                    new AnimatorListenerAdapter() {
+
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            view.setTag(DOZE_ANIMATOR_TAG, null);
+                        }
+
+                        @Override
+                        public void onAnimationStart(Animator animation) {
+                            view.setTag(DOZE_ANIMATOR_TAG, animation);
+                        }
+                    } /* listener */);
         } else {
+            Animator animator = (Animator) view.getTag(DOZE_ANIMATOR_TAG);
+            if (animator != null) {
+                animator.cancel();
+            }
             listener.accept(dark ? 1f : 0f);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 78df77f..2fc2cdb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.notification;
 
+import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
+
 import android.app.Notification;
 import android.content.Context;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuffColorFilter;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -32,16 +32,12 @@
 import com.android.internal.widget.NotificationExpandButton;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
-import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
 import com.android.systemui.statusbar.ViewTransformationHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 import java.util.Stack;
 
-import static com.android.systemui.statusbar.notification.TransformState.TRANSFORM_Y;
-
 /**
  * Wraps a notification header view.
  */
@@ -50,7 +46,6 @@
     private static final Interpolator LOW_PRIORITY_HEADER_CLOSE
             = new PathInterpolator(0.4f, 0f, 0.7f, 1f);
 
-    protected final ViewInvertHelper mInvertHelper;
     protected final ViewTransformationHelper mTransformationHelper;
     private final int mTranslationForHeader;
 
@@ -70,7 +65,6 @@
         super(ctx, view, row);
         mShowExpandButtonAtEnd = ctx.getResources().getBoolean(
                 R.bool.config_showNotificationExpandButtonAtEnd);
-        mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
         // we want to avoid that the header clashes with the other text when transforming
@@ -99,7 +93,6 @@
                     }
                 }, TRANSFORMING_VIEW_TITLE);
         resolveHeaderViews();
-        updateInvertHelper();
         addAppOpsOnClickListener(row);
         mTranslationForHeader = ctx.getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin)
@@ -107,16 +100,6 @@
                         com.android.internal.R.dimen.notification_content_margin_top);
     }
 
-    @Override
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationIconDozeHelper(ctx);
-    }
-
-    @Override
-    protected NotificationIconDozeHelper getDozer() {
-        return (NotificationIconDozeHelper) super.getDozer();
-    }
-
     protected void resolveHeaderViews() {
         mIcon = mView.findViewById(com.android.internal.R.id.icon);
         mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
@@ -125,7 +108,6 @@
         mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
         mNotificationHeader.setShowExpandButtonAtEnd(mShowExpandButtonAtEnd);
         mColor = mNotificationHeader.getOriginalIconColor();
-        getDozer().setColor(mColor);
     }
 
     private void addAppOpsOnClickListener(ExpandableNotificationRow row) {
@@ -141,7 +123,6 @@
 
         // Reinspect the notification.
         resolveHeaderViews();
-        updateInvertHelper();
         updateTransformedTypes();
         addRemainingTransformTypes();
         updateCropToPaddingForImageViews();
@@ -192,16 +173,6 @@
         }
     }
 
-    protected void updateInvertHelper() {
-        mInvertHelper.clearTargets();
-        for (int i = 0; i < mNotificationHeader.getChildCount(); i++) {
-            View child = mNotificationHeader.getChildAt(i);
-            if (child != mIcon) {
-                mInvertHelper.addTarget(child);
-            }
-        }
-    }
-
     protected void updateTransformedTypes() {
         mTransformationHelper.reset();
         mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_ICON, mIcon);
@@ -212,27 +183,6 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        if (fade) {
-            mInvertHelper.fade(dark, delay);
-        } else {
-            mInvertHelper.update(dark);
-        }
-        if (mIcon != null && !mRow.isChildInGroup()) {
-            // We don't update the color for children views / their icon is invisible anyway.
-            // It also may lead to bugs where the icon isn't correctly greyed out.
-            boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
-                    != NotificationHeaderView.NO_COLOR;
-
-            getDozer().setImageDark(mIcon, dark, fade, delay, !hadColorFilter);
-        }
-    }
-
-    @Override
     public void updateExpandability(boolean expandable, View.OnClickListener onClickListener) {
         mExpandButton.setVisibility(expandable ? View.VISIBLE : View.GONE);
         mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 2a47fe0..2d983c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -45,8 +45,6 @@
  */
 public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
 
-    private static final int mDarkProgressTint = 0xffffffff;
-
     protected ImageView mPicture;
     private ProgressBar mProgressBar;
     private TextView mTitle;
@@ -275,15 +273,6 @@
     }
 
     @Override
-    protected void updateInvertHelper() {
-        super.updateInvertHelper();
-        View mainColumn = mView.findViewById(com.android.internal.R.id.notification_main_column);
-        if (mainColumn != null) {
-            mInvertHelper.addTarget(mainColumn);
-        }
-    }
-
-    @Override
     protected void updateTransformedTypes() {
         // This also clears the existing types
         super.updateTransformedTypes();
@@ -306,65 +295,6 @@
     }
 
     @Override
-    public void setDark(boolean dark, boolean fade, long delay) {
-        if (dark == mDark && mDarkInitialized) {
-            return;
-        }
-        super.setDark(dark, fade, delay);
-        setPictureDark(dark, fade, delay);
-        setProgressBarDark(dark, fade, delay);
-    }
-
-    private void setProgressBarDark(boolean dark, boolean fade, long delay) {
-        if (mProgressBar != null) {
-            if (fade) {
-                fadeProgressDark(mProgressBar, dark, delay);
-            } else {
-                updateProgressDark(mProgressBar, dark);
-            }
-        }
-    }
-
-    private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) {
-        getDozer().startIntensityAnimation(animation -> {
-            float t = (float) animation.getAnimatedValue();
-            updateProgressDark(target, t);
-        }, dark, delay, null /* listener */);
-    }
-
-    private void updateProgressDark(ProgressBar target, float intensity) {
-        int color = interpolateColor(mColor, mDarkProgressTint, intensity);
-        target.getIndeterminateDrawable().mutate().setTint(color);
-        target.getProgressDrawable().mutate().setTint(color);
-    }
-
-    private void updateProgressDark(ProgressBar target, boolean dark) {
-        updateProgressDark(target, dark ? 1f : 0f);
-    }
-
-    private void setPictureDark(boolean dark, boolean fade, long delay) {
-        if (mPicture != null) {
-            getDozer().setImageDark(mPicture, dark, fade, delay, true /* useGrayscale */);
-        }
-    }
-
-    private static int interpolateColor(int source, int target, float t) {
-        int aSource = Color.alpha(source);
-        int rSource = Color.red(source);
-        int gSource = Color.green(source);
-        int bSource = Color.blue(source);
-        int aTarget = Color.alpha(target);
-        int rTarget = Color.red(target);
-        int gTarget = Color.green(target);
-        int bTarget = Color.blue(target);
-        return Color.argb(
-                (int) (aSource * (1f - t) + aTarget * t),
-                (int) (rSource * (1f - t) + rTarget * t),
-                (int) (gSource * (1f - t) + gTarget * t),
-                (int) (bSource * (1f - t) + bTarget * t));
-    }
-
-    @Override
     public void setContentHeight(int contentHeight, int minHeightHint) {
         super.setContentHeight(contentHeight, minHeightHint);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 93a9947..93058b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -17,10 +17,8 @@
 package com.android.systemui.statusbar.notification;
 
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.support.v4.graphics.ColorUtils;
 import android.view.NotificationHeaderView;
 import android.view.View;
 
@@ -36,12 +34,8 @@
 
     protected final View mView;
     protected final ExpandableNotificationRow mRow;
-    private final NotificationDozeHelper mDozer;
 
-    protected boolean mDark;
     private int mBackgroundColor = 0;
-    protected boolean mShouldInvertDark;
-    protected boolean mDarkInitialized = false;
 
     public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
@@ -65,36 +59,14 @@
     protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         mView = view;
         mRow = row;
-        mDozer = createDozer(ctx);
         onReinflated();
     }
 
-    protected NotificationDozeHelper createDozer(Context ctx) {
-        return new NotificationDozeHelper();
-    }
-
-    protected NotificationDozeHelper getDozer() {
-        return mDozer;
-    }
-
-    /**
-     * In dark mode, we draw as little as possible, assuming a black background.
-     *
-     * @param dark whether we should display ourselves in dark mode
-     * @param fade whether to animate the transition if the mode changes
-     * @param delay if fading, the delay of the animation
-     */
-    public void setDark(boolean dark, boolean fade, long delay) {
-        mDark = dark;
-        mDarkInitialized = true;
-    }
-
     /**
      * Notifies this wrapper that the content of the view might have changed.
      * @param row the row this wrapper is attached to
      */
     public void onContentUpdated(ExpandableNotificationRow row) {
-        mDarkInitialized = false;
     }
 
     public void onReinflated() {
@@ -106,18 +78,12 @@
             mBackgroundColor = ((ColorDrawable) background).getColor();
             mView.setBackground(null);
         }
-        mShouldInvertDark = mBackgroundColor == 0 || isColorLight(mBackgroundColor);
     }
 
     protected boolean shouldClearBackgroundOnReapply() {
         return true;
     }
 
-    private boolean isColorLight(int backgroundColor) {
-        return Color.alpha(backgroundColor) == 0
-                || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
-    }
-
     /**
      * Update the appearance of the expand button.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a323e08..5c14015 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -5160,7 +5160,9 @@
                 if (parentToCancelFinal != null) {
                     removeNotification(parentToCancelFinal);
                 }
-                if (shouldAutoCancel(sbn)) {
+                if (shouldAutoCancel(sbn)
+                        || mRemoteInputManager.getKeysKeptForRemoteInput().contains(
+                                notificationKey)) {
                     // Automatically remove all notifications that we may have kept around longer
                     removeNotification(sbn);
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 45fa44c..2dd3d4e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -1168,7 +1168,6 @@
         if (mOverflowNumber != null) {
             mHybridGroupManager.setOverflowNumberDark(mOverflowNumber, dark, fade, delay);
         }
-        mNotificationHeaderWrapper.setDark(dark, fade, delay);
     }
 
     public void reInflateViews(OnClickListener listener, StatusBarNotification notification) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b32ece7..6f572df 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -476,12 +476,23 @@
                 Slog.w(TAG, "Background start not allowed: service "
                         + service + " to " + r.name.flattenToShortString()
                         + " from pid=" + callingPid + " uid=" + callingUid
-                        + " pkg=" + callingPackage);
+                        + " pkg=" + callingPackage + " startFg?=" + fgRequired);
                 if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {
                     // In this case we are silently disabling the app, to disrupt as
                     // little as possible existing apps.
                     return null;
                 }
+                if (forcedStandby) {
+                    // This is an O+ app, but we might be here because the user has placed
+                    // it under strict background restrictions.  Don't punish the app if it's
+                    // trying to do the right thing but we're denying it for that reason.
+                    if (fgRequired) {
+                        if (DEBUG_BACKGROUND_CHECK) {
+                            Slog.v(TAG, "Silently dropping foreground service launch due to FAS");
+                        }
+                        return null;
+                    }
+                }
                 // This app knows it is in the new model where this operation is not
                 // allowed, so tell it what has happened.
                 UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
@@ -3592,6 +3603,21 @@
         }
     }
 
+    public void updateServiceApplicationInfoLocked(ApplicationInfo applicationInfo) {
+        final int userId = UserHandle.getUserId(applicationInfo.uid);
+        ServiceMap serviceMap = mServiceMap.get(userId);
+        if (serviceMap != null) {
+            ArrayMap<ComponentName, ServiceRecord> servicesByName = serviceMap.mServicesByName;
+            for (int j = servicesByName.size() - 1; j >= 0; j--) {
+                ServiceRecord serviceRecord = servicesByName.valueAt(j);
+                if (applicationInfo.packageName.equals(serviceRecord.appInfo.packageName)) {
+                    serviceRecord.appInfo = applicationInfo;
+                    serviceRecord.serviceInfo.applicationInfo = applicationInfo;
+                }
+            }
+        }
+    }
+
     void serviceForegroundCrash(ProcessRecord app, CharSequence serviceRecord) {
         mAm.crashApplication(app.uid, app.pid, app.info.packageName, app.userId,
                 "Context.startForegroundService() did not then call Service.startForeground(): "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cddda58..70648c6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -21455,6 +21455,7 @@
                             return ActivityManager.BROADCAST_SUCCESS;
                         }
                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+                        mServices.updateServiceApplicationInfoLocked(aInfo);
                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
                                 new String[] {ssp}, userId);
                     }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index e73f42f..73710d3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1927,11 +1927,12 @@
         if (displayStartTime != 0) {
             reportLaunchTimeLocked(curTime);
         }
-        final ActivityStack stack = getStack();
-        if (fullyDrawnStartTime != 0 && stack != null) {
+        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
+                getWindowingMode());
+        if (fullyDrawnStartTime != 0 && entry != null) {
             final long thisTime = curTime - fullyDrawnStartTime;
-            final long totalTime = stack.mFullyDrawnStartTime != 0
-                    ? (curTime - stack.mFullyDrawnStartTime) : thisTime;
+            final long totalTime = entry.mFullyDrawnStartTime != 0
+                    ? (curTime - entry.mFullyDrawnStartTime) : thisTime;
             if (SHOW_ACTIVITY_START_TIME) {
                 Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
                 EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
@@ -1953,7 +1954,7 @@
             if (totalTime > 0) {
                 //service.mUsageStatsService.noteFullyDrawnTime(realActivity, (int) totalTime);
             }
-            stack.mFullyDrawnStartTime = 0;
+            entry.mFullyDrawnStartTime = 0;
         }
         mStackSupervisor.getActivityMetricsLogger().logAppTransitionReportedDrawn(this,
                 restoredFromBundle);
@@ -1961,13 +1962,14 @@
     }
 
     private void reportLaunchTimeLocked(final long curTime) {
-        final ActivityStack stack = getStack();
-        if (stack == null) {
+        final LaunchTimeTracker.Entry entry = mStackSupervisor.getLaunchTimeTracker().getEntry(
+                getWindowingMode());
+        if (entry == null) {
             return;
         }
         final long thisTime = curTime - displayStartTime;
-        final long totalTime = stack.mLaunchStartTime != 0
-                ? (curTime - stack.mLaunchStartTime) : thisTime;
+        final long totalTime = entry.mLaunchStartTime != 0
+                ? (curTime - entry.mLaunchStartTime) : thisTime;
         if (SHOW_ACTIVITY_START_TIME) {
             Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
             EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
@@ -1991,7 +1993,7 @@
             //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
         }
         displayStartTime = 0;
-        stack.mLaunchStartTime = 0;
+        entry.mLaunchStartTime = 0;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c182502..818a609 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -339,9 +339,6 @@
     private final Rect mDeferredTaskBounds = new Rect();
     private final Rect mDeferredTaskInsetBounds = new Rect();
 
-    long mLaunchStartTime = 0;
-    long mFullyDrawnStartTime = 0;
-
     int mCurrentUser;
 
     final int mStackId;
@@ -1257,39 +1254,11 @@
                 + " callers=" + Debug.getCallers(5));
         r.setState(RESUMED, "minimalResumeActivityLocked");
         r.completeResumeLocked();
-        setLaunchTime(r);
+        mStackSupervisor.getLaunchTimeTracker().setLaunchTime(r);
         if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                 "Launch completed; removing icicle of " + r.icicle);
     }
 
-    private void startLaunchTraces(String packageName) {
-        if (mFullyDrawnStartTime != 0)  {
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-        }
-        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
-        Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-    }
-
-    private void stopFullyDrawnTraceIfNeeded() {
-        if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-            mFullyDrawnStartTime = 0;
-        }
-    }
-
-    void setLaunchTime(ActivityRecord r) {
-        if (r.displayStartTime == 0) {
-            r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
-            if (mLaunchStartTime == 0) {
-                startLaunchTraces(r.packageName);
-                mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
-            }
-        } else if (mLaunchStartTime == 0) {
-            startLaunchTraces(r.packageName);
-            mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
-        }
-    }
-
     private void clearLaunchTime(ActivityRecord r) {
         // Make sure that there is no activity waiting for this to launch.
         if (mStackSupervisor.mWaitingActivityLaunched.isEmpty()) {
@@ -1477,9 +1446,8 @@
         prev.setState(PAUSING, "startPausingLocked");
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
-        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
 
-        stopFullyDrawnTraceIfNeeded();
+        mStackSupervisor.getLaunchTimeTracker().stopFullyDrawnTraceIfNeeded(getWindowingMode());
 
         mService.updateCpuStats();
 
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index df1ee55..afad0b1 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -445,6 +445,7 @@
     private boolean mTaskLayersChanged = true;
 
     private ActivityMetricsLogger mActivityMetricsLogger;
+    private LaunchTimeTracker mLaunchTimeTracker = new LaunchTimeTracker();
 
     private final ArrayList<ActivityRecord> mTmpActivityList = new ArrayList<>();
 
@@ -629,6 +630,10 @@
         return mActivityMetricsLogger;
     }
 
+    LaunchTimeTracker getLaunchTimeTracker() {
+        return mLaunchTimeTracker;
+    }
+
     public KeyguardController getKeyguardController() {
         return mKeyguardController;
     }
@@ -1646,7 +1651,7 @@
         ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                 r.info.applicationInfo.uid, true);
 
-        r.getStack().setLaunchTime(r);
+        getLaunchTimeTracker().setLaunchTime(r);
 
         if (app != null && app.thread != null) {
             try {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 0104980..ad434b4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1587,6 +1587,7 @@
                     }
                 }
             } else if (mOptions.getAvoidMoveToFront()) {
+                mDoResume = false;
                 mAvoidMoveToFront = true;
             }
         }
@@ -1929,7 +1930,7 @@
         // Need to update mTargetStack because if task was moved out of it, the original stack may
         // be destroyed.
         mTargetStack = intentActivity.getStack();
-        if (!mAvoidMoveToFront && !mMovedToFront && mDoResume) {
+        if (!mMovedToFront && mDoResume) {
             if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Bring to front target: " + mTargetStack
                     + " from " + intentActivity);
             mTargetStack.moveToFront("intentActivityFound");
diff --git a/services/core/java/com/android/server/am/LaunchTimeTracker.java b/services/core/java/com/android/server/am/LaunchTimeTracker.java
new file mode 100644
index 0000000..ee86969
--- /dev/null
+++ b/services/core/java/com/android/server/am/LaunchTimeTracker.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.server.am;
+
+import android.app.WaitResult;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.SparseArray;
+
+/**
+ * Tracks launch time of apps to be reported by {@link WaitResult}. Note that this is slightly
+ * different from {@link ActivityMetricsLogger}, but should eventually merged with it.
+ */
+class LaunchTimeTracker {
+
+    private final SparseArray<Entry> mWindowingModeLaunchTime = new SparseArray<>();
+
+    void setLaunchTime(ActivityRecord r) {
+        Entry entry = mWindowingModeLaunchTime.get(r.getWindowingMode());
+        if (entry == null){
+            entry = new Entry();
+            mWindowingModeLaunchTime.append(r.getWindowingMode(), entry);
+        }
+        entry.setLaunchTime(r);
+    }
+
+    void stopFullyDrawnTraceIfNeeded(int windowingMode) {
+        final Entry entry = mWindowingModeLaunchTime.get(windowingMode);
+        if (entry == null) {
+            return;
+        }
+        entry.stopFullyDrawnTraceIfNeeded();
+    }
+
+    Entry getEntry(int windowingMode) {
+        return mWindowingModeLaunchTime.get(windowingMode);
+    }
+
+    static class Entry {
+
+        long mLaunchStartTime;
+        long mFullyDrawnStartTime;
+
+        void setLaunchTime(ActivityRecord r) {
+            if (r.displayStartTime == 0) {
+                r.fullyDrawnStartTime = r.displayStartTime = SystemClock.uptimeMillis();
+                if (mLaunchStartTime == 0) {
+                    startLaunchTraces(r.packageName);
+                    mLaunchStartTime = mFullyDrawnStartTime = r.displayStartTime;
+                }
+            } else if (mLaunchStartTime == 0) {
+                startLaunchTraces(r.packageName);
+                mLaunchStartTime = mFullyDrawnStartTime = SystemClock.uptimeMillis();
+            }
+        }
+
+        private void startLaunchTraces(String packageName) {
+            if (mFullyDrawnStartTime != 0)  {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+            }
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+        }
+
+        private void stopFullyDrawnTraceIfNeeded() {
+            if (mFullyDrawnStartTime != 0 && mLaunchStartTime == 0) {
+                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+                mFullyDrawnStartTime = 0;
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index a3d2173..67230c3 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -169,6 +169,7 @@
                         .setMayWait(mUserController.getCurrentUserId())
                         .execute();
                 mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+                mWindowManager.executeAppTransition();
 
                 targetActivity = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
                         mTargetActivityType).getTopActivity();
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index 0fb69e7..55d17a9 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -79,9 +79,6 @@
         mOriginalCallingPid = Binder.getCallingPid();
         mOriginalCallingUid = Binder.getCallingUid();
         mOriginalOptions = options;
-        if (mOriginalCallingPid == Process.myPid()) {
-            Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
-        }
     }
 
     /**
@@ -93,9 +90,6 @@
         mRealCallingPid = Binder.getCallingPid();
         mRealCallingUid = Binder.getCallingUid();
         mCallerOptions = options;
-        if (mRealCallingPid == Process.myPid()) {
-            Slog.wtf(TAG, "setCallerOptions called after clearing calling id");
-        }
     }
 
     /**
@@ -128,20 +122,28 @@
         if (mOriginalOptions != null) {
             checkPermissions(intent, aInfo, callerApp, supervisor, mOriginalOptions,
                     mOriginalCallingPid, mOriginalCallingUid);
-            if (mOriginalOptions.getRemoteAnimationAdapter() != null) {
-                mOriginalOptions.getRemoteAnimationAdapter().setCallingPid(mOriginalCallingPid);
-            }
+            setCallingPidForRemoteAnimationAdapter(mOriginalOptions, mOriginalCallingPid);
         }
         if (mCallerOptions != null) {
             checkPermissions(intent, aInfo, callerApp, supervisor, mCallerOptions,
                     mRealCallingPid, mRealCallingUid);
-            if (mCallerOptions.getRemoteAnimationAdapter() != null) {
-                mCallerOptions.getRemoteAnimationAdapter().setCallingPid(mRealCallingPid);
-            }
+            setCallingPidForRemoteAnimationAdapter(mCallerOptions, mRealCallingPid);
         }
         return mergeActivityOptions(mOriginalOptions, mCallerOptions);
     }
 
+    private void setCallingPidForRemoteAnimationAdapter(ActivityOptions options, int callingPid) {
+        final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
+        if (adapter == null) {
+            return;
+        }
+        if (callingPid == Process.myPid()) {
+            Slog.wtf(TAG, "Safe activity options constructed after clearing calling id");
+            return;
+        }
+        adapter.setCallingPid(callingPid);
+    }
+
     /**
      * @see ActivityOptions#popAppVerificationBundle
      */
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 32887e4..4d89d015 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -73,7 +73,7 @@
                             // original intent used to find service.
     final ServiceInfo serviceInfo;
                             // all information about the service.
-    final ApplicationInfo appInfo;
+    ApplicationInfo appInfo;
                             // information about service's app.
     final int userId;       // user that this service is running as
     final String packageName; // the package implementing intent's component
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 891ee2e..2fbb846 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -800,34 +800,7 @@
     }
 
     private void updateBoundsForWindowModeChange() {
-        Rect bounds = null;
-        final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
-        final TaskStack splitScreenStack =
-                mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
-        if (inSplitScreenPrimary || (splitScreenStack != null
-                && inSplitScreenSecondaryWindowingMode() && !splitScreenStack.fillsParent())) {
-            // The existence of a docked stack affects the size of other static stack created since
-            // the docked stack occupies a dedicated region on screen, but only if the dock stack is
-            // not fullscreen. If it's fullscreen, it means that we are in the transition of
-            // dismissing it, so we must not resize this stack.
-            bounds = new Rect();
-            mDisplayContent.getBounds(mTmpRect);
-            mTmpRect2.setEmpty();
-            if (splitScreenStack != null) {
-                splitScreenStack.getRawBounds(mTmpRect2);
-            }
-            final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
-                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-            getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
-                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
-        } else if (inPinnedWindowingMode()) {
-            // Update the bounds based on any changes to the display info
-            getAnimationOrCurrentBounds(mTmpRect2);
-            if (mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
-                    mTmpRect2, mTmpRect3)) {
-                bounds = new Rect(mTmpRect3);
-            }
-        }
+        final Rect bounds = calculateBoundsForWindowModeChange();
 
         if (inSplitScreenSecondaryWindowingMode()) {
             // When the stack is resized due to entering split screen secondary, offset the
@@ -841,6 +814,49 @@
         updateSurfaceBounds();
     }
 
+    private Rect calculateBoundsForWindowModeChange() {
+        final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
+        final TaskStack splitScreenStack =
+                mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+        if (inSplitScreenPrimary || (splitScreenStack != null
+                && inSplitScreenSecondaryWindowingMode() && !splitScreenStack.fillsParent())) {
+            // The existence of a docked stack affects the size of other static stack created since
+            // the docked stack occupies a dedicated region on screen, but only if the dock stack is
+            // not fullscreen. If it's fullscreen, it means that we are in the transition of
+            // dismissing it, so we must not resize this stack.
+            final Rect bounds = new Rect();
+            mDisplayContent.getBounds(mTmpRect);
+            mTmpRect2.setEmpty();
+            if (splitScreenStack != null) {
+                if (inSplitScreenSecondaryWindowingMode()
+                        && mDisplayContent.mDividerControllerLocked.isMinimizedDock()
+                        && splitScreenStack.getTopChild() != null) {
+                    // If the primary split screen stack is currently minimized, then don't use the
+                    // stack bounds of the minimized stack, instead, use the temporary task bounds
+                    // to calculate the appropriate uniminized size of any secondary split stack
+                    // TODO: Find a cleaner way for computing new stack bounds while minimized that
+                    //       doesn't assume the primary stack's task bounds as the temp task bounds
+                    splitScreenStack.getTopChild().getBounds(mTmpRect2);
+                } else {
+                    splitScreenStack.getRawBounds(mTmpRect2);
+                }
+            }
+            final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode
+                    == SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+            getStackDockedModeBounds(mTmpRect, bounds, mTmpRect2,
+                    mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft);
+            return bounds;
+        } else if (inPinnedWindowingMode()) {
+            // Update the bounds based on any changes to the display info
+            getAnimationOrCurrentBounds(mTmpRect2);
+            if (mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(
+                    mTmpRect2, mTmpRect3)) {
+                return new Rect(mTmpRect3);
+            }
+        }
+        return null;
+    }
+
     /**
      * Determines the stack and task bounds of the other stack when in docked mode. The current task
      * bounds is passed in but depending on the stack, the task and stack must match. Only in
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index d25fd3f..49fbd8f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -477,4 +477,5 @@
     int RIL_UNSOL_NETWORK_SCAN_RESULT = 1049;
     int RIL_UNSOL_ICC_SLOT_STATUS = 1050;
     int RIL_UNSOL_KEEPALIVE_STATUS = 1051;
+    int RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG = 1052;
 }
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index ffca466..a8411aa 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -486,12 +486,8 @@
     return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
 
 UNSUPPORTED_FLAGS = frozenset({
-    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('DG'),
-    flag_sequence('EA'), flag_sequence('EH'), flag_sequence('FK'),
-    flag_sequence('GF'), flag_sequence('GP'), flag_sequence('GS'),
-    flag_sequence('MF'), flag_sequence('MQ'), flag_sequence('NC'),
-    flag_sequence('PM'), flag_sequence('RE'), flag_sequence('TF'),
-    flag_sequence('WF'), flag_sequence('XK'), flag_sequence('YT'),
+    flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('MQ'),
+    flag_sequence('RE'), flag_sequence('TF'),
 })
 
 EQUIVALENT_FLAGS = {
@@ -531,10 +527,17 @@
 ZWJ_IDENTICALS = {
     # KISS
     (0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468): 0x1F48F,
-    # FAMILY
-    (0x1F468, 0x200D, 0x1F469, 0x200D, 0x1F466): 0x1F46A,
 }
 
+SAME_FLAG_MAPPINGS = [
+    # Diego Garcia and British Indian Ocean Territory
+    ((0x1F1EE, 0x1F1F4), (0x1F1E9, 0x1F1EC)),
+    # St. Martin and France
+    ((0x1F1F2, 0x1F1EB), (0x1F1EB, 0x1F1F7)),
+    # Spain and Ceuta & Melilla
+    ((0x1F1EA, 0x1F1F8), (0x1F1EA, 0x1F1E6)),
+]
+
 ZWJ = 0x200D
 FEMALE_SIGN = 0x2640
 MALE_SIGN = 0x2642
@@ -636,6 +639,9 @@
         all_sequences.add(reversed_seq)
         equivalent_emoji[reversed_seq] = sequence
 
+    for first, second in SAME_FLAG_MAPPINGS:
+        equivalent_emoji[first] = second
+
     # Remove unsupported flags
     all_sequences.difference_update(UNSUPPORTED_FLAGS)