Merge "Document system activity intents that may not be implemented" into pi-dev
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index dd869dc..bc43d91 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -506,11 +506,11 @@
     <!-- String containing the apn value for tethering.  May be overriden by secure settings
          TETHER_DUN_APN.  Value is a comma separated series of strings:
          "name,apn,proxy,port,username,password,server,mmsc,mmsproxy,mmsport,mcc,mnc,auth,type",
-         Or string format of ApnSettingV3.
+         Or string format of ApnSettingV3 or higher.
          note that empty fields can be ommitted: "name,apn,,,,,,,,,310,260,,DUN"
          Multiple entries are separated by using string-array:
          "<item>[ApnSettingV3]Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14,,,,,,,spn,testspn</item>
-          <item>[ApnSettingV3]Name1,apn2,,,,,,,,,123,46,,mms|*,IPV6,IP,true,12,,,,,,,,</item>" -->
+          <item>[ApnSettingV5]Name1,apn2,,,,,,,,,123,46,,mms|*,IPV6,IP,true,12,,,,,,,,,,</item>" -->
     <string-array translatable="false" name="config_tether_apndata">
     </string-array>
 
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index 821ee80..44510c2 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -20,6 +20,9 @@
 import junit.framework.TestCase;
 
 public class VintfObjectTest extends TestCase {
+    /**
+     * Sanity check for {@link VintfObject#report VintfObject.report()}.
+     */
     public void testReport() {
         String[] xmls = VintfObject.report();
         assertTrue(xmls.length > 0);
@@ -28,6 +31,6 @@
                 "<manifest version=\"1.0\" type=\"framework\">"));
         // From /system/compatibility-matrix.xml
         assertTrue(String.join("", xmls).contains(
-                "<compatibility-matrix version=\"1.0\" type=\"framework\">"));
+                "<compatibility-matrix version=\"1.0\" type=\"framework\""));
     }
 }
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index c486e68..aa45709 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2540,19 +2540,20 @@
                     if (position < 0) {
                         return -1;
                     }
-                    if (mPosition != position) {
-                        in.seek(position);
-                        mPosition = position;
-                    }
+                    try {
+                        if (mPosition != position) {
+                            in.seek(position);
+                            mPosition = position;
+                        }
 
-                    int bytesRead = in.read(buffer, offset, size);
-                    if (bytesRead < 0) {
-                        mPosition = -1; // need to seek on next read
-                        return -1;
-                    }
-
-                    mPosition += bytesRead;
-                    return bytesRead;
+                        int bytesRead = in.read(buffer, offset, size);
+                        if (bytesRead >= 0) {
+                            mPosition += bytesRead;
+                            return bytesRead;
+                        }
+                    } catch (IOException e) {}
+                    mPosition = -1; // need to seek on next read
+                    return -1;
                 }
 
                 @Override
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 54a1af4..6a2a04a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -47,8 +47,10 @@
             "com.android.settings.category.ia.development";
     public static final String CATEGORY_NOTIFICATIONS =
             "com.android.settings.category.ia.notifications";
-    public static final String CATEGORY_DO_NOT_DISTURB =
-            "com.android.settings.category.ia.dnd";
+    public static final String CATEGORY_DO_NOT_DISTURB = "com.android.settings.category.ia.dnd";
+    public static final String CATEGORY_GESTURES = "com.android.settings.category.ia.gestures";
+    public static final String CATEGORY_NIGHT_LIGHT =
+            "com.android.settings.category.ia.night_light";
 
     public static final Map<String, String> KEY_COMPAT_MAP;
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
index 06e2ee1..b7699f1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
@@ -67,6 +67,19 @@
         return mWhitelistedApps.contains(pkg);
     }
 
+    public boolean isWhitelisted(String[] pkgs) {
+        if (ArrayUtils.isEmpty(pkgs)) {
+            return false;
+        }
+        for (String pkg : pkgs) {
+            if (isWhitelisted(pkg)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     public boolean isSysWhitelistedExceptIdle(String pkg) {
         return mSysWhitelistedAppsExceptIdle.contains(pkg);
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 6025d68..13364ab 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -26,6 +26,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.support.annotation.VisibleForTesting;
+import android.text.format.DateUtils;
 import android.util.IconDrawableFactory;
 import android.util.Log;
 import java.util.ArrayList;
@@ -41,7 +42,8 @@
     @VisibleForTesting
     static final String ANDROID_SYSTEM_PACKAGE_NAME = "android";
 
-    private static final int RECENT_TIME_INTERVAL_MILLIS = 15 * 60 * 1000;
+    // Keep last 24 hours of location app information.
+    private static final long RECENT_TIME_INTERVAL_MILLIS = DateUtils.DAY_IN_MILLIS;
 
     @VisibleForTesting
     static final int[] LOCATION_OPS = new int[] {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index d12473e..f34605c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -57,8 +57,10 @@
         allKeys.add(CategoryKey.CATEGORY_SYSTEM);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
         allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
+        allKeys.add(CategoryKey.CATEGORY_GESTURES);
+        allKeys.add(CategoryKey.CATEGORY_NIGHT_LIGHT);
         // DO NOT REMOVE ANYTHING ABOVE
 
-        assertThat(allKeys.size()).isEqualTo(16);
+        assertThat(allKeys.size()).isEqualTo(18);
     }
 }
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 f591781..0af2c05 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
@@ -61,24 +61,32 @@
 
         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();
 
         mPowerWhitelistBackend.addApp(PACKAGE_TWO);
 
         verify(mDeviceIdleService, atLeastOnce()).addPowerSaveWhitelistApp(PACKAGE_TWO);
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isTrue();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(
+                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();
 
         mPowerWhitelistBackend.removeApp(PACKAGE_ONE);
 
         verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_ONE);
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse();
         assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
+        assertThat(mPowerWhitelistBackend.isWhitelisted(
+                new String[]{PACKAGE_ONE, PACKAGE_TWO})).isFalse();
     }
 
     @Test
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
index 5e0fcef..8a54aee 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/location/RecentLocationAppsTest.java
@@ -37,8 +37,8 @@
     // App running duration in milliseconds
     private static final int DURATION = 10;
     private static final long ONE_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(1);
-    private static final long FOURTEEN_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(14);
-    private static final long TWENTY_MIN_AGO = NOW - TimeUnit.MINUTES.toMillis(20);
+    private static final long TWENTY_THREE_HOURS_AGO = NOW - TimeUnit.HOURS.toMillis(23);
+    private static final long TWO_DAYS_AGO = NOW - TimeUnit.DAYS.toMillis(2);
     private static final String[] TEST_PACKAGE_NAMES =
             {"package_1MinAgo", "package_14MinAgo", "package_20MinAgo"};
 
@@ -74,7 +74,7 @@
         when(mUserManager.getUserProfiles())
                 .thenReturn(Collections.singletonList(new UserHandle(mTestUserId)));
 
-        long[] testRequestTime = {ONE_MIN_AGO, FOURTEEN_MIN_AGO, TWENTY_MIN_AGO};
+        long[] testRequestTime = {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO};
         List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime);
         when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps);
         mockTestApplicationInfos(mTestUserId, TEST_PACKAGE_NAMES);
@@ -91,7 +91,7 @@
         assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]);
         assertThat(requests.get(0).requestFinishTime).isEqualTo(ONE_MIN_AGO + DURATION);
         assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]);
-        assertThat(requests.get(1).requestFinishTime).isEqualTo(FOURTEEN_MIN_AGO + DURATION);
+        assertThat(requests.get(1).requestFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO + DURATION);
     }
 
     @Test
@@ -105,7 +105,7 @@
                         ONE_MIN_AGO,
                         DURATION);
         long[] testRequestTime =
-                {ONE_MIN_AGO, FOURTEEN_MIN_AGO, TWENTY_MIN_AGO, ONE_MIN_AGO};
+                {ONE_MIN_AGO, TWENTY_THREE_HOURS_AGO, TWO_DAYS_AGO, ONE_MIN_AGO};
         List<PackageOps> appOps = createTestPackageOpsList(TEST_PACKAGE_NAMES, testRequestTime);
         appOps.add(androidSystemPackageOps);
         when(mAppOpsManager.getPackagesForOps(RecentLocationApps.LOCATION_OPS)).thenReturn(appOps);
@@ -119,7 +119,7 @@
         assertThat(requests.get(0).packageName).isEqualTo(TEST_PACKAGE_NAMES[0]);
         assertThat(requests.get(0).requestFinishTime).isEqualTo(ONE_MIN_AGO + DURATION);
         assertThat(requests.get(1).packageName).isEqualTo(TEST_PACKAGE_NAMES[1]);
-        assertThat(requests.get(1).requestFinishTime).isEqualTo(FOURTEEN_MIN_AGO + DURATION);
+        assertThat(requests.get(1).requestFinishTime).isEqualTo(TWENTY_THREE_HOURS_AGO + DURATION);
     }
 
     private void mockTestApplicationInfos(int userId, String... packageNameList)
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index b5d48b4..e902c92 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -42,7 +42,7 @@
             android:singleLine="true"
             android:ellipsize="start"
             android:inputType="textShortMessage|textAutoCorrect|textCapSentences"
-            android:imeOptions="actionSend|flagNoExtractUi|flagNoFullscreen" />
+            android:imeOptions="actionSend" />
 
     <FrameLayout
             android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
index c8a5544..7931dfe 100644
--- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
@@ -21,62 +21,70 @@
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/mobile_combo"
     android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_gravity="center_vertical"
-    android:paddingStart="2dp"
-    android:orientation="horizontal">
-    <FrameLayout
-        android:id="@+id/inout_container"
-        android:layout_height="17dp"
+    android:layout_height="match_parent"
+    android:gravity="center_vertical" >
+
+    <com.android.keyguard.AlphaOptimizedLinearLayout
+        android:id="@+id/mobile_group"
         android:layout_width="wrap_content"
-        android:layout_gravity="center_vertical">
-        <ImageView
-            android:id="@+id/mobile_in"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/ic_activity_down"
-            android:visibility="gone"
-            android:paddingEnd="2dp"
-        />
-        <ImageView
-            android:id="@+id/mobile_out"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:src="@drawable/ic_activity_up"
-            android:paddingEnd="2dp"
-            android:visibility="gone"
-        />
-    </FrameLayout>
-    <ImageView
-        android:id="@+id/mobile_type"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:paddingEnd="1dp"
-        android:visibility="gone" />
-    <Space
-        android:id="@+id/mobile_roaming_space"
         android:layout_height="match_parent"
-        android:layout_width="@dimen/roaming_icon_start_padding"
-        android:visibility="gone"
-    />
-    <FrameLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical">
-        <com.android.systemui.statusbar.AnimatedImageView
-            android:id="@+id/mobile_signal"
-            android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:paddingStart="2dp"
+        android:orientation="horizontal" >
+
+        <FrameLayout
+            android:id="@+id/inout_container"
+            android:layout_height="17dp"
             android:layout_width="wrap_content"
-            systemui:hasOverlappingRendering="false"
-        />
+            android:layout_gravity="center_vertical">
+            <ImageView
+                android:id="@+id/mobile_in"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:src="@drawable/ic_activity_down"
+                android:visibility="gone"
+                android:paddingEnd="2dp"
+            />
+            <ImageView
+                android:id="@+id/mobile_out"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:src="@drawable/ic_activity_up"
+                android:paddingEnd="2dp"
+                android:visibility="gone"
+            />
+        </FrameLayout>
         <ImageView
-            android:id="@+id/mobile_roaming"
+            android:id="@+id/mobile_type"
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:paddingEnd="1dp"
+            android:visibility="gone" />
+        <Space
+            android:id="@+id/mobile_roaming_space"
+            android:layout_height="match_parent"
+            android:layout_width="@dimen/roaming_icon_start_padding"
+            android:visibility="gone"
+        />
+        <FrameLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:src="@drawable/stat_sys_roaming"
-            android:contentDescription="@string/data_connection_roaming"
-            android:visibility="gone" />
-    </FrameLayout>
+            android:layout_gravity="center_vertical">
+            <com.android.systemui.statusbar.AnimatedImageView
+                android:id="@+id/mobile_signal"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                systemui:hasOverlappingRendering="false"
+            />
+            <ImageView
+                android:id="@+id/mobile_roaming"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:src="@drawable/stat_sys_roaming"
+                android:contentDescription="@string/data_connection_roaming"
+                android:visibility="gone" />
+        </FrameLayout>
+    </com.android.keyguard.AlphaOptimizedLinearLayout>
 </com.android.systemui.statusbar.StatusBarMobileView>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index 5a0dddc..cc536a5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -57,6 +57,7 @@
     public static final int HIT_TARGET_BACK = 1;
     public static final int HIT_TARGET_HOME = 2;
     public static final int HIT_TARGET_OVERVIEW = 3;
+    public static final int HIT_TARGET_ROTATION = 4;
 
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({FLAG_DISABLE_SWIPE_UP,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index 19980a2..04c500f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN;
+import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON;
 import static com.android.systemui.statusbar.policy.DarkIconDispatcher.getTint;
 import static com.android.systemui.statusbar.policy.DarkIconDispatcher.isInArea;
 
@@ -24,10 +27,14 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 
+import android.widget.LinearLayout;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.keyguard.AlphaOptimizedLinearLayout;
 import com.android.settingslib.graph.SignalDrawable;
@@ -35,10 +42,14 @@
 import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 
-public class StatusBarMobileView extends AlphaOptimizedLinearLayout implements DarkReceiver,
+public class StatusBarMobileView extends FrameLayout implements DarkReceiver,
         StatusIconDisplayable {
     private static final String TAG = "StatusBarMobileView";
 
+    /// Used to show etc dots
+    private StatusBarIconView mDotView;
+    /// The main icon view
+    private LinearLayout mMobileGroup;
     private String mSlot;
     private MobileIconState mState;
     private SignalDrawable mMobileDrawable;
@@ -47,12 +58,17 @@
     private ImageView mOut;
     private ImageView mMobile, mMobileType, mMobileRoaming;
     private View mMobileRoamingSpace;
+    private int mVisibleState = -1;
 
-    public static StatusBarMobileView fromContext(Context context) {
+    public static StatusBarMobileView fromContext(Context context, String slot) {
         LayoutInflater inflater = LayoutInflater.from(context);
-
-        return (StatusBarMobileView)
+        StatusBarMobileView v = (StatusBarMobileView)
                 inflater.inflate(R.layout.status_bar_mobile_signal_group, null);
+
+        v.setSlot(slot);
+        v.init();
+        v.setVisibleState(STATE_ICON);
+        return v;
     }
 
     public StatusBarMobileView(Context context) {
@@ -72,14 +88,8 @@
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-
-        init();
-    }
-
     private void init() {
+        mMobileGroup = findViewById(R.id.mobile_group);
         mMobile = findViewById(R.id.mobile_signal);
         mMobileType = findViewById(R.id.mobile_type);
         mMobileRoaming = findViewById(R.id.mobile_roaming);
@@ -90,6 +100,18 @@
 
         mMobileDrawable = new SignalDrawable(getContext());
         mMobile.setImageDrawable(mMobileDrawable);
+
+        initDotView();
+    }
+
+    private void initDotView() {
+        mDotView = new StatusBarIconView(mContext, mSlot, null);
+        mDotView.setVisibleState(STATE_DOT);
+
+        int width = mContext.getResources().getDimensionPixelSize(R.dimen.status_bar_icon_size);
+        LayoutParams lp = new LayoutParams(width, width);
+        lp.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
+        addView(mDotView, lp);
     }
 
     public void applyMobileState(MobileIconState state) {
@@ -113,9 +135,9 @@
     private void initViewState() {
         setContentDescription(mState.contentDescription);
         if (!mState.visible) {
-            setVisibility(View.GONE);
+            mMobileGroup.setVisibility(View.GONE);
         } else {
-            setVisibility(View.VISIBLE);
+            mMobileGroup.setVisibility(View.VISIBLE);
         }
         mMobileDrawable.setLevel(mState.strengthId);
         if (mState.typeId > 0) {
@@ -137,7 +159,7 @@
     private void updateState(MobileIconState state) {
         setContentDescription(state.contentDescription);
         if (mState.visible != state.visible) {
-            setVisibility(state.visible ? View.VISIBLE : View.GONE);
+            mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE);
         }
         if (mState.strengthId != state.strengthId) {
             mMobileDrawable.setLevel(state.strengthId);
@@ -173,6 +195,8 @@
         mOut.setImageTintList(color);
         mMobileType.setImageTintList(color);
         mMobileRoaming.setImageTintList(color);
+        mDotView.setDecorColor(tint);
+        mDotView.setIconColor(tint, false);
     }
 
     @Override
@@ -194,11 +218,12 @@
         mOut.setImageTintList(list);
         mMobileType.setImageTintList(list);
         mMobileRoaming.setImageTintList(list);
+        mDotView.setDecorColor(color);
     }
 
     @Override
     public void setDecorColor(int color) {
-        //TODO: May also not be needed
+        mDotView.setDecorColor(color);
     }
 
     @Override
@@ -208,12 +233,30 @@
 
     @Override
     public void setVisibleState(int state) {
-        //TODO: May not be needed. Mobile is always expected to be visible (not a dot)
+        if (state == mVisibleState) {
+            return;
+        }
+
+        mVisibleState = state;
+        switch (state) {
+            case STATE_ICON:
+                mMobileGroup.setVisibility(View.VISIBLE);
+                mDotView.setVisibility(View.GONE);
+                break;
+            case STATE_DOT:
+                mMobileGroup.setVisibility(View.INVISIBLE);
+                mDotView.setVisibility(View.VISIBLE);
+                break;
+            case STATE_HIDDEN:
+            default:
+                setVisibility(View.INVISIBLE);
+                break;
+        }
     }
 
     @Override
     public int getVisibleState() {
-        return 0;
+        return mVisibleState;
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 46b4078..e0e991b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -237,9 +237,8 @@
 
     public void addMobileView(MobileIconState state) {
         Log.d(TAG, "addMobileView: ");
-        StatusBarMobileView view = StatusBarMobileView.fromContext(mContext);
+        StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, state.slot);
 
-        view.setSlot(state.slot);
         view.applyMobileState(state);
         view.setStaticDrawableColor(mColor);
 
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 533d5ec..98f9f1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -88,6 +88,7 @@
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
 
 public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
     final static boolean DEBUG = false;
@@ -116,6 +117,7 @@
     private Rect mHomeButtonBounds = new Rect();
     private Rect mBackButtonBounds = new Rect();
     private Rect mRecentsButtonBounds = new Rect();
+    private Rect mRotationButtonBounds = new Rect();
     private int[] mTmpPosition = new int[2];
 
     private KeyButtonDrawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
@@ -341,6 +343,8 @@
                     mDownHitTarget = HIT_TARGET_HOME;
                 } else if (mRecentsButtonBounds.contains(x, y)) {
                     mDownHitTarget = HIT_TARGET_OVERVIEW;
+                } else if (mRotationButtonBounds.contains(x, y)) {
+                    mDownHitTarget = HIT_TARGET_ROTATION;
                 }
                 break;
         }
@@ -893,6 +897,7 @@
         updateButtonLocationOnScreen(getBackButton(), mBackButtonBounds);
         updateButtonLocationOnScreen(getHomeButton(), mHomeButtonBounds);
         updateButtonLocationOnScreen(getRecentsButton(), mRecentsButtonBounds);
+        updateButtonLocationOnScreen(getRotateSuggestionButton(), mRotationButtonBounds);
         mGestureHelper.onLayout(changed, left, top, right, bottom);
         mRecentsOnboarding.setNavBarHeight(getMeasuredHeight());
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 061677c..65cb56c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -249,7 +249,7 @@
 
 public class StatusBar extends SystemUI implements DemoMode,
         DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
-        OnHeadsUpChangedListener, CommandQueue.Callbacks,
+        OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
         ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter {
     public static final boolean MULTIUSER_DEBUG = false;
 
@@ -785,12 +785,7 @@
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
-        mZenController.addCallback(new ZenModeController.Callback() {
-            @Override
-            public void onZenChanged(int zen) {
-                updateEmptyShadeView();
-            }
-        });
+        mZenController.addCallback(this);
         mActivityLaunchAnimator = new ActivityLaunchAnimator(mStatusBarWindow,
                 this,
                 mNotificationPanel,
@@ -3376,6 +3371,7 @@
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(null);
         mDeviceProvisionedController.removeCallback(mUserSetupObserver);
         Dependency.get(ConfigurationController.class).removeCallback(this);
+        mZenController.removeCallback(this);
         mAppOpsListener.destroy();
     }
 
@@ -5536,6 +5532,11 @@
     }
 
     @Override
+    public void onZenChanged(int zen) {
+        updateEmptyShadeView();
+    }
+
+    @Override
     public void showAssistDisclosure() {
         if (mAssistManager != null) {
             mAssistManager.showDisclosure();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 1ba37a9..3b9ee8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -296,8 +296,7 @@
         }
 
         private StatusBarMobileView onCreateStatusBarMobileView(String slot) {
-            StatusBarMobileView view = StatusBarMobileView.fromContext(mContext);
-            view.setSlot(slot);
+            StatusBarMobileView view = StatusBarMobileView.fromContext(mContext, slot);
             return view;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 4538977..0811179 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -49,7 +49,7 @@
     private static final String TAG = "StatusIconContainer";
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_OVERFLOW = false;
-    // Max 5 status icons including battery
+    // Max 8 status icons including battery
     private static final int MAX_ICONS = 7;
     private static final int MAX_DOTS = 1;
 
@@ -152,7 +152,7 @@
 
         int visibleCount = mMeasureViews.size();
         int maxVisible = visibleCount <= MAX_ICONS ? MAX_ICONS : MAX_ICONS - 1;
-        int totalWidth = getPaddingStart() + getPaddingEnd();
+        int totalWidth = mPaddingLeft + mPaddingRight;
         boolean trackWidth = true;
 
         // Measure all children so that they report the correct width
@@ -208,8 +208,8 @@
      */
     private void calculateIconTranslations() {
         mLayoutStates.clear();
-        float width = getWidth() - getPaddingEnd();
-        float translationX = width;
+        float width = getWidth();
+        float translationX = width - getPaddingEnd();
         float contentStart = getPaddingStart();
         int childCount = getChildCount();
         // Underflow === don't show content until that index
@@ -344,10 +344,11 @@
                 animate = true;
             }
 
-            icon.setVisibleState(visibleState);
             if (animate) {
                 animateTo(view, animationProperties);
+                icon.setVisibleState(visibleState);
             } else {
+                icon.setVisibleState(visibleState);
                 super.applyToView(view);
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 59bf982..310f14c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -565,6 +565,11 @@
         @Override
         public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
             final InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
+            //if pinned, set imeOption to keep the behavior like in portrait.
+            if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isPinned()) {
+                outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI
+                        | EditorInfo.IME_FLAG_NO_FULLSCREEN;
+            }
 
             if (mShowImeOnInputConnection && inputConnection != null) {
                 final InputMethodManager imm = InputMethodManager.getInstance();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index 339c115..2031b27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -36,6 +36,7 @@
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ZenRule;
 import android.util.Log;
+import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.qs.GlobalSetting;
@@ -112,6 +113,10 @@
 
     @Override
     public void addCallback(Callback callback) {
+        if (callback == null) {
+            Slog.e(TAG, "Attempted to add a null callback.");
+            return;
+        }
         mCallbacks.add(callback);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index cb509e0..bdeb8bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -314,12 +314,11 @@
 
     @Test
     public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
-        // Bind notification logs an event, so this counts as one invocation for the metrics logger.
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
                 TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true,
                 true);
         mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
-        verify(mMetricsLogger, times(2)).count(anyString(), anyInt());
+        verify(mMetricsLogger, times(1)).count(anyString(), anyInt());
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
index da8017e..ff65587 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ZenModeControllerImplTest.java
@@ -105,4 +105,10 @@
 
         assertTrue(mController.areNotificationsHiddenInShade());
     }
-}
\ No newline at end of file
+
+    @Test
+    public void testAddNullCallback() {
+        mController.addCallback(null);
+        mController.fireConfigChanged(null);
+    }
+}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 51c0488..9b833f7 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -157,6 +157,9 @@
         }
     };
 
+    @GuardedBy("mLock")
+    private boolean mAllowInstantService;
+
     public AutofillManagerService(Context context) {
         super(context);
         mContext = context;
@@ -518,6 +521,23 @@
         sFullScreenMode = mode;
     }
 
+    // Called by Shell command.
+    boolean getAllowInstantService() {
+        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        synchronized (mLock) {
+            return mAllowInstantService;
+        }
+    }
+
+    // Called by Shell command.
+    void setAllowInstantService(boolean mode) {
+        mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+        Slog.i(TAG, "setAllowInstantService(): " + mode);
+        synchronized (mLock) {
+            mAllowInstantService = mode;
+        }
+    }
+
     private void setDebugLocked(boolean debug) {
         com.android.server.autofill.Helper.sDebug = debug;
         android.view.autofill.Helper.sDebug = debug;
@@ -866,7 +886,8 @@
             synchronized (mLock) {
                 final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
                 return service.startSessionLocked(activityToken, getCallingUid(), appCallback,
-                        autofillId, bounds, value, hasCallback, flags, componentName, compatMode);
+                        autofillId, bounds, value, hasCallback, componentName, compatMode,
+                        mAllowInstantService, flags);
             }
         }
 
@@ -1202,6 +1223,7 @@
                     mAutofillCompatState.dump(prefix2, pw);
                     pw.print(prefix2); pw.print("from settings: ");
                     pw.println(getWhitelistedCompatModePackagesFromSettings());
+                    pw.print("Allow instant service: "); pw.println(mAllowInstantService);
                 }
                 if (showHistory) {
                     pw.println(); pw.println("Requests history:"); pw.println();
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 4bd8063..d97253e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -342,7 +342,8 @@
     int startSessionLocked(@NonNull IBinder activityToken, int uid,
             @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId,
             @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback,
-            int flags, @NonNull ComponentName componentName, boolean compatMode) {
+            @NonNull ComponentName componentName, boolean compatMode,
+            boolean bindInstantServiceAllowed, int flags) {
         if (!isEnabledLocked()) {
             return 0;
         }
@@ -372,7 +373,7 @@
         pruneAbandonedSessionsLocked();
 
         final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
-                hasCallback, componentName, compatMode, flags);
+                hasCallback, componentName, compatMode, bindInstantServiceAllowed, flags);
         if (newSession == null) {
             return NO_SESSION;
         }
@@ -491,7 +492,8 @@
     @GuardedBy("mLock")
     private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
             @NonNull IBinder appCallbackToken, boolean hasCallback,
-            @NonNull ComponentName componentName, boolean compatMode, int flags) {
+            @NonNull ComponentName componentName, boolean compatMode,
+            boolean bindInstantServiceAllowed, int flags) {
         // use random ids so that one app cannot know that another app creates sessions
         int sessionId;
         int tries = 0;
@@ -510,7 +512,7 @@
         final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock,
                 sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory,
                 mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, compatMode,
-                flags);
+                bindInstantServiceAllowed, flags);
         mSessions.put(newSession.id, newSession);
 
         return newSession;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index c76c8ac..f7b7ceb4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -86,6 +86,9 @@
             pw.println("  get fc_score [--algorithm ALGORITHM] value1 value2");
             pw.println("    Gets the field classification score for 2 fields.");
             pw.println("");
+            pw.println("  get bind-instant-service-allowed");
+            pw.println("    Gets whether binding to services provided by instant apps is allowed");
+            pw.println("");
             pw.println("  set log_level [off | debug | verbose]");
             pw.println("    Sets the Autofill log level.");
             pw.println("");
@@ -98,6 +101,9 @@
             pw.println("  set full_screen_mode [true | false | default]");
             pw.println("    Sets the Fill UI full screen mode");
             pw.println("");
+            pw.println("  set bind-instant-service-allowed [true | false]");
+            pw.println("    Sets whether binding to services provided by instant apps is allowed");
+            pw.println("");
             pw.println("  list sessions [--user USER_ID]");
             pw.println("    Lists all pending sessions.");
             pw.println("");
@@ -123,6 +129,8 @@
                 return getFieldClassificationScore(pw);
             case "full_screen_mode":
                 return getFullScreenMode(pw);
+            case "bind-instant-service-allowed":
+                return getBindInstantService(pw);
             default:
                 pw.println("Invalid set: " + what);
                 return -1;
@@ -141,6 +149,8 @@
                 return setMaxVisibileDatasets();
             case "full_screen_mode":
                 return setFullScreenMode(pw);
+            case "bind-instant-service-allowed":
+                return setBindInstantService(pw);
             default:
                 pw.println("Invalid set: " + what);
                 return -1;
@@ -259,6 +269,30 @@
         }
     }
 
+    private int getBindInstantService(PrintWriter pw) {
+        if (mService.getAllowInstantService()) {
+            pw.println("true");
+        } else {
+            pw.println("false");
+        }
+        return 0;
+    }
+
+    private int setBindInstantService(PrintWriter pw) {
+        final String mode = getNextArgRequired();
+        switch (mode.toLowerCase()) {
+            case "true":
+                mService.setAllowInstantService(true);
+                return 0;
+            case "false":
+                mService.setAllowInstantService(false);
+                return 0;
+            default:
+                pw.println("Invalid mode: " + mode);
+                return -1;
+        }
+    }
+
     private int requestDestroy(PrintWriter pw) {
         if (!isNextArgSessions(pw)) {
             return -1;
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index 9bec856..ba544f1 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -15,8 +15,6 @@
  */
 package com.android.server.autofill;
 
-import static android.view.autofill.AutofillManager.FC_SERVICE_TIMEOUT;
-
 import static com.android.server.autofill.Helper.sDebug;
 import static com.android.server.autofill.Helper.sVerbose;
 import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
@@ -52,8 +50,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 /**
  * Strategy used to bridge the field classification algorithms provided by a service in an external
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 5372d0c..f781013 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -68,6 +68,9 @@
 
     /**
      * When non-null, overrides whether the UI should be shown on full-screen mode.
+     *
+     * <p>Note: access to this variable is not synchronized because it's "final" on real usage -
+     * it's only set by Shell cmd, for development purposes.
      */
     public static Boolean sFullScreenMode = null;
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index f7a4b73..4ded3fe 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -84,6 +84,8 @@
 
     private final Handler mHandler;
 
+    private final boolean mBindInstantServiceAllowed;
+
     private IAutoFillService mAutoFillService;
 
     private boolean mBinding;
@@ -109,13 +111,14 @@
     }
 
     public RemoteFillService(Context context, ComponentName componentName,
-            int userId, FillServiceCallbacks callbacks) {
+            int userId, FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
         mContext = context;
         mCallbacks = callbacks;
         mComponentName = componentName;
         mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
         mUserId = userId;
         mHandler = new Handler(FgThread.getHandler().getLooper());
+        mBindInstantServiceAllowed = bindInstantServiceAllowed;
     }
 
     public void destroy() {
@@ -207,6 +210,7 @@
                 .append(String.valueOf(isBound())).println();
         pw.append(prefix).append(tab).append("hasPendingRequest=")
                 .append(String.valueOf(mPendingRequest != null)).println();
+        pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
         pw.println();
     }
 
@@ -258,12 +262,17 @@
         if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
         mBinding = true;
 
-        boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection,
-                Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+        int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+        if (mBindInstantServiceAllowed) {
+            flags |= Context.BIND_ALLOW_INSTANT;
+        }
+
+        final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
                 new UserHandle(mUserId));
 
         if (!willBind) {
-            if (sDebug) Slog.d(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent);
+            Slog.w(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent + " using flags "
+                    + flags);
             mBinding = false;
 
             if (!mServiceDied) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 88a679b..73c7172 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -517,7 +517,7 @@
             @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
             @NonNull LocalLog wtfHistory,
             @NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName,
-            boolean compatMode, int flags) {
+            boolean compatMode, boolean bindInstantServiceAllowed, int flags) {
         id = sessionId;
         mFlags = flags;
         this.uid = uid;
@@ -526,7 +526,8 @@
         mLock = lock;
         mUi = ui;
         mHandler = handler;
-        mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this);
+        mRemoteFillService = new RemoteFillService(context, serviceComponentName, userId, this,
+                bindInstantServiceAllowed);
         mActivityToken = activityToken;
         mHasCallback = hasCallback;
         mUiLatencyHistory = uiLatencyHistory;
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 2a76055..cff1a84 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -18,7 +18,6 @@
 
 import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
 import static com.android.server.autofill.Helper.sDebug;
-import static com.android.server.autofill.Helper.sVerbose;
 
 import android.annotation.Nullable;
 import android.graphics.Rect;
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 03d8f39..d7057f4 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -166,7 +166,7 @@
     private SyncManager getSyncManager() {
         synchronized(mSyncManagerLock) {
             try {
-                // Try to create the SyncManager, return null if it fails (e.g. the disk is full).
+                // Try to create the SyncManager, return null if it fails (which it shouldn't).
                 if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest);
             } catch (SQLiteException e) {
                 Log.e(TAG, "Can't create SyncManager", e);
@@ -199,7 +199,7 @@
         final long identityToken = clearCallingIdentity();
         try {
             if (mSyncManager == null) {
-                pw.println("No SyncManager created!  (Disk full?)");
+                pw.println("SyncManager not available yet");
             } else {
                 mSyncManager.dump(fd, pw, dumpAll);
             }
diff --git a/services/core/java/com/android/server/content/SyncJobService.java b/services/core/java/com/android/server/content/SyncJobService.java
index 9980930..089632d 100644
--- a/services/core/java/com/android/server/content/SyncJobService.java
+++ b/services/core/java/com/android/server/content/SyncJobService.java
@@ -115,7 +115,10 @@
             Slog.v(TAG, "onStopJob called " + params.getJobId() + ", reason: "
                     + params.getStopReason());
         }
-        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params));
+        final boolean readyToSync = SyncManager.readyToSync();
+
+        mLogger.log("onStopJob() ", mLogger.jobParametersToString(params),
+                " readyToSync=", readyToSync);
         synchronized (mLock) {
             final int jobId = params.getJobId();
             mJobParamsMap.remove(jobId);
@@ -124,13 +127,15 @@
             final long nowUptime = SystemClock.uptimeMillis();
             final long runtime = nowUptime - startUptime;
 
+
             if (startUptime == 0) {
                 wtf("Job " + jobId + " start uptime not found: "
                         + " params=" + jobParametersToString(params));
             } else if (runtime > 60 * 1000) {
                 // WTF if startSyncH() hasn't happened, *unless* onStopJob() was called too soon.
                 // (1 minute threshold.)
-                if (!mStartedSyncs.get(jobId)) {
+                // Also don't wtf when it's not ready to sync.
+                if (readyToSync && !mStartedSyncs.get(jobId)) {
                     wtf("Job " + jobId + " didn't start: "
                             + " startUptime=" + startUptime
                             + " nowUptime=" + nowUptime
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 5fa4245..33cf11b 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -91,6 +91,7 @@
 import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
@@ -215,6 +216,10 @@
     private static final int SYNC_ADAPTER_CONNECTION_FLAGS = Context.BIND_AUTO_CREATE
             | Context.BIND_NOT_FOREGROUND | Context.BIND_ALLOW_OOM_MANAGEMENT;
 
+    /** Singleton instance. */
+    @GuardedBy("SyncManager.class")
+    private static SyncManager sInstance;
+
     private Context mContext;
 
     private static final AccountAndUser[] INITIAL_ACCOUNTS_ARRAY = new AccountAndUser[0];
@@ -571,6 +576,14 @@
     }
 
     public SyncManager(Context context, boolean factoryTest) {
+        synchronized (SyncManager.class) {
+            if (sInstance == null) {
+                sInstance = this;
+            } else {
+                Slog.wtf(TAG, "SyncManager instantiated multiple times");
+            }
+        }
+
         // Initialize the SyncStorageEngine first, before registering observers
         // and creating threads and so on; it may fail if the disk is full.
         mContext = context;
@@ -2851,6 +2864,16 @@
     }
 
     /**
+     * @return whether the device is ready to run sync jobs.
+     */
+    public static boolean readyToSync() {
+        synchronized (SyncManager.class) {
+            return sInstance != null && sInstance.mProvisioned && sInstance.mBootCompleted
+                    && sInstance.mJobServiceReady;
+        }
+    }
+
+    /**
      * Handles SyncOperation Messages that are posted to the associated
      * HandlerThread.
      */
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 553b4fe..9da6917 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -426,9 +426,13 @@
             removeAnimation(taskAdapter);
         }
 
+        // Clear any pending failsafe runnables
+        mService.mH.removeCallbacks(mFailsafeRunnable);
+
         // Clear references to the runner
         unlinkToDeathOfRunner();
         mRunner = null;
+        mCanceled = true;
 
         // Clear associated input consumers
         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index fbf6691..a2af9b8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -19,6 +19,9 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
+import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.verify;
@@ -82,6 +85,25 @@
         verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
     }
 
+    @Test
+    public void testCancelAfterRemove_expectIgnored() throws Exception {
+        final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
+                false /* isRecentTaskInvisible */);
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+
+        // Remove the app window so that the animation target can not be created
+        appWindow.removeImmediately();
+        mController.startAnimation();
+        mController.cleanupAnimation(REORDER_KEEP_IN_PLACE);
+        try {
+            mController.cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "test");
+        } catch (Exception e) {
+            fail("Unexpected failure when canceling animation after finishing it");
+        }
+    }
+
     private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
         verify(binder, atLeast(0)).asBinder();
         verifyNoMoreInteractions(binder);