Merge "Update mGlobalBluetoothA2dpOn when active device changed" into pi-dev
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fcab8c1..c58b91e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1555,6 +1555,7 @@
         private final long[] mRejectTimes;
         private final int mDuration;
         private final int mProxyUid;
+        private final boolean mRunning;
         private final String mProxyPackageName;
 
         public OpEntry(int op, int mode, long time, long rejectTime, int duration,
@@ -1566,12 +1567,13 @@
             mTimes[0] = time;
             mRejectTimes[0] = rejectTime;
             mDuration = duration;
+            mRunning = duration == -1;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
         }
 
         public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
-                int proxyUid, String proxyPackage) {
+                boolean running, int proxyUid, String proxyPackage) {
             mOp = op;
             mMode = mode;
             mTimes = new long[_NUM_UID_STATE];
@@ -1579,10 +1581,16 @@
             System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
             System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
             mDuration = duration;
+            mRunning = running;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
         }
 
+        public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
+                int proxyUid, String proxyPackage) {
+            this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage);
+        }
+
         public int getOp() {
             return mOp;
         }
@@ -1632,7 +1640,7 @@
         }
 
         public boolean isRunning() {
-            return mDuration == -1;
+            return mRunning;
         }
 
         public int getDuration() {
@@ -1659,6 +1667,7 @@
             dest.writeLongArray(mTimes);
             dest.writeLongArray(mRejectTimes);
             dest.writeInt(mDuration);
+            dest.writeBoolean(mRunning);
             dest.writeInt(mProxyUid);
             dest.writeString(mProxyPackageName);
         }
@@ -1669,6 +1678,7 @@
             mTimes = source.createLongArray();
             mRejectTimes = source.createLongArray();
             mDuration = source.readInt();
+            mRunning = source.readBoolean();
             mProxyUid = source.readInt();
             mProxyPackageName = source.readString();
         }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 15aedd7..63de8bf 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1664,7 +1664,8 @@
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device includes at least one form of audio
-     * output, such as speakers, audio jack or streaming over bluetooth
+     * output, as defined in the Android Compatibility Definition Document (CDD)
+     * <a href="https://source.android.com/compatibility/android-cdd#7_8_audio">section 7.8 Audio</a>.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 2d8b4d4..c861499 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -43,7 +43,7 @@
         DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false");
         DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
         DEFAULT_FLAGS.put("settings_audio_switcher", "true");
-        DEFAULT_FLAGS.put("settings_systemui_theme", "false");
+        DEFAULT_FLAGS.put("settings_systemui_theme", "true");
     }
 
     /**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 7c814f4..ed67075 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1630,6 +1630,8 @@
                         contentInsets.top + outsets.top, contentInsets.right + outsets.right,
                         contentInsets.bottom + outsets.bottom);
             }
+            contentInsets = ensureInsetsNonNegative(contentInsets, "content");
+            stableInsets = ensureInsetsNonNegative(stableInsets, "stable");
             mLastWindowInsets = new WindowInsets(contentInsets,
                     null /* windowDecorInsets */, stableInsets,
                     mContext.getResources().getConfiguration().isScreenRound(),
@@ -1638,6 +1640,17 @@
         return mLastWindowInsets;
     }
 
+    private Rect ensureInsetsNonNegative(Rect insets, String kind) {
+        if (insets.left < 0  || insets.top < 0  || insets.right < 0  || insets.bottom < 0) {
+            Log.wtf(mTag, "Negative " + kind + "Insets: " + insets + ", mFirst=" + mFirst);
+            return new Rect(Math.max(0, insets.left),
+                    Math.max(0, insets.top),
+                    Math.max(0, insets.right),
+                    Math.max(0, insets.bottom));
+        }
+        return insets;
+    }
+
     void dispatchApplyInsets(View host) {
         WindowInsets insets = getWindowInsets(true /* forceConstruct */);
         final boolean dispatchCutout = (mWindowAttributes.layoutInDisplayCutoutMode
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 2940079..9171959 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -156,9 +156,12 @@
         if (activeServiceSupportsAssistGesture()) {
             return getActiveServiceComponentName();
         }
-
-        Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
-                .getAssistIntent(false);
+        final SearchManager searchManager =
+            (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+        if (searchManager == null) {
+            return null;
+        }
+        final Intent intent = searchManager.getAssistIntent(false);
         PackageManager pm = mContext.getPackageManager();
         ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_DEFAULT_ONLY,
                 userId);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 571878d..4f567d2 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -76,6 +76,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.ResolverActivity;
 import com.android.internal.app.ResolverActivity.TargetInfo;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -932,7 +933,7 @@
         public static final int TARGET_SERVICE = 1;
         public static final int TARGET_STANDARD = 2;
 
-        private static final int MAX_SERVICE_TARGETS = 8;
+        private static final int MAX_SERVICE_TARGETS = 4;
         private static final int MAX_TARGETS_PER_SERVICE = 4;
 
         private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
@@ -1189,123 +1190,20 @@
         }
     }
 
-    static class RowScale {
-        private static final int DURATION = 400;
-
-        float mScale;
-        ChooserRowAdapter mAdapter;
-        private final ObjectAnimator mAnimator;
-
-        public static final FloatProperty<RowScale> PROPERTY =
-                new FloatProperty<RowScale>("scale") {
-            @Override
-            public void setValue(RowScale object, float value) {
-                object.mScale = value;
-                object.mAdapter.notifyDataSetChanged();
-            }
-
-            @Override
-            public Float get(RowScale object) {
-                return object.mScale;
-            }
-        };
-
-        public RowScale(@NonNull ChooserRowAdapter adapter, float from, float to) {
-            mAdapter = adapter;
-            mScale = from;
-            if (from == to) {
-                mAnimator = null;
-                return;
-            }
-
-            mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to)
-                .setDuration(DURATION);
-            mAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    mAdapter.onAnimationStart();
-                }
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mAdapter.onAnimationEnd();
-                }
-            });
-        }
-
-        public RowScale setInterpolator(Interpolator interpolator) {
-            if (mAnimator != null) {
-                mAnimator.setInterpolator(interpolator);
-            }
-            return this;
-        }
-
-        public float get() {
-            return mScale;
-        }
-
-        public void startAnimation() {
-            if (mAnimator != null) {
-                mAnimator.start();
-            }
-        }
-
-        public void cancelAnimation() {
-            if (mAnimator != null) {
-                mAnimator.cancel();
-            }
-        }
-    }
-
     class ChooserRowAdapter extends BaseAdapter {
         private ChooserListAdapter mChooserListAdapter;
         private final LayoutInflater mLayoutInflater;
         private final int mColumnCount = 4;
-        private RowScale[] mServiceTargetScale;
-        private final Interpolator mInterpolator;
         private int mAnimationCount = 0;
 
         public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
             mChooserListAdapter = wrappedAdapter;
             mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
 
-            mInterpolator = AnimationUtils.loadInterpolator(ChooserActivity.this,
-                    android.R.interpolator.decelerate_quint);
-
             wrappedAdapter.registerDataSetObserver(new DataSetObserver() {
                 @Override
                 public void onChanged() {
                     super.onChanged();
-                    final int rcount = getServiceTargetRowCount();
-                    if (mServiceTargetScale == null
-                            || mServiceTargetScale.length != rcount) {
-                        RowScale[] old = mServiceTargetScale;
-                        int oldRCount = old != null ? old.length : 0;
-                        mServiceTargetScale = new RowScale[rcount];
-                        if (old != null && rcount > 0) {
-                            System.arraycopy(old, 0, mServiceTargetScale, 0,
-                                    Math.min(old.length, rcount));
-                        }
-
-                        for (int i = rcount; i < oldRCount; i++) {
-                            old[i].cancelAnimation();
-                        }
-
-                        for (int i = oldRCount; i < rcount; i++) {
-                            final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
-                                    .setInterpolator(mInterpolator);
-                            mServiceTargetScale[i] = rs;
-                        }
-
-                        // Start the animations in a separate loop.
-                        // The process of starting animations will result in
-                        // binding views to set up initial values, and we must
-                        // have ALL of the new RowScale objects created above before
-                        // we get started.
-                        for (int i = oldRCount; i < rcount; i++) {
-                            mServiceTargetScale[i].startAnimation();
-                        }
-                    }
-
                     notifyDataSetChanged();
                 }
 
@@ -1313,39 +1211,10 @@
                 public void onInvalidated() {
                     super.onInvalidated();
                     notifyDataSetInvalidated();
-                    if (mServiceTargetScale != null) {
-                        for (RowScale rs : mServiceTargetScale) {
-                            rs.cancelAnimation();
-                        }
-                    }
                 }
             });
         }
 
-        private float getRowScale(int rowPosition) {
-            final int start = getCallerTargetRowCount();
-            final int end = start + getServiceTargetRowCount();
-            if (rowPosition >= start && rowPosition < end) {
-                return mServiceTargetScale[rowPosition - start].get();
-            }
-            return 1.f;
-        }
-
-        public void onAnimationStart() {
-            final boolean lock = mAnimationCount == 0;
-            mAnimationCount++;
-            if (lock) {
-                mResolverDrawerLayout.setDismissLocked(true);
-            }
-        }
-
-        public void onAnimationEnd() {
-            mAnimationCount--;
-            if (mAnimationCount == 0) {
-                mResolverDrawerLayout.setDismissLocked(false);
-            }
-        }
-
         @Override
         public int getCount() {
             return (int) (
@@ -1360,9 +1229,9 @@
                     (float) mChooserListAdapter.getCallerTargetCount() / mColumnCount);
         }
 
+        // There can be at most one row of service targets.
         public int getServiceTargetRowCount() {
-            return (int) Math.ceil(
-                    (float) mChooserListAdapter.getServiceTargetCount() / mColumnCount);
+            return (int) mChooserListAdapter.getServiceTargetCount() == 0 ? 0 : 1;
         }
 
         @Override
@@ -1485,8 +1354,7 @@
             }
 
             final int oldHeight = holder.row.getLayoutParams().height;
-            holder.row.getLayoutParams().height = Math.max(1,
-                    (int) (holder.measuredRowHeight * getRowScale(rowPosition)));
+            holder.row.getLayoutParams().height = Math.max(1, holder.measuredRowHeight);
             if (holder.row.getLayoutParams().height != oldHeight) {
                 holder.row.requestLayout();
             }
@@ -1728,7 +1596,7 @@
                 final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
                 int height = ((RowViewHolder) (v.getTag())).measuredRowHeight;
 
-                offset += (int) (height * mChooserRowAdapter.getRowScale(pos));
+                offset += (int) (height);
 
                 if (vt >= 0) {
                     mCachedViewType = vt;
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index d135040..c9a9161 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -100,7 +100,6 @@
         super.onFinishInflate();
         mMessageContainer = findViewById(R.id.group_message_container);
         mSenderName = findViewById(R.id.message_name);
-        mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
         mAvatarView = findViewById(R.id.message_icon);
         mImageContainer = findViewById(R.id.messaging_group_icon_container);
         mSendingSpinner = findViewById(R.id.messaging_group_sending_progress);
@@ -190,73 +189,66 @@
     }
 
     public void removeMessage(MessagingMessage messagingMessage) {
-        ViewGroup messageParent = (ViewGroup) messagingMessage.getView().getParent();
-        messageParent.removeView(messagingMessage.getView());
+        View view = messagingMessage.getView();
+        boolean wasShown = view.isShown();
+        ViewGroup messageParent = (ViewGroup) view.getParent();
+        if (messageParent == null) {
+            return;
+        }
+        messageParent.removeView(view);
         Runnable recycleRunnable = () -> {
-            messageParent.removeTransientView(messagingMessage.getView());
+            messageParent.removeTransientView(view);
             messagingMessage.recycle();
-            if (mMessageContainer.getChildCount() == 0
-                    && mMessageContainer.getTransientViewCount() == 0
-                    && mImageContainer.getChildCount() == 0) {
-                ViewParent parent = getParent();
-                if (parent instanceof ViewGroup) {
-                    ((ViewGroup) parent).removeView(MessagingGroup.this);
-                }
-                setAvatar(null);
-                mAvatarView.setAlpha(1.0f);
-                mAvatarView.setTranslationY(0.0f);
-                mSenderName.setAlpha(1.0f);
-                mSenderName.setTranslationY(0.0f);
-                mIsolatedMessage = null;
-                mMessages = null;
-                sInstancePool.release(MessagingGroup.this);
-            }
         };
-        if (isShown()) {
-            messageParent.addTransientView(messagingMessage.getView(), 0);
-            performRemoveAnimation(messagingMessage.getView(), recycleRunnable);
-            if (mMessageContainer.getChildCount() == 0
-                    && mImageContainer.getChildCount() == 0) {
-                removeGroupAnimated(null);
-            }
+        if (wasShown && !MessagingLinearLayout.isGone(view)) {
+            messageParent.addTransientView(view, 0);
+            performRemoveAnimation(view, recycleRunnable);
         } else {
             recycleRunnable.run();
         }
-
     }
 
-    private void removeGroupAnimated(Runnable endAction) {
-        performRemoveAnimation(mAvatarView, null);
-        performRemoveAnimation(mSenderName, null);
-        boolean endActionTriggered = false;
-        for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) {
-            View child = mMessageContainer.getChildAt(i);
-            if (child.getVisibility() == View.GONE) {
-                continue;
-            }
-            final ViewGroup.LayoutParams lp = child.getLayoutParams();
-            if (lp instanceof MessagingLinearLayout.LayoutParams
-                    && ((MessagingLinearLayout.LayoutParams) lp).hide
-                    && !((MessagingLinearLayout.LayoutParams) lp).visibleBefore) {
-                continue;
-            }
-            Runnable childEndAction = endActionTriggered ? null : endAction;
-            performRemoveAnimation(child, childEndAction);
-            endActionTriggered = true;
-        }
+    public void recycle() {
         if (mIsolatedMessage != null) {
-            performRemoveAnimation(mIsolatedMessage, !endActionTriggered ? endAction : null);
-            endActionTriggered = true;
+            mImageContainer.removeView(mIsolatedMessage);
         }
-        if (!endActionTriggered && endAction != null) {
-            endAction.run();
+        for (int i = 0; i < mMessages.size(); i++) {
+            MessagingMessage message = mMessages.get(i);
+            mMessageContainer.removeView(message.getView());
+            message.recycle();
         }
+        setAvatar(null);
+        mAvatarView.setAlpha(1.0f);
+        mAvatarView.setTranslationY(0.0f);
+        mSenderName.setAlpha(1.0f);
+        mSenderName.setTranslationY(0.0f);
+        setAlpha(1.0f);
+        mIsolatedMessage = null;
+        mMessages = null;
+        mAddedMessages.clear();
+        mFirstLayout = true;
+        MessagingPropertyAnimator.recycle(this);
+        sInstancePool.release(MessagingGroup.this);
+    }
+
+    public void removeGroupAnimated(Runnable endAction) {
+        performRemoveAnimation(this, () -> {
+            setAlpha(1.0f);
+            MessagingPropertyAnimator.setToLaidOutPosition(this);
+            if (endAction != null) {
+                endAction.run();
+            }
+        });
     }
 
     public void performRemoveAnimation(View message, Runnable endAction) {
-        MessagingPropertyAnimator.fadeOut(message, endAction);
-        MessagingPropertyAnimator.startLocalTranslationTo(message,
-                (int) (-getHeight() * 0.5f), MessagingLayout.FAST_OUT_LINEAR_IN);
+        performRemoveAnimation(message, -message.getHeight(), endAction);
+    }
+
+    private void performRemoveAnimation(View view, int disappearTranslation, Runnable endAction) {
+        MessagingPropertyAnimator.startLocalTranslationTo(view, disappearTranslation,
+                MessagingLayout.FAST_OUT_LINEAR_IN);
+        MessagingPropertyAnimator.fadeOut(view, endAction);
     }
 
     public CharSequence getSenderName() {
@@ -341,6 +333,11 @@
         }
     }
 
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+
     public Icon getAvatarSymbolIfMatching(CharSequence avatarName, String avatarSymbol,
             int layoutColor) {
         if (mAvatarName.equals(avatarName) && mAvatarSymbol.equals(avatarSymbol)
@@ -458,6 +455,7 @@
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
         if (!mAddedMessages.isEmpty()) {
+            final boolean firstLayout = mFirstLayout;
             getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                 @Override
                 public boolean onPreDraw() {
@@ -466,7 +464,7 @@
                             continue;
                         }
                         MessagingPropertyAnimator.fadeIn(message.getView());
-                        if (!mFirstLayout) {
+                        if (!firstLayout) {
                             MessagingPropertyAnimator.startLocalTranslationFrom(message.getView(),
                                     message.getView().getHeight(),
                                     MessagingLayout.LINEAR_OUT_SLOW_IN);
diff --git a/core/java/com/android/internal/widget/MessagingImageMessage.java b/core/java/com/android/internal/widget/MessagingImageMessage.java
index 9db74e8..607a3a9 100644
--- a/core/java/com/android/internal/widget/MessagingImageMessage.java
+++ b/core/java/com/android/internal/widget/MessagingImageMessage.java
@@ -170,8 +170,6 @@
 
     public void recycle() {
         MessagingMessage.super.recycle();
-        setAlpha(1.0f);
-        setTranslationY(0);
         setImageBitmap(null);
         mDrawable = null;
         sInstancePool.release(this);
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index 03a734d..0fd6109 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -180,8 +180,13 @@
         List<MessagingMessage> historicMessages = createMessages(newHistoricMessages,
                 true /* isHistoric */);
         List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */);
+
+        ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);
         addMessagesToGroups(historicMessages, messages, showSpinner);
 
+        // Let's first check which groups were removed altogether and remove them in one animation
+        removeGroups(oldGroups);
+
         // Let's remove the remaining messages
         mMessages.forEach(REMOVE_MESSAGE);
         mHistoricMessages.forEach(REMOVE_MESSAGE);
@@ -193,6 +198,31 @@
         updateTitleAndNamesDisplay();
     }
 
+    private void removeGroups(ArrayList<MessagingGroup> oldGroups) {
+        int size = oldGroups.size();
+        for (int i = 0; i < size; i++) {
+            MessagingGroup group = oldGroups.get(i);
+            if (!mGroups.contains(group)) {
+                List<MessagingMessage> messages = group.getMessages();
+                Runnable endRunnable = () -> {
+                    mMessagingLinearLayout.removeTransientView(group);
+                    group.recycle();
+                };
+
+                boolean wasShown = group.isShown();
+                mMessagingLinearLayout.removeView(group);
+                if (wasShown && !MessagingLinearLayout.isGone(group)) {
+                    mMessagingLinearLayout.addTransientView(group, 0);
+                    group.removeGroupAnimated(endRunnable);
+                } else {
+                    endRunnable.run();
+                }
+                mMessages.removeAll(messages);
+                mHistoricMessages.removeAll(messages);
+            }
+        }
+    }
+
     private void updateTitleAndNamesDisplay() {
         ArrayMap<CharSequence, String> uniqueNames = new ArrayMap<>();
         ArrayMap<Character, CharSequence> uniqueCharacters = new ArrayMap<>();
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index 991e3e7..64b1f24 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -163,15 +163,6 @@
             }
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
             MessagingChild messagingChild = (MessagingChild) child;
-            if (lp.hide) {
-                if (shown && lp.visibleBefore) {
-                    messagingChild.hideAnimated();
-                }
-                lp.visibleBefore = false;
-                continue;
-            } else {
-                lp.visibleBefore = true;
-            }
 
             final int childWidth = child.getMeasuredWidth();
             final int childHeight = child.getMeasuredHeight();
@@ -182,6 +173,19 @@
             } else {
                 childLeft = paddingLeft + lp.leftMargin;
             }
+            if (lp.hide) {
+                if (shown && lp.visibleBefore) {
+                    // We still want to lay out the child to have great animations
+                    child.layout(childLeft, childTop, childLeft + childWidth,
+                            childTop + lp.lastVisibleHeight);
+                    messagingChild.hideAnimated();
+                }
+                lp.visibleBefore = false;
+                continue;
+            } else {
+                lp.visibleBefore = true;
+                lp.lastVisibleHeight = childHeight;
+            }
 
             if (!first) {
                 childTop += mSpacing;
@@ -228,6 +232,18 @@
         return copy;
     }
 
+    public static boolean isGone(View view) {
+        if (view.getVisibility() == View.GONE) {
+            return true;
+        }
+        final ViewGroup.LayoutParams lp = view.getLayoutParams();
+        if (lp instanceof MessagingLinearLayout.LayoutParams
+                && ((MessagingLinearLayout.LayoutParams) lp).hide) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Sets how many lines should be displayed at most
      */
@@ -263,6 +279,7 @@
 
         public boolean hide = false;
         public boolean visibleBefore = false;
+        public int lastVisibleHeight;
 
         public LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index ffcb503..74d0aae 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -124,8 +124,7 @@
     @Override
     default void hideAnimated() {
         setIsHidingAnimated(true);
-        getGroup().performRemoveAnimation(getState().getHostView(),
-                () -> setIsHidingAnimated(false));
+        getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
     }
 
     default boolean hasOverlappingRendering() {
@@ -133,7 +132,7 @@
     }
 
     default void recycle() {
-        getState().reset();
+        getState().recycle();
     }
 
     default View getView() {
diff --git a/core/java/com/android/internal/widget/MessagingMessageState.java b/core/java/com/android/internal/widget/MessagingMessageState.java
index ac62472..1ba2b51 100644
--- a/core/java/com/android/internal/widget/MessagingMessageState.java
+++ b/core/java/com/android/internal/widget/MessagingMessageState.java
@@ -72,7 +72,10 @@
         return mHostView;
     }
 
-    public void reset() {
+    public void recycle() {
+        mHostView.setAlpha(1.0f);
+        mHostView.setTranslationY(0);
+        MessagingPropertyAnimator.recycle(mHostView);
         mIsHidingAnimated = false;
         mIsHistoric = false;
         mGroup = null;
diff --git a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
index 7c3ab7f..7703cb0 100644
--- a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
+++ b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
@@ -31,111 +31,125 @@
  * A listener that automatically starts animations when the layout bounds change.
  */
 public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
-    static final long APPEAR_ANIMATION_LENGTH = 210;
+    private static final long APPEAR_ANIMATION_LENGTH = 210;
     private static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
     public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
-    private static final int TAG_LOCAL_TRANSLATION_ANIMATOR = R.id.tag_local_translation_y_animator;
-    private static final int TAG_LOCAL_TRANSLATION_Y = R.id.tag_local_translation_y;
+    private static final int TAG_TOP_ANIMATOR = R.id.tag_top_animator;
+    private static final int TAG_TOP = R.id.tag_top_override;
     private static final int TAG_LAYOUT_TOP = R.id.tag_layout_top;
+    private static final int TAG_FIRST_LAYOUT = R.id.tag_is_first_layout;
     private static final int TAG_ALPHA_ANIMATOR = R.id.tag_alpha_animator;
     private static final ViewClippingUtil.ClippingParameters CLIPPING_PARAMETERS =
             view -> view.getId() == com.android.internal.R.id.notification_messaging;
-    private static final IntProperty<View> LOCAL_TRANSLATION_Y =
-            new IntProperty<View>("localTranslationY") {
+    private static final IntProperty<View> TOP =
+            new IntProperty<View>("top") {
                 @Override
                 public void setValue(View object, int value) {
-                    setLocalTranslationY(object, value);
+                    setTop(object, value);
                 }
 
                 @Override
                 public Integer get(View object) {
-                    return getLocalTranslationY(object);
+                    return getTop(object);
                 }
             };
 
     @Override
     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
             int oldTop, int oldRight, int oldBottom) {
-        int oldHeight = oldBottom - oldTop;
-        Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
-        if (layoutTop != null) {
-            oldTop = layoutTop;
-        }
-        int topChange = oldTop - top;
-        if (oldHeight == 0 || topChange == 0 || !v.isShown() || isGone(v)) {
-            // First layout
+        setLayoutTop(v, top);
+        if (isFirstLayout(v)) {
+            setFirstLayout(v, false /* first */);
+            setTop(v, top);
             return;
         }
-        if (layoutTop != null) {
-            v.setTagInternal(TAG_LAYOUT_TOP, top);
-        }
-        int newHeight = bottom - top;
-        int heightDifference = oldHeight - newHeight;
-        // Only add the difference if the height changes and it's getting smaller
-        heightDifference = Math.max(heightDifference, 0);
-        startLocalTranslationFrom(v, topChange + heightDifference + getLocalTranslationY(v));
+        startTopAnimation(v, getTop(v), top, MessagingLayout.FAST_OUT_SLOW_IN);
     }
 
-    private boolean isGone(View view) {
-        if (view.getVisibility() == View.GONE) {
-            return true;
-        }
-        final ViewGroup.LayoutParams lp = view.getLayoutParams();
-        if (lp instanceof MessagingLinearLayout.LayoutParams
-                && ((MessagingLinearLayout.LayoutParams) lp).hide) {
-            return true;
-        }
-        return false;
-    }
-
-    public static void startLocalTranslationFrom(View v, int startTranslation) {
-        startLocalTranslationFrom(v, startTranslation, MessagingLayout.FAST_OUT_SLOW_IN);
-    }
-
-    public static void startLocalTranslationFrom(View v, int startTranslation,
-            Interpolator interpolator) {
-        startLocalTranslation(v, startTranslation, 0, interpolator);
-    }
-
-    public static void startLocalTranslationTo(View v, int endTranslation,
-            Interpolator interpolator) {
-        startLocalTranslation(v, getLocalTranslationY(v), endTranslation, interpolator);
-    }
-
-    public static int getLocalTranslationY(View v) {
-        Integer tag = (Integer) v.getTag(TAG_LOCAL_TRANSLATION_Y);
+    private static boolean isFirstLayout(View view) {
+        Boolean tag = (Boolean) view.getTag(TAG_FIRST_LAYOUT);
         if (tag == null) {
-            return 0;
+            return true;
         }
         return tag;
     }
 
-    private static void setLocalTranslationY(View v, int value) {
-        v.setTagInternal(TAG_LOCAL_TRANSLATION_Y, value);
+    public static void recycle(View view) {
+        setFirstLayout(view, true /* first */);
+    }
+
+    private static void setFirstLayout(View view, boolean first) {
+        view.setTagInternal(TAG_FIRST_LAYOUT, first);
+    }
+
+    private static void setLayoutTop(View view, int top) {
+        view.setTagInternal(TAG_LAYOUT_TOP, top);
+    }
+
+    public static int getLayoutTop(View view) {
+        Integer tag = (Integer) view.getTag(TAG_LAYOUT_TOP);
+        if (tag == null) {
+            return getTop(view);
+        }
+        return tag;
+    }
+
+    /**
+     * Start a translation animation from a start offset to the laid out location
+     * @param view The view to animate
+     * @param startTranslation The starting translation to start from.
+     * @param interpolator The interpolator to use.
+     */
+    public static void startLocalTranslationFrom(View view, int startTranslation,
+            Interpolator interpolator) {
+        startTopAnimation(view, getTop(view) + startTranslation, getLayoutTop(view), interpolator);
+    }
+
+    /**
+     * Start a translation animation from a start offset to the laid out location
+     * @param view The view to animate
+     * @param endTranslation The end translation to go to.
+     * @param interpolator The interpolator to use.
+     */
+    public static void startLocalTranslationTo(View view, int endTranslation,
+            Interpolator interpolator) {
+        int top = getTop(view);
+        startTopAnimation(view, top, top + endTranslation, interpolator);
+    }
+
+    public static int getTop(View v) {
+        Integer tag = (Integer) v.getTag(TAG_TOP);
+        if (tag == null) {
+            return v.getTop();
+        }
+        return tag;
+    }
+
+    private static void setTop(View v, int value) {
+        v.setTagInternal(TAG_TOP, value);
         updateTopAndBottom(v);
     }
 
     private static void updateTopAndBottom(View v) {
-        int layoutTop = (int) v.getTag(TAG_LAYOUT_TOP);
-        int localTranslation = getLocalTranslationY(v);
+        int top = getTop(v);
         int height = v.getHeight();
-        v.setTop(layoutTop + localTranslation);
-        v.setBottom(layoutTop + height + localTranslation);
+        v.setTop(top);
+        v.setBottom(height + top);
     }
 
-    private static void startLocalTranslation(final View v, int start, int end,
+    private static void startTopAnimation(final View v, int start, int end,
             Interpolator interpolator) {
-        ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR);
+        ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_TOP_ANIMATOR);
         if (existing != null) {
             existing.cancel();
         }
-        ObjectAnimator animator = ObjectAnimator.ofInt(v, LOCAL_TRANSLATION_Y, start, end);
-        Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
-        if (layoutTop == null) {
-            layoutTop = v.getTop();
-            v.setTagInternal(TAG_LAYOUT_TOP, layoutTop);
+        if (!v.isShown() || start == end
+                || (MessagingLinearLayout.isGone(v) && !isHidingAnimated(v))) {
+            setTop(v, end);
+            return;
         }
-        setLocalTranslationY(v, start);
+        ObjectAnimator animator = ObjectAnimator.ofInt(v, TOP, start, end);
+        setTop(v, start);
         animator.setInterpolator(interpolator);
         animator.setDuration(APPEAR_ANIMATION_LENGTH);
         animator.addListener(new AnimatorListenerAdapter() {
@@ -143,12 +157,8 @@
 
             @Override
             public void onAnimationEnd(Animator animation) {
-                v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, null);
+                v.setTagInternal(TAG_TOP_ANIMATOR, null);
                 setClippingDeactivated(v, false);
-                if (!mCancelled) {
-                    setLocalTranslationY(v, 0);
-                    v.setTagInternal(TAG_LAYOUT_TOP, null);
-                }
             }
 
             @Override
@@ -157,10 +167,17 @@
             }
         });
         setClippingDeactivated(v, true);
-        v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, animator);
+        v.setTagInternal(TAG_TOP_ANIMATOR, animator);
         animator.start();
     }
 
+    private static boolean isHidingAnimated(View v) {
+        if (v instanceof MessagingLinearLayout.MessagingChild) {
+            return ((MessagingLinearLayout.MessagingChild) v).isHidingAnimated();
+        }
+        return false;
+    }
+
     public static void fadeIn(final View v) {
         ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_ALPHA_ANIMATOR);
         if (existing != null) {
@@ -199,6 +216,13 @@
         if (existing != null) {
             existing.cancel();
         }
+        if (!view.isShown() || (MessagingLinearLayout.isGone(view) && !isHidingAnimated(view))) {
+            view.setAlpha(0.0f);
+            if (endAction != null) {
+                endAction.run();
+            }
+            return;
+        }
         ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA,
                 view.getAlpha(), 0.0f);
         animator.setInterpolator(ALPHA_OUT);
@@ -224,10 +248,14 @@
     }
 
     public static boolean isAnimatingTranslation(View v) {
-        return v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR) != null;
+        return v.getTag(TAG_TOP_ANIMATOR) != null;
     }
 
     public static boolean isAnimatingAlpha(View v) {
         return v.getTag(TAG_ALPHA_ANIMATOR) != null;
     }
+
+    public static void setToLaidOutPosition(View view) {
+        setTop(view, getLayoutTop(view));
+    }
 }
diff --git a/core/java/com/android/internal/widget/MessagingTextMessage.java b/core/java/com/android/internal/widget/MessagingTextMessage.java
index 219116e..4081a86 100644
--- a/core/java/com/android/internal/widget/MessagingTextMessage.java
+++ b/core/java/com/android/internal/widget/MessagingTextMessage.java
@@ -92,8 +92,6 @@
 
     public void recycle() {
         MessagingMessage.super.recycle();
-        setAlpha(1.0f);
-        setTranslationY(0);
         sInstancePool.release(this);
     }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 19e5e21..dced0ad 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -850,7 +850,7 @@
 
     <!-- Used for permissions that are associated telephony features. -->
     <permission-group android:name="android.permission-group.CALL_LOG"
-        android:icon="@drawable/perm_group_phone_calls"
+        android:icon="@drawable/perm_group_call_log"
         android:label="@string/permgrouplab_calllog"
         android:description="@string/permgroupdesc_calllog"
         android:request="@string/permgrouprequest_calllog"
diff --git a/core/res/res/drawable/perm_group_call_log.xml b/core/res/res/drawable/perm_group_call_log.xml
new file mode 100644
index 0000000..0dfdbee
--- /dev/null
+++ b/core/res/res/drawable/perm_group_call_log.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#000000"
+        android:pathData="M16.01,14.48l-2.62,2.62c-2.75,-1.49 -5.01,-3.75 -6.5,-6.5l2.62,-2.62c0.24,-0.24 0.34,-0.58 0.27,-0.9L9.13,3.82c-0.09,-0.47 -0.5,-0.8 -0.98,-0.8L4,3.01c-0.56,0 -1.03,0.47 -1,1.03c0.17,2.91 1.04,5.63 2.43,8.01c1.57,2.69 3.81,4.93 6.5,6.5c2.38,1.39 5.1,2.26 8.01,2.43c0.56,0.03 1.03,-0.44 1.03,-1v-4.15c0,-0.48 -0.34,-0.89 -0.8,-0.98l-3.26,-0.65C16.58,14.14 16.24,14.24 16.01,14.48z"/>
+    <path
+        android:fillColor="#000000"
+        android:pathData="M12,8h10V6H12V8zM12,4h10V2H12V4zM22,10H12v2h10V10z"/>
+</vector>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 47d04ed..bf7e068 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -140,15 +140,18 @@
   <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. -->
   <item type="id" name="accessibilityActionMoveWindow" />
 
-  <!-- A tag used to save an animator in local y translation -->
-  <item type="id" name="tag_local_translation_y_animator" />
+  <!-- A tag used to save an animator in top -->
+  <item type="id" name="tag_top_animator" />
 
-  <!-- A tag used to save the local translation y -->
-  <item type="id" name="tag_local_translation_y" />
+  <!-- A tag used to save the current top override -->
+  <item type="id" name="tag_top_override" />
 
   <!-- A tag used to save the original top of a view -->
   <item type="id" name="tag_layout_top" />
 
+  <!-- A tag used to save whether a view was laid out before -->
+  <item type="id" name="tag_is_first_layout" />
+
   <!-- A tag used to save an animator in alpha -->
   <item type="id" name="tag_alpha_animator" />
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f7ff377..8a045a0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3260,9 +3260,10 @@
   <java-symbol type="id" name="message_name" />
   <java-symbol type="id" name="message_icon" />
   <java-symbol type="id" name="group_message_container" />
-  <java-symbol type="id" name="tag_local_translation_y_animator" />
-  <java-symbol type="id" name="tag_local_translation_y" />
+  <java-symbol type="id" name="tag_top_animator" />
+  <java-symbol type="id" name="tag_top_override" />
   <java-symbol type="id" name="tag_layout_top" />
+  <java-symbol type="id" name="tag_is_first_layout" />
   <java-symbol type="id" name="tag_alpha_animator" />
   <java-symbol type="id" name="clip_children_set_tag" />
   <java-symbol type="id" name="clip_to_padding_tag" />
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
new file mode 100644
index 0000000..c8e46fc
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -0,0 +1,143 @@
+/*
+ * 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 android.view;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ViewRootImplTest {
+
+    private Context mContext;
+    private ViewRootImplAccessor mViewRootImpl;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            mViewRootImpl = new ViewRootImplAccessor(
+                    new ViewRootImpl(mContext, mContext.getDisplay()));
+        });
+    }
+
+    @Test
+    public void negativeInsets_areSetToZero() throws Exception {
+        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40);
+        mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40);
+        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect()));
+        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+                insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect()));
+    }
+
+    @Test
+    public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception {
+        mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40);
+        mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40);
+        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40)));
+        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+                insets.getStableInsetRight(), insets.getStableInsetBottom()),
+                equalTo(new Rect(10, 0, 30, 0)));
+    }
+
+    @Test
+    public void positiveInsets_areLeftAsIs() throws Exception {
+        mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40);
+        mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40);
+        final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+        assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40)));
+        assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+                insets.getStableInsetRight(), insets.getStableInsetBottom()),
+                equalTo(new Rect(10, 20, 30, 40)));
+    }
+
+    private static class ViewRootImplAccessor {
+
+        private final ViewRootImpl mViewRootImpl;
+
+        ViewRootImplAccessor(ViewRootImpl viewRootImpl) {
+            mViewRootImpl = viewRootImpl;
+        }
+
+        public ViewRootImpl get() {
+            return mViewRootImpl;
+        }
+
+        AttachInfoAccessor getAttachInfo() throws Exception {
+            return new AttachInfoAccessor(
+                    getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo")));
+        }
+
+        WindowInsets getWindowInsets(boolean forceConstruct) throws Exception {
+            return (WindowInsets) invokeMethod(mViewRootImpl,
+                    ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class),
+                    forceConstruct);
+        }
+
+        class AttachInfoAccessor {
+
+            private final Class<?> mClass;
+            private final Object mAttachInfo;
+
+            AttachInfoAccessor(Object attachInfo) throws Exception {
+                mAttachInfo = attachInfo;
+                mClass = ViewRootImpl.class.getClassLoader().loadClass(
+                        "android.view.View$AttachInfo");
+            }
+
+            Rect getContentInsets() throws Exception {
+                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets"));
+            }
+
+            Rect getStableInsets() throws Exception {
+                return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets"));
+            }
+        }
+
+        private static Object getField(Object o, Field field) throws Exception {
+            field.setAccessible(true);
+            return field.get(o);
+        }
+
+        private static Object invokeMethod(Object o, Method method, Object... args)
+                throws Exception {
+            method.setAccessible(true);
+            return method.invoke(o, args);
+        }
+    }
+}
diff --git a/docs/html/reference/_book.yaml b/docs/html/reference/_book.yaml
deleted file mode 100644
index b902a61..0000000
--- a/docs/html/reference/_book.yaml
+++ /dev/null
@@ -1,853 +0,0 @@
-reference:
-- title: Class Index
-  path: /reference/classes.html
-  status_text: no-toggle
-- title: Package Index
-  path: /reference/packages.html
-  status_text: no-toggle
-- title: android
-  path: /reference/android/package-summary.html
-  status_text: apilevel-1
-- title: android.accessibilityservice
-  path: /reference/android/accessibilityservice/package-summary.html
-  status_text: apilevel-4
-- title: android.accounts
-  path: /reference/android/accounts/package-summary.html
-  status_text: apilevel-5
-- title: android.animation
-  path: /reference/android/animation/package-summary.html
-  status_text: apilevel-11
-- title: android.annotation
-  path: /reference/android/annotation/package-summary.html
-  status_text: apilevel-16
-- title: android.app
-  path: /reference/android/app/package-summary.html
-  status_text: apilevel-1
-- title: android.app.admin
-  path: /reference/android/app/admin/package-summary.html
-  status_text: apilevel-8
-- title: android.app.assist
-  path: /reference/android/app/assist/package-summary.html
-  status_text: apilevel-23
-- title: android.app.backup
-  path: /reference/android/app/backup/package-summary.html
-  status_text: apilevel-8
-- title: android.app.job
-  path: /reference/android/app/job/package-summary.html
-  status_text: apilevel-21
-- title: android.app.usage
-  path: /reference/android/app/usage/package-summary.html
-  status_text: apilevel-21
-- title: android.appwidget
-  path: /reference/android/appwidget/package-summary.html
-  status_text: apilevel-3
-- title: android.bluetooth
-  path: /reference/android/bluetooth/package-summary.html
-  status_text: apilevel-5
-- title: android.bluetooth.le
-  path: /reference/android/bluetooth/le/package-summary.html
-  status_text: apilevel-21
-- title: android.companion
-  path: /reference/android/companion/package-summary.html
-  status_text: apilevel-O
-- title: android.content
-  path: /reference/android/content/package-summary.html
-  status_text: apilevel-1
-- title: android.content.pm
-  path: /reference/android/content/pm/package-summary.html
-  status_text: apilevel-1
-- title: android.content.res
-  path: /reference/android/content/res/package-summary.html
-  status_text: apilevel-1
-- title: android.database
-  path: /reference/android/database/package-summary.html
-  status_text: apilevel-1
-- title: android.database.sqlite
-  path: /reference/android/database/sqlite/package-summary.html
-  status_text: apilevel-1
-- title: android.databinding
-  path: /reference/android/databinding/package-summary.html
-  status_text: apilevel-
-- title: android.drm
-  path: /reference/android/drm/package-summary.html
-  status_text: apilevel-11
-- title: android.gesture
-  path: /reference/android/gesture/package-summary.html
-  status_text: apilevel-4
-- title: android.graphics
-  path: /reference/android/graphics/package-summary.html
-  status_text: apilevel-1
-- title: android.graphics.drawable
-  path: /reference/android/graphics/drawable/package-summary.html
-  status_text: apilevel-1
-- title: android.graphics.drawable.shapes
-  path: /reference/android/graphics/drawable/shapes/package-summary.html
-  status_text: apilevel-1
-- title: android.graphics.fonts
-  path: /reference/android/graphics/fonts/package-summary.html
-  status_text: apilevel-O
-- title: android.graphics.pdf
-  path: /reference/android/graphics/pdf/package-summary.html
-  status_text: apilevel-19
-- title: android.hardware
-  path: /reference/android/hardware/package-summary.html
-  status_text: apilevel-1
-- title: android.hardware.camera2
-  path: /reference/android/hardware/camera2/package-summary.html
-  status_text: apilevel-21
-- title: android.hardware.camera2.params
-  path: /reference/android/hardware/camera2/params/package-summary.html
-  status_text: apilevel-21
-- title: android.hardware.display
-  path: /reference/android/hardware/display/package-summary.html
-  status_text: apilevel-17
-- title: android.hardware.fingerprint
-  path: /reference/android/hardware/fingerprint/package-summary.html
-  status_text: apilevel-23
-- title: android.hardware.input
-  path: /reference/android/hardware/input/package-summary.html
-  status_text: apilevel-16
-- title: android.hardware.usb
-  path: /reference/android/hardware/usb/package-summary.html
-  status_text: apilevel-12
-- title: android.icu.lang
-  path: /reference/android/icu/lang/package-summary.html
-  status_text: apilevel-24
-- title: android.icu.math
-  path: /reference/android/icu/math/package-summary.html
-  status_text: apilevel-24
-- title: android.icu.text
-  path: /reference/android/icu/text/package-summary.html
-  status_text: apilevel-24
-- title: android.icu.util
-  path: /reference/android/icu/util/package-summary.html
-  status_text: apilevel-24
-- title: android.inputmethodservice
-  path: /reference/android/inputmethodservice/package-summary.html
-  status_text: apilevel-3
-- title: android.location
-  path: /reference/android/location/package-summary.html
-  status_text: apilevel-1
-- title: android.media
-  path: /reference/android/media/package-summary.html
-  status_text: apilevel-1
-- title: android.media.audiofx
-  path: /reference/android/media/audiofx/package-summary.html
-  status_text: apilevel-9
-- title: android.media.browse
-  path: /reference/android/media/browse/package-summary.html
-  status_text: apilevel-21
-- title: android.media.effect
-  path: /reference/android/media/effect/package-summary.html
-  status_text: apilevel-14
-- title: android.media.midi
-  path: /reference/android/media/midi/package-summary.html
-  status_text: apilevel-23
-- title: android.media.projection
-  path: /reference/android/media/projection/package-summary.html
-  status_text: apilevel-21
-- title: android.media.session
-  path: /reference/android/media/session/package-summary.html
-  status_text: apilevel-21
-- title: android.media.tv
-  path: /reference/android/media/tv/package-summary.html
-  status_text: apilevel-21
-- title: android.mtp
-  path: /reference/android/mtp/package-summary.html
-  status_text: apilevel-12
-- title: android.net
-  path: /reference/android/net/package-summary.html
-  status_text: apilevel-1
-- title: android.net.http
-  path: /reference/android/net/http/package-summary.html
-  status_text: apilevel-1
-- title: android.net.nsd
-  path: /reference/android/net/nsd/package-summary.html
-  status_text: apilevel-16
-- title: android.net.rtp
-  path: /reference/android/net/rtp/package-summary.html
-  status_text: apilevel-12
-- title: android.net.sip
-  path: /reference/android/net/sip/package-summary.html
-  status_text: apilevel-9
-- title: android.net.wifi
-  path: /reference/android/net/wifi/package-summary.html
-  status_text: apilevel-1
-- title: android.net.wifi.aware
-  path: /reference/android/net/wifi/aware/package-summary.html
-  status_text: apilevel-O
-- title: android.net.wifi.hotspot2
-  path: /reference/android/net/wifi/hotspot2/package-summary.html
-  status_text: apilevel-O
-- title: android.net.wifi.hotspot2.omadm
-  path: /reference/android/net/wifi/hotspot2/omadm/package-summary.html
-  status_text: apilevel-O
-- title: android.net.wifi.hotspot2.pps
-  path: /reference/android/net/wifi/hotspot2/pps/package-summary.html
-  status_text: apilevel-O
-- title: android.net.wifi.p2p
-  path: /reference/android/net/wifi/p2p/package-summary.html
-  status_text: apilevel-14
-- title: android.net.wifi.p2p.nsd
-  path: /reference/android/net/wifi/p2p/nsd/package-summary.html
-  status_text: apilevel-16
-- title: android.nfc
-  path: /reference/android/nfc/package-summary.html
-  status_text: apilevel-9
-- title: android.nfc.cardemulation
-  path: /reference/android/nfc/cardemulation/package-summary.html
-  status_text: apilevel-19
-- title: android.nfc.tech
-  path: /reference/android/nfc/tech/package-summary.html
-  status_text: apilevel-10
-- title: android.opengl
-  path: /reference/android/opengl/package-summary.html
-  status_text: apilevel-1
-- title: android.os
-  path: /reference/android/os/package-summary.html
-  status_text: apilevel-1
-- title: android.os.health
-  path: /reference/android/os/health/package-summary.html
-  status_text: apilevel-24
-- title: android.os.storage
-  path: /reference/android/os/storage/package-summary.html
-  status_text: apilevel-9
-- title: android.preference
-  path: /reference/android/preference/package-summary.html
-  status_text: apilevel-1
-- title: android.print
-  path: /reference/android/print/package-summary.html
-  status_text: apilevel-19
-- title: android.print.pdf
-  path: /reference/android/print/pdf/package-summary.html
-  status_text: apilevel-19
-- title: android.printservice
-  path: /reference/android/printservice/package-summary.html
-  status_text: apilevel-19
-- title: android.provider
-  path: /reference/android/provider/package-summary.html
-  status_text: apilevel-1
-- title: android.renderscript
-  path: /reference/android/renderscript/package-summary.html
-  status_text: apilevel-11
-- title: android.sax
-  path: /reference/android/sax/package-summary.html
-  status_text: apilevel-1
-- title: android.security
-  path: /reference/android/security/package-summary.html
-  status_text: apilevel-14
-- title: android.security.keystore
-  path: /reference/android/security/keystore/package-summary.html
-  status_text: apilevel-23
-- title: android.service.autofill
-  path: /reference/android/service/autofill/package-summary.html
-  status_text: apilevel-O
-- title: android.service.carrier
-  path: /reference/android/service/carrier/package-summary.html
-  status_text: apilevel-22
-- title: android.service.chooser
-  path: /reference/android/service/chooser/package-summary.html
-  status_text: apilevel-23
-- title: android.service.dreams
-  path: /reference/android/service/dreams/package-summary.html
-  status_text: apilevel-17
-- title: android.service.media
-  path: /reference/android/service/media/package-summary.html
-  status_text: apilevel-21
-- title: android.service.notification
-  path: /reference/android/service/notification/package-summary.html
-  status_text: apilevel-18
-- title: android.service.quicksettings
-  path: /reference/android/service/quicksettings/package-summary.html
-  status_text: apilevel-24
-- title: android.service.restrictions
-  path: /reference/android/service/restrictions/package-summary.html
-  status_text: apilevel-21
-- title: android.service.textservice
-  path: /reference/android/service/textservice/package-summary.html
-  status_text: apilevel-14
-- title: android.service.voice
-  path: /reference/android/service/voice/package-summary.html
-  status_text: apilevel-21
-- title: android.service.vr
-  path: /reference/android/service/vr/package-summary.html
-  status_text: apilevel-24
-- title: android.service.wallpaper
-  path: /reference/android/service/wallpaper/package-summary.html
-  status_text: apilevel-7
-- title: android.speech
-  path: /reference/android/speech/package-summary.html
-  status_text: apilevel-3
-- title: android.speech.tts
-  path: /reference/android/speech/tts/package-summary.html
-  status_text: apilevel-4
-- title: android.support.animation
-  path: /reference/android/support/animation/package-summary.html
-  status_text: apilevel-25.3.0
-- title: android.support.annotation
-  path: /reference/android/support/annotation/package-summary.html
-  status_text: apilevel-
-- title: android.support.app.recommendation
-  path: /reference/android/support/app/recommendation/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.compat
-  path: /reference/android/support/compat/package-summary.html
-  status_text: apilevel-
-- title: android.support.coreui
-  path: /reference/android/support/coreui/package-summary.html
-  status_text: apilevel-
-- title: android.support.coreutils
-  path: /reference/android/support/coreutils/package-summary.html
-  status_text: apilevel-
-- title: android.support.customtabs
-  path: /reference/android/support/customtabs/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.design
-  path: /reference/android/support/design/package-summary.html
-  status_text: apilevel-
-- title: android.support.design.widget
-  path: /reference/android/support/design/widget/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.dynamicanimation
-  path: /reference/android/support/dynamicanimation/package-summary.html
-  status_text: apilevel-
-- title: android.support.exifinterface
-  path: /reference/android/support/exifinterface/package-summary.html
-  status_text: apilevel-
-- title: android.support.fragment
-  path: /reference/android/support/fragment/package-summary.html
-  status_text: apilevel-
-- title: android.support.graphics.drawable
-  path: /reference/android/support/graphics/drawable/package-summary.html
-  status_text: apilevel-23.2.0
-- title: android.support.graphics.drawable.animated
-  path: /reference/android/support/graphics/drawable/animated/package-summary.html
-  status_text: apilevel-
-- title: android.support.media
-  path: /reference/android/support/media/package-summary.html
-  status_text: apilevel-25.1.0
-- title: android.support.media.instantvideo
-  path: /reference/android/support/media/instantvideo/package-summary.html
-  status_text: apilevel-
-- title: android.support.media.instantvideo.preload
-  path: /reference/android/support/media/instantvideo/preload/package-summary.html
-  status_text: apilevel-26.0.0-alpha1
-- title: android.support.media.instantvideo.widget
-  path: /reference/android/support/media/instantvideo/widget/package-summary.html
-  status_text: apilevel-26.0.0-alpha1
-- title: android.support.media.tv
-  path: /reference/android/support/media/tv/package-summary.html
-  status_text: apilevel-26.0.0-alpha1
-- title: android.support.mediacompat
-  path: /reference/android/support/mediacompat/package-summary.html
-  status_text: apilevel-
-- title: android.support.multidex
-  path: /reference/android/support/multidex/package-summary.html
-  status_text: apilevel-
-- title: android.support.percent
-  path: /reference/android/support/percent/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.recommendation
-  path: /reference/android/support/recommendation/package-summary.html
-  status_text: apilevel-
-- title: android.support.transition
-  path: /reference/android/support/transition/package-summary.html
-  status_text: apilevel-24.2.0
-- title: android.support.v13
-  path: /reference/android/support/v13/package-summary.html
-  status_text: apilevel-
-- title: android.support.v13.app
-  path: /reference/android/support/v13/app/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v13.view
-  path: /reference/android/support/v13/view/package-summary.html
-  status_text: apilevel-24.0.0
-- title: android.support.v13.view.inputmethod
-  path: /reference/android/support/v13/view/inputmethod/package-summary.html
-  status_text: apilevel-25.0.0
-- title: android.support.v14.preference
-  path: /reference/android/support/v14/preference/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.v17.leanback
-  path: /reference/android/support/v17/leanback/package-summary.html
-  status_text: apilevel-
-- title: android.support.v17.leanback.app
-  path: /reference/android/support/v17/leanback/app/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v17.leanback.database
-  path: /reference/android/support/v17/leanback/database/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v17.leanback.graphics
-  path: /reference/android/support/v17/leanback/graphics/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v17.leanback.media
-  path: /reference/android/support/v17/leanback/media/package-summary.html
-  status_text: apilevel-25.1.0
-- title: android.support.v17.leanback.system
-  path: /reference/android/support/v17/leanback/system/package-summary.html
-  status_text: apilevel-22.2.1
-- title: android.support.v17.leanback.widget
-  path: /reference/android/support/v17/leanback/widget/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v17.leanback.widget.picker
-  path: /reference/android/support/v17/leanback/widget/picker/package-summary.html
-  status_text: apilevel-23.2.0
-- title: android.support.v17.preference
-  path: /reference/android/support/v17/preference/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.v4
-  path: /reference/android/support/v4/package-summary.html
-  status_text: apilevel-
-- title: android.support.v4.accessibilityservice
-  path: /reference/android/support/v4/accessibilityservice/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.app
-  path: /reference/android/support/v4/app/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.content
-  path: /reference/android/support/v4/content/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.content.pm
-  path: /reference/android/support/v4/content/pm/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.v4.content.res
-  path: /reference/android/support/v4/content/res/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.v4.database
-  path: /reference/android/support/v4/database/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.graphics
-  path: /reference/android/support/v4/graphics/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.graphics.drawable
-  path: /reference/android/support/v4/graphics/drawable/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.hardware.display
-  path: /reference/android/support/v4/hardware/display/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.hardware.fingerprint
-  path: /reference/android/support/v4/hardware/fingerprint/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.v4.math
-  path: /reference/android/support/v4/math/package-summary.html
-  status_text: apilevel-26.0.0-alpha1
-- title: android.support.v4.media
-  path: /reference/android/support/v4/media/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.media.session
-  path: /reference/android/support/v4/media/session/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.net
-  path: /reference/android/support/v4/net/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.os
-  path: /reference/android/support/v4/os/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.print
-  path: /reference/android/support/v4/print/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.provider
-  path: /reference/android/support/v4/provider/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.text
-  path: /reference/android/support/v4/text/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.text.util
-  path: /reference/android/support/v4/text/util/package-summary.html
-  status_text: apilevel-24.2.0
-- title: android.support.v4.util
-  path: /reference/android/support/v4/util/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.view
-  path: /reference/android/support/v4/view/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.view.accessibility
-  path: /reference/android/support/v4/view/accessibility/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v4.view.animation
-  path: /reference/android/support/v4/view/animation/package-summary.html
-  status_text: apilevel-22.1.0
-- title: android.support.v4.widget
-  path: /reference/android/support/v4/widget/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.app
-  path: /reference/android/support/v7/app/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.appcompat
-  path: /reference/android/support/v7/appcompat/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.v7.cardview
-  path: /reference/android/support/v7/cardview/package-summary.html
-  status_text: apilevel-
-- title: android.support.v7.content.res
-  path: /reference/android/support/v7/content/res/package-summary.html
-  status_text: apilevel-24.0.0
-- title: android.support.v7.graphics
-  path: /reference/android/support/v7/graphics/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.graphics.drawable
-  path: /reference/android/support/v7/graphics/drawable/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.v7.gridlayout
-  path: /reference/android/support/v7/gridlayout/package-summary.html
-  status_text: apilevel-
-- title: android.support.v7.media
-  path: /reference/android/support/v7/media/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.mediarouter
-  path: /reference/android/support/v7/mediarouter/package-summary.html
-  status_text: apilevel-
-- title: android.support.v7.palette
-  path: /reference/android/support/v7/palette/package-summary.html
-  status_text: apilevel-
-- title: android.support.v7.preference
-  path: /reference/android/support/v7/preference/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.v7.recyclerview
-  path: /reference/android/support/v7/recyclerview/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.v7.util
-  path: /reference/android/support/v7/util/package-summary.html
-  status_text: apilevel-22.1.0
-- title: android.support.v7.view
-  path: /reference/android/support/v7/view/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.widget
-  path: /reference/android/support/v7/widget/package-summary.html
-  status_text: apilevel-22.0.0
-- title: android.support.v7.widget.helper
-  path: /reference/android/support/v7/widget/helper/package-summary.html
-  status_text: apilevel-22.2.0
-- title: android.support.v7.widget.util
-  path: /reference/android/support/v7/widget/util/package-summary.html
-  status_text: apilevel-22.1.0
-- title: android.support.v8.renderscript
-  path: /reference/android/support/v8/renderscript/package-summary.html
-  status_text: apilevel-23.0.0
-- title: android.support.wearable
-  path: /reference/android/support/wearable/package-summary.html
-  status_text: apilevel-
-- title: android.support.wearable.view
-  path: /reference/android/support/wearable/view/package-summary.html
-  status_text: apilevel-26.0.0-alpha1
-- title: android.system
-  path: /reference/android/system/package-summary.html
-  status_text: apilevel-21
-- title: android.telecom
-  path: /reference/android/telecom/package-summary.html
-  status_text: apilevel-21
-- title: android.telephony
-  path: /reference/android/telephony/package-summary.html
-  status_text: apilevel-1
-- title: android.telephony.cdma
-  path: /reference/android/telephony/cdma/package-summary.html
-  status_text: apilevel-5
-- title: android.telephony.gsm
-  path: /reference/android/telephony/gsm/package-summary.html
-  status_text: apilevel-1
-- title: android.test
-  path: /reference/android/test/package-summary.html
-  status_text: apilevel-1
-- title: android.test.mock
-  path: /reference/android/test/mock/package-summary.html
-  status_text: apilevel-1
-- title: android.test.suitebuilder
-  path: /reference/android/test/suitebuilder/package-summary.html
-  status_text: apilevel-1
-- title: android.test.suitebuilder.annotation
-  path: /reference/android/test/suitebuilder/annotation/package-summary.html
-  status_text: apilevel-1
-- title: android.text
-  path: /reference/android/text/package-summary.html
-  status_text: apilevel-1
-- title: android.text.format
-  path: /reference/android/text/format/package-summary.html
-  status_text: apilevel-3
-- title: android.text.method
-  path: /reference/android/text/method/package-summary.html
-  status_text: apilevel-1
-- title: android.text.style
-  path: /reference/android/text/style/package-summary.html
-  status_text: apilevel-1
-- title: android.text.util
-  path: /reference/android/text/util/package-summary.html
-  status_text: apilevel-1
-- title: android.transition
-  path: /reference/android/transition/package-summary.html
-  status_text: apilevel-19
-- title: android.util
-  path: /reference/android/util/package-summary.html
-  status_text: apilevel-1
-- title: android.view
-  path: /reference/android/view/package-summary.html
-  status_text: apilevel-1
-- title: android.view.accessibility
-  path: /reference/android/view/accessibility/package-summary.html
-  status_text: apilevel-4
-- title: android.view.animation
-  path: /reference/android/view/animation/package-summary.html
-  status_text: apilevel-1
-- title: android.view.autofill
-  path: /reference/android/view/autofill/package-summary.html
-  status_text: apilevel-O
-- title: android.view.inputmethod
-  path: /reference/android/view/inputmethod/package-summary.html
-  status_text: apilevel-3
-- title: android.view.textclassifier
-  path: /reference/android/view/textclassifier/package-summary.html
-  status_text: apilevel-O
-- title: android.view.textservice
-  path: /reference/android/view/textservice/package-summary.html
-  status_text: apilevel-14
-- title: android.webkit
-  path: /reference/android/webkit/package-summary.html
-  status_text: apilevel-1
-- title: android.widget
-  path: /reference/android/widget/package-summary.html
-  status_text: apilevel-1
-- title: com.android.test.runner
-  path: /reference/com/android/test/runner/package-summary.html
-  status_text: apilevel-
-- title: dalvik.annotation
-  path: /reference/dalvik/annotation/package-summary.html
-  status_text: apilevel-1
-- title: dalvik.bytecode
-  path: /reference/dalvik/bytecode/package-summary.html
-  status_text: apilevel-1
-- title: dalvik.system
-  path: /reference/dalvik/system/package-summary.html
-  status_text: apilevel-1
-- title: java.awt.font
-  path: /reference/java/awt/font/package-summary.html
-  status_text: apilevel-1
-- title: java.beans
-  path: /reference/java/beans/package-summary.html
-  status_text: apilevel-3
-- title: java.io
-  path: /reference/java/io/package-summary.html
-  status_text: apilevel-1
-- title: java.lang
-  path: /reference/java/lang/package-summary.html
-  status_text: apilevel-1
-- title: java.lang.annotation
-  path: /reference/java/lang/annotation/package-summary.html
-  status_text: apilevel-1
-- title: java.lang.invoke
-  path: /reference/java/lang/invoke/package-summary.html
-  status_text: apilevel-O
-- title: java.lang.ref
-  path: /reference/java/lang/ref/package-summary.html
-  status_text: apilevel-1
-- title: java.lang.reflect
-  path: /reference/java/lang/reflect/package-summary.html
-  status_text: apilevel-1
-- title: java.math
-  path: /reference/java/math/package-summary.html
-  status_text: apilevel-1
-- title: java.net
-  path: /reference/java/net/package-summary.html
-  status_text: apilevel-1
-- title: java.nio
-  path: /reference/java/nio/package-summary.html
-  status_text: apilevel-1
-- title: java.nio.channels
-  path: /reference/java/nio/channels/package-summary.html
-  status_text: apilevel-1
-- title: java.nio.channels.spi
-  path: /reference/java/nio/channels/spi/package-summary.html
-  status_text: apilevel-1
-- title: java.nio.charset
-  path: /reference/java/nio/charset/package-summary.html
-  status_text: apilevel-1
-- title: java.nio.charset.spi
-  path: /reference/java/nio/charset/spi/package-summary.html
-  status_text: apilevel-1
-- title: java.nio.file
-  path: /reference/java/nio/file/package-summary.html
-  status_text: apilevel-O
-- title: java.nio.file.attribute
-  path: /reference/java/nio/file/attribute/package-summary.html
-  status_text: apilevel-O
-- title: java.nio.file.spi
-  path: /reference/java/nio/file/spi/package-summary.html
-  status_text: apilevel-O
-- title: java.security
-  path: /reference/java/security/package-summary.html
-  status_text: apilevel-1
-- title: java.security.acl
-  path: /reference/java/security/acl/package-summary.html
-  status_text: apilevel-1
-- title: java.security.cert
-  path: /reference/java/security/cert/package-summary.html
-  status_text: apilevel-1
-- title: java.security.interfaces
-  path: /reference/java/security/interfaces/package-summary.html
-  status_text: apilevel-1
-- title: java.security.spec
-  path: /reference/java/security/spec/package-summary.html
-  status_text: apilevel-1
-- title: java.sql
-  path: /reference/java/sql/package-summary.html
-  status_text: apilevel-1
-- title: java.text
-  path: /reference/java/text/package-summary.html
-  status_text: apilevel-1
-- title: java.time
-  path: /reference/java/time/package-summary.html
-  status_text: apilevel-O
-- title: java.time.chrono
-  path: /reference/java/time/chrono/package-summary.html
-  status_text: apilevel-O
-- title: java.time.format
-  path: /reference/java/time/format/package-summary.html
-  status_text: apilevel-O
-- title: java.time.temporal
-  path: /reference/java/time/temporal/package-summary.html
-  status_text: apilevel-O
-- title: java.time.zone
-  path: /reference/java/time/zone/package-summary.html
-  status_text: apilevel-O
-- title: java.util
-  path: /reference/java/util/package-summary.html
-  status_text: apilevel-1
-- title: java.util.concurrent
-  path: /reference/java/util/concurrent/package-summary.html
-  status_text: apilevel-1
-- title: java.util.concurrent.atomic
-  path: /reference/java/util/concurrent/atomic/package-summary.html
-  status_text: apilevel-1
-- title: java.util.concurrent.locks
-  path: /reference/java/util/concurrent/locks/package-summary.html
-  status_text: apilevel-1
-- title: java.util.function
-  path: /reference/java/util/function/package-summary.html
-  status_text: apilevel-24
-- title: java.util.jar
-  path: /reference/java/util/jar/package-summary.html
-  status_text: apilevel-1
-- title: java.util.logging
-  path: /reference/java/util/logging/package-summary.html
-  status_text: apilevel-1
-- title: java.util.prefs
-  path: /reference/java/util/prefs/package-summary.html
-  status_text: apilevel-1
-- title: java.util.regex
-  path: /reference/java/util/regex/package-summary.html
-  status_text: apilevel-1
-- title: java.util.stream
-  path: /reference/java/util/stream/package-summary.html
-  status_text: apilevel-24
-- title: java.util.zip
-  path: /reference/java/util/zip/package-summary.html
-  status_text: apilevel-1
-- title: javax.crypto
-  path: /reference/javax/crypto/package-summary.html
-  status_text: apilevel-1
-- title: javax.crypto.interfaces
-  path: /reference/javax/crypto/interfaces/package-summary.html
-  status_text: apilevel-1
-- title: javax.crypto.spec
-  path: /reference/javax/crypto/spec/package-summary.html
-  status_text: apilevel-1
-- title: javax.microedition.khronos.egl
-  path: /reference/javax/microedition/khronos/egl/package-summary.html
-  status_text: apilevel-1
-- title: javax.microedition.khronos.opengles
-  path: /reference/javax/microedition/khronos/opengles/package-summary.html
-  status_text: apilevel-1
-- title: javax.net
-  path: /reference/javax/net/package-summary.html
-  status_text: apilevel-1
-- title: javax.net.ssl
-  path: /reference/javax/net/ssl/package-summary.html
-  status_text: apilevel-1
-- title: javax.security.auth
-  path: /reference/javax/security/auth/package-summary.html
-  status_text: apilevel-1
-- title: javax.security.auth.callback
-  path: /reference/javax/security/auth/callback/package-summary.html
-  status_text: apilevel-1
-- title: javax.security.auth.login
-  path: /reference/javax/security/auth/login/package-summary.html
-  status_text: apilevel-1
-- title: javax.security.auth.x500
-  path: /reference/javax/security/auth/x500/package-summary.html
-  status_text: apilevel-1
-- title: javax.security.cert
-  path: /reference/javax/security/cert/package-summary.html
-  status_text: apilevel-1
-- title: javax.sql
-  path: /reference/javax/sql/package-summary.html
-  status_text: apilevel-1
-- title: javax.xml
-  path: /reference/javax/xml/package-summary.html
-  status_text: apilevel-1
-- title: javax.xml.datatype
-  path: /reference/javax/xml/datatype/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.namespace
-  path: /reference/javax/xml/namespace/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.parsers
-  path: /reference/javax/xml/parsers/package-summary.html
-  status_text: apilevel-1
-- title: javax.xml.transform
-  path: /reference/javax/xml/transform/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.transform.dom
-  path: /reference/javax/xml/transform/dom/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.transform.sax
-  path: /reference/javax/xml/transform/sax/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.transform.stream
-  path: /reference/javax/xml/transform/stream/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.validation
-  path: /reference/javax/xml/validation/package-summary.html
-  status_text: apilevel-8
-- title: javax.xml.xpath
-  path: /reference/javax/xml/xpath/package-summary.html
-  status_text: apilevel-8
-- title: junit.framework
-  path: /reference/junit/framework/package-summary.html
-  status_text: apilevel-1
-- title: junit.runner
-  path: /reference/junit/runner/package-summary.html
-  status_text: apilevel-1
-- title: org.apache.http.conn
-  path: /reference/org/apache/http/conn/package-summary.html
-  status_text: apilevel-1
-- title: org.apache.http.conn.scheme
-  path: /reference/org/apache/http/conn/scheme/package-summary.html
-  status_text: apilevel-1
-- title: org.apache.http.conn.ssl
-  path: /reference/org/apache/http/conn/ssl/package-summary.html
-  status_text: apilevel-1
-- title: org.apache.http.params
-  path: /reference/org/apache/http/params/package-summary.html
-  status_text: apilevel-1
-- title: org.json
-  path: /reference/org/json/package-summary.html
-  status_text: apilevel-1
-- title: org.w3c.dom
-  path: /reference/org/w3c/dom/package-summary.html
-  status_text: apilevel-1
-- title: org.w3c.dom.ls
-  path: /reference/org/w3c/dom/ls/package-summary.html
-  status_text: apilevel-8
-- title: org.xml.sax
-  path: /reference/org/xml/sax/package-summary.html
-  status_text: apilevel-1
-- title: org.xml.sax.ext
-  path: /reference/org/xml/sax/ext/package-summary.html
-  status_text: apilevel-1
-- title: org.xml.sax.helpers
-  path: /reference/org/xml/sax/helpers/package-summary.html
-  status_text: apilevel-1
-- title: org.xmlpull.v1
-  path: /reference/org/xmlpull/v1/package-summary.html
-  status_text: apilevel-1
-- title: org.xmlpull.v1.sax2
-  path: /reference/org/xmlpull/v1/sax2/package-summary.html
-  status_text: apilevel-1
diff --git a/docs/html/reference/_project.yaml b/docs/html/reference/_project.yaml
deleted file mode 100644
index e5c26e7..0000000
--- a/docs/html/reference/_project.yaml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: "Reference"
-home_url: /reference/
-description: "API Reference packages and classes."
-content_license: cc3-apache2
-buganizer_id: 30209417
-parent_project_metadata_path: /develop/_project.yaml
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
index b7699f1..7234788 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
@@ -16,15 +16,19 @@
 
 package com.android.settingslib.fuelgauge;
 
+import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.IDeviceIdleController;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.UserHandle;
 import android.support.annotation.VisibleForTesting;
+import android.telecom.DefaultDialerManager;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
 
+import com.android.internal.telephony.SmsApplication;
 import com.android.internal.util.ArrayUtils;
 
 /**
@@ -38,19 +42,20 @@
 
     private static PowerWhitelistBackend sInstance;
 
+    private final Context mAppContext;
     private final IDeviceIdleController mDeviceIdleService;
     private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
     private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
     private final ArraySet<String> mSysWhitelistedAppsExceptIdle = new ArraySet<>();
 
-    public PowerWhitelistBackend() {
-        mDeviceIdleService = IDeviceIdleController.Stub.asInterface(
-                ServiceManager.getService(DEVICE_IDLE_SERVICE));
-        refreshList();
+    public PowerWhitelistBackend(Context context) {
+        this(context, IDeviceIdleController.Stub.asInterface(
+                ServiceManager.getService(DEVICE_IDLE_SERVICE)));
     }
 
     @VisibleForTesting
-    PowerWhitelistBackend(IDeviceIdleController deviceIdleService) {
+    PowerWhitelistBackend(Context context, IDeviceIdleController deviceIdleService) {
+        mAppContext = context.getApplicationContext();
         mDeviceIdleService = deviceIdleService;
         refreshList();
     }
@@ -64,7 +69,27 @@
     }
 
     public boolean isWhitelisted(String pkg) {
-        return mWhitelistedApps.contains(pkg);
+        if (mWhitelistedApps.contains(pkg)) {
+            return true;
+        }
+
+        // Additionally, check if pkg is default dialer/sms. They are considered essential apps and
+        // should be automatically whitelisted (otherwise user may be able to set restriction on
+        // them, leading to bad device behavior.)
+        if (!mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return false;
+        }
+        final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
+                true /* updateIfNeeded */);
+        if (defaultSms != null && TextUtils.equals(pkg, defaultSms.getPackageName())) {
+            return true;
+        }
+
+        final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext);
+        if (TextUtils.equals(pkg, defaultDialer)) {
+            return true;
+        }
+        return false;
     }
 
     public boolean isWhitelisted(String[] pkgs) {
@@ -120,16 +145,19 @@
         mSysWhitelistedApps.clear();
         mSysWhitelistedAppsExceptIdle.clear();
         mWhitelistedApps.clear();
+        if (mDeviceIdleService == null) {
+            return;
+        }
         try {
-            String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
+            final String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
             for (String app : whitelistedApps) {
                 mWhitelistedApps.add(app);
             }
-            String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
+            final String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
             for (String app : sysWhitelistedApps) {
                 mSysWhitelistedApps.add(app);
             }
-            String[] sysWhitelistedAppsExceptIdle =
+            final String[] sysWhitelistedAppsExceptIdle =
                     mDeviceIdleService.getSystemPowerWhitelistExceptIdle();
             for (String app : sysWhitelistedAppsExceptIdle) {
                 mSysWhitelistedAppsExceptIdle.add(app);
@@ -139,9 +167,9 @@
         }
     }
 
-    public static PowerWhitelistBackend getInstance() {
+    public static PowerWhitelistBackend getInstance(Context context) {
         if (sInstance == null) {
-            sInstance = new PowerWhitelistBackend();
+            sInstance = new PowerWhitelistBackend(context);
         }
         return sInstance;
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
index 0af2c05..a23eebc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
@@ -23,35 +23,52 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.IDeviceIdleController;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowDefaultDialerManager;
+import com.android.settingslib.testutils.shadow.ShadowSmsApplication;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowDefaultDialerManager.class, ShadowSmsApplication.class})
 public class PowerWhitelistBackendTest {
 
     private static final String PACKAGE_ONE = "com.example.packageone";
     private static final String PACKAGE_TWO = "com.example.packagetwo";
 
-    private PowerWhitelistBackend mPowerWhitelistBackend;
     @Mock
     private IDeviceIdleController mDeviceIdleService;
 
+    private PowerWhitelistBackend mPowerWhitelistBackend;
+    private ShadowPackageManager mPackageManager;
+    private Context mContext;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mContext = RuntimeEnvironment.application;
         doReturn(new String[] {}).when(mDeviceIdleService).getFullPowerWhitelist();
         doReturn(new String[] {}).when(mDeviceIdleService).getSystemPowerWhitelist();
         doReturn(new String[] {}).when(mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
         doNothing().when(mDeviceIdleService).addPowerSaveWhitelistApp(anyString());
         doNothing().when(mDeviceIdleService).removePowerSaveWhitelistApp(anyString());
-        mPowerWhitelistBackend = new PowerWhitelistBackend(mDeviceIdleService);
+        mPackageManager = Shadow.extract(mContext.getPackageManager());
+        mPackageManager.setSystemFeature(PackageManager.FEATURE_TELEPHONY, true);
+
+        mPowerWhitelistBackend = new PowerWhitelistBackend(mContext, mDeviceIdleService);
     }
 
     @Test
@@ -61,8 +78,8 @@
 
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
-        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue();
-        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
 
         mPowerWhitelistBackend.addApp(PACKAGE_TWO);
 
@@ -70,15 +87,15 @@
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isTrue();
         assertThat(mPowerWhitelistBackend.isWhitelisted(
-                new String[]{PACKAGE_ONE, PACKAGE_TWO})).isTrue();
+                new String[] {PACKAGE_ONE, PACKAGE_TWO})).isTrue();
 
         mPowerWhitelistBackend.removeApp(PACKAGE_TWO);
 
         verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO);
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
-        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue();
-        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
 
         mPowerWhitelistBackend.removeApp(PACKAGE_ONE);
 
@@ -86,7 +103,23 @@
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
         assertThat(mPowerWhitelistBackend.isWhitelisted(
-                new String[]{PACKAGE_ONE, PACKAGE_TWO})).isFalse();
+                new String[] {PACKAGE_ONE, PACKAGE_TWO})).isFalse();
+    }
+
+    @Test
+    public void isWhitelisted_shouldWhitelistDefaultSms() {
+        final String testSms = "com.android.test.defaultsms";
+        ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver"));
+
+        assertThat(mPowerWhitelistBackend.isWhitelisted(testSms)).isTrue();
+    }
+
+    @Test
+    public void isWhitelisted_shouldWhitelistDefaultDialer() {
+        final String testDialer = "com.android.test.defaultdialer";
+        ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer);
+
+        assertThat(mPowerWhitelistBackend.isWhitelisted(testDialer)).isTrue();
     }
 
     @Test
@@ -101,7 +134,7 @@
 
     @Test
     public void testIsSystemWhitelistedExceptIdle_onePackage() throws Exception {
-        doReturn(new String[]{PACKAGE_TWO}).when(
+        doReturn(new String[] {PACKAGE_TWO}).when(
                 mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
         mPowerWhitelistBackend.refreshList();
 
@@ -111,7 +144,7 @@
 
     @Test
     public void testIsSystemWhitelistedExceptIdle_packageArray() throws Exception {
-        doReturn(new String[]{PACKAGE_TWO}).when(
+        doReturn(new String[] {PACKAGE_TWO}).when(
                 mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
         mPowerWhitelistBackend.refreshList();
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
new file mode 100644
index 0000000..f4afdb1
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
@@ -0,0 +1,44 @@
+/*
+ * 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.settingslib.testutils.shadow;
+
+import android.content.Context;
+import android.telecom.DefaultDialerManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(DefaultDialerManager.class)
+public class ShadowDefaultDialerManager {
+
+    private static String sDefaultDailer;
+
+    @Resetter
+    public void reset() {
+        sDefaultDailer = null;
+    }
+
+    @Implementation
+    public static String getDefaultDialerApplication(Context context) {
+        return sDefaultDailer;
+    }
+
+    public static void setDefaultDialerApplication(String dialer) {
+        sDefaultDailer = dialer;
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
new file mode 100644
index 0000000..dd7b007
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
@@ -0,0 +1,46 @@
+/*
+ * 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.settingslib.testutils.shadow;
+
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.internal.telephony.SmsApplication;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(SmsApplication.class)
+public class ShadowSmsApplication {
+
+    private static ComponentName sDefaultSmsApplication;
+
+    @Resetter
+    public void reset() {
+        sDefaultSmsApplication = null;
+    }
+
+    @Implementation
+    public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
+        return sDefaultSmsApplication;
+    }
+
+    public static void setDefaultSmsApplication(ComponentName cn) {
+        sDefaultSmsApplication = cn;
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 28e8db9..e1a602b 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -214,4 +214,7 @@
 
     <!-- Default for Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS -->
     <string name="def_backup_agent_timeout_parameters"></string>
+
+    <!-- Default for Settings.System.VIBRATE_WHEN_RINGING -->
+    <bool name="def_vibrate_when_ringing">false</bool>
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index fbe52d1..960d305 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2935,7 +2935,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 168;
+            private static final int SETTINGS_VERSION = 169;
 
             private final int mUserId;
 
@@ -3805,6 +3805,21 @@
                     currentVersion = 168;
                 }
 
+                if (currentVersion == 168) {
+                    // Version 168: by default, vibrate for phone calls
+                    final SettingsState systemSettings = getSystemSettingsLocked(userId);
+                    final Setting currentSetting = systemSettings.getSettingLocked(
+                            Settings.System.VIBRATE_WHEN_RINGING);
+                    if (currentSetting.isNull()) {
+                        systemSettings.insertSettingLocked(
+                                Settings.System.VIBRATE_WHEN_RINGING,
+                                getContext().getResources().getBoolean(
+                                        R.bool.def_vibrate_when_ringing) ? "1" : "0",
+                                null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+                    }
+                    currentVersion = 169;
+                }
+
                 // vXXX: Add new settings above this point.
 
                 if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 89f9e1f..9a3bdf2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -867,6 +867,8 @@
 
     <!-- The size of corner radius of the arrow in the onboarding toast. -->
     <dimen name="recents_onboarding_toast_arrow_corner_radius">2dp</dimen>
+    <!-- The start margin of quick scrub onboarding toast. -->
+    <dimen name="recents_quick_scrub_onboarding_margin_start">8dp</dimen>
 
     <!-- The min alpha to apply to a task affiliation group color. -->
     <item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 8cfba2c..ab82269 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -184,9 +184,15 @@
             return;
         }
         boolean selected = mLastExpansion == 1f;
+
+        // Disable accessibility temporarily while we update selected state purely for the
+        // marquee. This will ensure that accessibility doesn't announce the TYPE_VIEW_SELECTED
+        // event on any of the children.
+        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
         for (int i = 0; i < mPages.size(); i++) {
             mPages.get(i).setSelected(i == getCurrentItem() ? selected : false);
         }
+        setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
     }
 
     public void setPageListener(PageListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 086c87b..8d8e206 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -393,7 +393,20 @@
         if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
             mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 
-            mWindowManager.addView(mLayout, getWindowLayoutParams());
+            final int gravity;
+            final int x;
+            if (stringRes == R.string.recents_swipe_up_onboarding) {
+                gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+                x = 0;
+            } else {
+                int layoutDirection =
+                        mContext.getResources().getConfiguration().getLayoutDirection();
+                gravity = Gravity.BOTTOM | (layoutDirection == View.LAYOUT_DIRECTION_LTR
+                        ? Gravity.LEFT : Gravity.RIGHT);
+                x = mContext.getResources().getDimensionPixelSize(
+                        R.dimen.recents_quick_scrub_onboarding_margin_start);
+            }
+            mWindowManager.addView(mLayout, getWindowLayoutParams(gravity, x));
             mLayout.setAlpha(0);
             mLayout.animate()
                     .alpha(1f)
@@ -459,19 +472,19 @@
         pw.println("    }");
     }
 
-    private WindowManager.LayoutParams getWindowLayoutParams() {
+    private WindowManager.LayoutParams getWindowLayoutParams(int gravity, int x) {
         int flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
                 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.WRAP_CONTENT,
-                0, -mNavBarHeight / 2,
+                ViewGroup.LayoutParams.WRAP_CONTENT,
+                x, -mNavBarHeight / 2,
                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                 flags,
                 PixelFormat.TRANSLUCENT);
         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
         lp.setTitle("RecentsOnboarding");
-        lp.gravity = Gravity.BOTTOM;
+        lp.gravity = gravity;
         return lp;
     }
 
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 03791c7..91a4dda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -182,6 +182,9 @@
             }
         }
         if (mReplyAction != null) {
+            // Let's reset the view on update, assuming the new pending intent isn't cancelled
+            // anymore. The color filter automatically resets when it's updated.
+            mReplyAction.setEnabled(true);
             performOnPendingIntentCancellation(mReplyAction, () -> {
                 if (mReplyAction != null && mReplyAction.isEnabled()) {
                     mReplyAction.setEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 8ede224..879ac92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -16,11 +16,8 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.util.ArraySet;
 import android.util.Pools;
 import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.animation.Interpolator;
 import android.widget.ImageView;
 import android.widget.ProgressBar;
@@ -411,7 +408,8 @@
         mOwnPosition[1] -= (1.0f - mTransformedView.getScaleY()) * mTransformedView.getPivotY();
 
         // Remove local translations
-        mOwnPosition[1] -= MessagingPropertyAnimator.getLocalTranslationY(mTransformedView);
+        mOwnPosition[1] -= MessagingPropertyAnimator.getTop(mTransformedView)
+                - MessagingPropertyAnimator.getLayoutTop(mTransformedView);
         return mOwnPosition;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 3c0b226..894ea62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -114,6 +114,10 @@
         return mVisibility != null ? mVisibility : View.VISIBLE;
     }
 
+    public boolean isVisible() {
+        return getVisibility() == View.VISIBLE;
+    }
+
     public float getAlpha() {
         return mAlpha != null ? mAlpha : 1;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 6c66cab..0fd8df0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -336,13 +336,14 @@
                 int x = (int) event.getX();
                 int y = (int) event.getY();
                 mDownHitTarget = HIT_TARGET_NONE;
-                if (mBackButtonBounds.contains(x, y)) {
+                if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) {
                     mDownHitTarget = HIT_TARGET_BACK;
-                } else if (mHomeButtonBounds.contains(x, y)) {
+                } else if (getHomeButton().isVisible() && mHomeButtonBounds.contains(x, y)) {
                     mDownHitTarget = HIT_TARGET_HOME;
-                } else if (mRecentsButtonBounds.contains(x, y)) {
+                } else if (getRecentsButton().isVisible() && mRecentsButtonBounds.contains(x, y)) {
                     mDownHitTarget = HIT_TARGET_OVERVIEW;
-                } else if (mRotationButtonBounds.contains(x, y)) {
+                } else if (getRotateSuggestionButton().isVisible()
+                        && mRotationButtonBounds.contains(x, y)) {
                     mDownHitTarget = HIT_TARGET_ROTATION;
                 }
                 break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 5f5d12e..5001d4f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -173,11 +173,13 @@
                 || mStatusBar.isFullScreenUserSwitcherState()) {
             mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
         } else if (mShowing && !mDozing) {
-            mBouncer.setExpansion(expansion);
+            if (!isWakeAndUnlocking()) {
+                mBouncer.setExpansion(expansion);
+            }
             if (expansion != KeyguardBouncer.EXPANSION_HIDDEN && tracking
                     && mStatusBar.isKeyguardCurrentlySecure()
                     && !mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
-                mBouncer.show(false /* resetSecuritySelection */, false /* animated */);
+                mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
             }
         }
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 8340ab2..85135ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -16,14 +16,12 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -170,6 +168,15 @@
         verify(mBouncer, never()).setExpansion(eq(0.5f));
     }
 
+    @Test
+    public void onPanelExpansionChanged_neverTranslatesBouncerWhenWakeAndUnlock() {
+        when(mFingerprintUnlockController.getMode())
+                .thenReturn(FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
+        mStatusBarKeyguardViewManager.onPanelExpansionChanged(KeyguardBouncer.EXPANSION_VISIBLE,
+                false /* tracking */);
+        verify(mBouncer, never()).setExpansion(anyFloat());
+    }
+
     private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
 
         public TestableStatusBarKeyguardViewManager(Context context,
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 3beebcb..aa86ea8 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -812,11 +812,12 @@
             resOps = new ArrayList<>();
             for (int j=0; j<pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
-                long duration = curOp.duration == -1
+                final boolean running = curOp.duration == -1;
+                long duration = running
                         ? (elapsedNow - curOp.startRealtime)
                         : curOp.duration;
                 resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                        curOp.rejectTime, (int) duration, curOp.proxyUid,
+                        curOp.rejectTime, (int) duration, running, curOp.proxyUid,
                         curOp.proxyPackageName));
             }
         } else {
@@ -826,11 +827,12 @@
                     if (resOps == null) {
                         resOps = new ArrayList<>();
                     }
-                    long duration = curOp.duration == -1
+                    final boolean running = curOp.duration == -1;
+                    final long duration = running
                             ? (elapsedNow - curOp.startRealtime)
                             : curOp.duration;
                     resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                            curOp.rejectTime, (int) duration, curOp.proxyUid,
+                            curOp.rejectTime, (int) duration, running, curOp.proxyUid,
                             curOp.proxyPackageName));
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4c2a940..ca715b5 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -119,7 +119,7 @@
 
     // How long the startForegroundService() grace period is to get around to
     // calling startForeground() before we ANR + stop it.
-    static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
+    static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
 
     final ActivityManagerService mAm;
 
@@ -501,6 +501,18 @@
             }
         }
 
+        // At this point we've applied allowed-to-start policy based on whether this was
+        // an ordinary startService() or a startForegroundService().  Now, only require that
+        // the app follow through on the startForegroundService() -> startForeground()
+        // contract if it actually targets O+.
+        if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
+            if (DEBUG_BACKGROUND_CHECK || DEBUG_FOREGROUND_SERVICE) {
+                Slog.i(TAG, "startForegroundService() but host targets "
+                        + r.appInfo.targetSdkVersion + " - not requiring startForeground()");
+            }
+            fgRequired = false;
+        }
+
         NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
                 callingUid, r.packageName, service, service.getFlags(), null, r.userId);
 
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 16f4585..d456f62 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2413,11 +2413,16 @@
         }
 
         // Compute configuration based on max supported width and height.
-        outBounds.set(0, 0, maxActivityWidth, maxActivityHeight);
-        // Position the activity frame on the opposite side of the nav bar.
-        final int navBarPosition = service.mWindowManager.getNavBarPosition();
-        final int left = navBarPosition == NAV_BAR_LEFT ? appBounds.right - outBounds.width() : 0;
-        outBounds.offsetTo(left, 0 /* top */);
+        // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
+        // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
+        // bounds would end up too small.
+        outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
+
+        if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) {
+            // Position the activity frame on the opposite side of the nav bar.
+            outBounds.left = appBounds.right - maxActivityWidth;
+            outBounds.right = appBounds.right;
+        }
     }
 
     boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 4e6307d..0f8c526 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1015,26 +1015,25 @@
             locationListener = mFusedLocationListener;
         }
 
-        if (!locationManager.isProviderEnabled(provider)) {
-            Log.w(TAG, "Unable to request location since " + provider
-                    + " provider does not exist or is not enabled.");
-            return;
-        }
-
         Log.i(TAG,
                 String.format(
                         "GNSS HAL Requesting location updates from %s provider for %d millis.",
                         provider, durationMillis));
-        locationManager.requestLocationUpdates(provider,
-                LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
-                locationListener, mHandler.getLooper());
-        locationListener.numLocationUpdateRequest++;
-        mHandler.postDelayed(() -> {
-            if (--locationListener.numLocationUpdateRequest == 0) {
-                Log.i(TAG, String.format("Removing location updates from %s provider.", provider));
-                locationManager.removeUpdates(locationListener);
-            }
-        }, durationMillis);
+        try {
+            locationManager.requestLocationUpdates(provider,
+                    LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
+                    locationListener, mHandler.getLooper());
+            locationListener.numLocationUpdateRequest++;
+            mHandler.postDelayed(() -> {
+                if (--locationListener.numLocationUpdateRequest == 0) {
+                    Log.i(TAG,
+                            String.format("Removing location updates from %s provider.", provider));
+                    locationManager.removeUpdates(locationListener);
+                }
+            }, durationMillis);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "Unable to request location.", e);
+        }
     }
 
     private void injectBestLocation(Location location) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e810b1a..d496ab6 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -17260,17 +17260,6 @@
                                         + "Persistent apps are not updateable.");
                         return;
                     }
-                    // Prevent apps from downgrading their targetSandbox.
-                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
-                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
-                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
-                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
-                                "Package " + pkg.packageName + " new target sandbox "
-                                + newTargetSandbox + " is incompatible with the previous value of"
-                                + oldTargetSandbox + ".");
-                        return;
-                    }
-
                     // Prevent installing of child packages
                     if (oldPackage.parentPackage != null) {
                         res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
index 91ef3d4..ed2b79e 100644
--- a/services/core/java/com/android/server/power/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -392,7 +392,7 @@
         mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
         mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
         mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true);
-        mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, true);
+        mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, false);
 
         // Get default value from Settings.Secure
         final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index b8431b1..65c8e96 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -22,7 +22,9 @@
 import static com.android.server.wm.AnimationSpecProto.ALPHA;
 
 import android.graphics.Rect;
+import android.util.Log;
 import android.util.proto.ProtoOutputStream;
+import android.view.Surface;
 import android.view.SurfaceControl;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -171,14 +173,18 @@
      */
     private DimState getDimState(WindowContainer container) {
         if (mDimState == null) {
-            final SurfaceControl ctl = makeDimLayer();
-            mDimState = new DimState(ctl);
-            /**
-             * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's
-             * via state resetting for Dim's with containers.
-             */
-            if (container == null) {
-                mDimState.mDontReset = true;
+            try {
+                final SurfaceControl ctl = makeDimLayer();
+                mDimState = new DimState(ctl);
+                /**
+                 * See documentation on {@link #dimAbove} to understand lifecycle management of
+                 * Dim's via state resetting for Dim's with containers.
+                 */
+                if (container == null) {
+                    mDimState.mDontReset = true;
+                }
+            } catch (Surface.OutOfResourcesException e) {
+                Log.w(TAG, "OutOfResourcesException creating dim surface");
             }
         }
 
@@ -189,6 +195,11 @@
     private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer,
             float alpha) {
         final DimState d = getDimState(container);
+
+        if (d == null) {
+            return;
+        }
+
         if (container != null) {
             // The dim method is called from WindowState.prepareSurfaces(), which is always called
             // in the correct Z from lowest Z to highest. This ensures that the dim layer is always
@@ -208,10 +219,11 @@
      * @param t A Transaction in which to finish the dim.
      */
     void stopDim(SurfaceControl.Transaction t) {
-        DimState d = getDimState(null);
-        t.hide(d.mDimLayer);
-        d.isVisible = false;
-        d.mDontReset = false;
+        if (mDimState != null) {
+            t.hide(mDimState.mDimLayer);
+            mDimState.isVisible = false;
+            mDimState.mDontReset = false;
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 7211533..2bfff26 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -206,6 +206,9 @@
                 }
             }
         });
+        a.mAnim = anim;
+        mRunningAnimations.put(a.mLeash, a);
+
         anim.start();
         if (a.mAnimSpec.canSkipFirstFrame()) {
             // If we can skip the first frame, we start one frame later.
@@ -215,8 +218,6 @@
         // Immediately start the animation by manually applying an animation frame. Otherwise, the
         // start time would only be set in the next frame, leading to a delay.
         anim.doAnimationFrame(mChoreographer.getFrameTime());
-        a.mAnim = anim;
-        mRunningAnimations.put(a.mLeash, a);
     }
 
     private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index c366e4d..7b775f5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -54,7 +54,7 @@
     static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false;
     static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false;
     static final boolean DEBUG_WALLPAPER = false;
-    static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
+    static final boolean DEBUG_WALLPAPER_LIGHT = true || DEBUG_WALLPAPER;
     static final boolean DEBUG_DRAG = false;
     static final boolean DEBUG_SCREEN_ON = false;
     static final boolean DEBUG_SCREENSHOT = false;
diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
index ea0fe45..7f397d6 100644
--- a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
@@ -18,6 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -36,6 +38,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.List;
+
 /**
  * Tests app ops version upgrades
  */
@@ -107,6 +111,46 @@
         verifyNoMoreInteractions(listener);
     }
 
+    @Test
+    public void testIsRunning() throws Exception {
+        final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+        // Start the op
+        appOpsManager.startOp(AppOpsManager.OP_CAMERA);
+
+        assertTrue("Camera should be running", isCameraOn(appOpsManager));
+
+        // Finish the op
+        appOpsManager.finishOp(AppOpsManager.OP_CAMERA);
+
+        assertFalse("Camera should not be running", isCameraOn(appOpsManager));
+    }
+
+    private boolean isCameraOn(AppOpsManager appOpsManager) {
+        List<AppOpsManager.PackageOps> packages
+                = appOpsManager.getPackagesForOps(new int[] {AppOpsManager.OP_CAMERA});
+        // AppOpsManager can return null when there is no requested data.
+        if (packages != null) {
+            final int numPackages = packages.size();
+            for (int packageInd = 0; packageInd < numPackages; packageInd++) {
+                AppOpsManager.PackageOps packageOp = packages.get(packageInd);
+                List<AppOpsManager.OpEntry> opEntries = packageOp.getOps();
+                if (opEntries != null) {
+                    final int numOps = opEntries.size();
+                    for (int opInd = 0; opInd < numOps; opInd++) {
+                        AppOpsManager.OpEntry opEntry = opEntries.get(opInd);
+                        if (opEntry.getOp() == AppOpsManager.OP_CAMERA) {
+                            if (opEntry.isRunning()) {
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
     private static Context getContext() {
         return InstrumentationRegistry.getContext();
     }