Merge "Fix build break" into pi-dev
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 88300db..4c7dc11 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1132,8 +1132,7 @@
             if (mSaveTriggerId != null && mSaveTriggerId.equals(id)) {
                 if (sDebug) Log.d(TAG, "triggering commit by click of " + id);
                 commitLocked();
-                mMetricsLogger.action(MetricsEvent.AUTOFILL_SAVE_EXPLICITLY_TRIGGERED,
-                        mContext.getPackageName());
+                mMetricsLogger.write(newLog(MetricsEvent.AUTOFILL_SAVE_EXPLICITLY_TRIGGERED));
             }
         }
     }
@@ -1893,14 +1892,19 @@
                 }
             }
 
-            final LogMaker log = new LogMaker(MetricsEvent.AUTOFILL_DATASET_APPLIED)
-                    .setPackageName(mContext.getPackageName())
+            mMetricsLogger.write(newLog(MetricsEvent.AUTOFILL_DATASET_APPLIED)
                     .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, itemCount)
-                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, numApplied);
-            mMetricsLogger.write(log);
+                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VIEWS_FILLED, numApplied));
         }
     }
 
+    private LogMaker newLog(int category) {
+        return new LogMaker(category)
+                .setPackageName(mContext.getPackageName())
+                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE,
+                        isCompatibilityModeEnabledLocked() ? 1 : 0);
+    }
+
     /**
      *  Set the tracked views.
      *
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 30a17a1..f066e34 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -57,6 +57,7 @@
 
 import androidx.slice.Slice;
 import androidx.slice.SliceItem;
+import androidx.slice.SliceManager;
 import androidx.slice.core.SliceQuery;
 import androidx.slice.widget.ListContent;
 import androidx.slice.widget.RowContent;
@@ -390,6 +391,11 @@
         }
     }
 
+    public void refresh() {
+        Slice slice = SliceManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+        onChanged(slice);
+    }
+
     public static class Row extends LinearLayout {
 
         /**
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 454528e..f6b5d69 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -287,7 +287,12 @@
         }
     }
 
-    public void refreshTime() {
+    public void dozeTimeTick() {
+        refreshTime();
+        mKeyguardSlice.refresh();
+    }
+
+    private void refreshTime() {
         mClockView.refresh();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index f867b34..c5e66f9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -79,7 +79,6 @@
     private DateFormat mDateFormat;
     private String mLastText;
     private boolean mRegistered;
-    private boolean mRegisteredEveryMinute;
     private String mNextAlarm;
     private NextAlarmController mNextAlarmController;
     protected AlarmManager mAlarmManager;
@@ -175,7 +174,7 @@
         mZenModeController = new ZenModeControllerImpl(getContext(), mHandler);
         mZenModeController.addCallback(this);
         mDatePattern = getContext().getString(R.string.system_ui_aod_date_pattern);
-        registerClockUpdate(false /* everyMinute */);
+        registerClockUpdate();
         updateClock();
         return true;
     }
@@ -214,22 +213,13 @@
     /**
      * Registers a broadcast receiver for clock updates, include date, time zone and manually
      * changing the date/time via the settings app.
-     *
-     * @param everyMinute {@code true} if you also want updates every minute.
      */
-    protected void registerClockUpdate(boolean everyMinute) {
+    private void registerClockUpdate() {
         if (mRegistered) {
-            if (mRegisteredEveryMinute == everyMinute) {
-                return;
-            } else {
-                unregisterClockUpdate();
-            }
+            return;
         }
 
         IntentFilter filter = new IntentFilter();
-        if (everyMinute) {
-            filter.addAction(Intent.ACTION_TIME_TICK);
-        }
         filter.addAction(Intent.ACTION_DATE_CHANGED);
         filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
@@ -237,15 +227,6 @@
         getContext().registerReceiver(mIntentReceiver, filter, null /* permission*/,
                 null /* scheduler */);
         mRegistered = true;
-        mRegisteredEveryMinute = everyMinute;
-    }
-
-    protected void unregisterClockUpdate() {
-        if (!mRegistered) {
-            return;
-        }
-        getContext().unregisterReceiver(mIntentReceiver);
-        mRegistered = false;
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 9fcb090..ee83250 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -212,7 +212,7 @@
     }
 
     public void hideClock(boolean animate) {
-        animateHide(mClockView, animate);
+        animateHiddenState(mClockView, View.GONE, animate);
     }
 
     public void showClock(boolean animate) {
@@ -240,21 +240,29 @@
     }
 
     /**
-     * Hides a view.
+     * Animate a view to INVISIBLE or GONE
      */
-    private void animateHide(final View v, boolean animate) {
+    private void animateHiddenState(final View v, int state, boolean animate) {
         v.animate().cancel();
         if (!animate) {
             v.setAlpha(0f);
-            v.setVisibility(View.INVISIBLE);
+            v.setVisibility(state);
             return;
         }
+
         v.animate()
                 .alpha(0f)
                 .setDuration(160)
                 .setStartDelay(0)
                 .setInterpolator(Interpolators.ALPHA_OUT)
-                .withEndAction(() -> v.setVisibility(View.INVISIBLE));
+                .withEndAction(() -> v.setVisibility(state));
+    }
+
+    /**
+     * Hides a view.
+     */
+    private void animateHide(final View v, boolean animate) {
+        animateHiddenState(v, View.INVISIBLE, animate);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index b650944..b475b64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2267,7 +2267,7 @@
     }
 
     public void onScreenTurningOn() {
-        mKeyguardStatusView.refreshTime();
+        mKeyguardStatusView.dozeTimeTick();
     }
 
     @Override
@@ -2690,7 +2690,7 @@
     }
 
     public void dozeTimeTick() {
-        mKeyguardStatusView.refreshTime();
+        mKeyguardStatusView.dozeTimeTick();
         mKeyguardBottomArea.dozeTimeTick();
         if (mDarkAmount > 0) {
             positionClockAndNotifications();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 210764a..17a4fbc 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -90,6 +90,17 @@
     }
 
     @Test
+    public void refresh_replacesSliceContentAndNotifiesListener() {
+        AtomicBoolean notified = new AtomicBoolean();
+        mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
+            notified.set(true);
+        });
+        mKeyguardSliceView.refresh();
+        Assert.assertTrue("Listener should be notified about slice changes.",
+                notified.get());
+    }
+
+    @Test
     public void getTextColor_whiteTextWhenAOD() {
         // Set text color to red since the default is white and test would always pass
         mKeyguardSliceView.setTextColor(Color.RED);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
new file mode 100644
index 0000000..1d8de2f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.keyguard;
+
+import static org.mockito.Mockito.verify;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.LayoutInflater;
+import android.widget.TextClock;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+
+@SmallTest
+@RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardStatusViewTest extends SysuiTestCase {
+
+    @Mock
+    KeyguardSliceView mKeyguardSlice;
+    @Mock
+    TextClock mClockView;
+    @InjectMocks
+    KeyguardStatusView mKeyguardStatusView;
+
+    @Before
+    public void setUp() {
+        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+        mKeyguardStatusView =
+                (KeyguardStatusView) layoutInflater.inflate(R.layout.keyguard_status_view, null);
+        org.mockito.MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void dozeTimeTick_updatesSlice() {
+        mKeyguardStatusView.dozeTimeTick();
+        verify(mKeyguardSlice).refresh();
+    }
+
+    @Test
+    public void dozeTimeTick_updatesClock() {
+        mKeyguardStatusView.dozeTimeTick();
+        verify(mClockView).refresh();
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index a45e690..46e2bfb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -85,13 +85,6 @@
     }
 
     @Test
-    public void unregisterClockUpdate() {
-        mProvider.unregisterClockUpdate();
-        Assert.assertFalse("Clock updates should have been unregistered.",
-                mProvider.isRegistered());
-    }
-
-    @Test
     public void returnsValidSlice() {
         Slice slice = mProvider.onBindSlice(mProvider.getUri());
         SliceItem text = SliceQuery.find(slice, android.app.slice.SliceItem.FORMAT_TEXT,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index 9e8fa22..231cdf5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -121,7 +121,7 @@
         fragment.initNotificationIconArea(mMockNotificiationAreaController);
         fragment.disable(StatusBarManager.DISABLE_CLOCK, 0, false);
 
-        assertEquals(View.INVISIBLE, mFragment.getView().findViewById(R.id.clock).getVisibility());
+        assertEquals(View.GONE, mFragment.getView().findViewById(R.id.clock).getVisibility());
 
         fragment.disable(0, 0, false);
 
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d61f228..1541231 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3967,6 +3967,7 @@
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // NOTE: starting on OS P, it also added the following field:
     // Tag FIELD_FLAGS - Flags used to start the session
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SESSION_STARTED = 906;
 
     // An autofill request was processed by a service
@@ -3980,6 +3981,7 @@
     // Type TYPE_CLOSE: Service returned a null response.
     // Tag FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS: if service requested field classification,
     // number of entries field ids in the request.
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_REQUEST = 907;
 
     // Tag of a field for a package of an autofill service
@@ -3998,6 +4000,7 @@
     // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets shown
     // NOTE: starting on OS P, it also added the following field:
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_FILL_UI = 910;
 
     // Tag of a field for the length of the filter text
@@ -4005,12 +4008,17 @@
 
     // An autofill authentication succeeded
     // Package: Package of app that was autofilled
+    // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_AUTHENTICATED = 912;
 
     // An activity was autofilled and all values could be applied
     // Package: Package of app that is autofilled
     // Tag FIELD_AUTOFILL_NUM_VALUES: Number of values that were suggested to be autofilled
     // Tag FIELD_AUTOFILL_NUM_VIEWS_FILLED: Number of views that could be filled
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_DATASET_APPLIED = 913;
 
     // Tag of a field for the number values to be filled in
@@ -4027,6 +4035,7 @@
     // Tag FIELD_AUTOFILL_NUM_IDS: The number of ids that are saved
     // NOTE: starting on OS P, it also added the following field:
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_UI = 916;
 
     // Tag of a field for the number of saveable ids
@@ -4038,10 +4047,14 @@
     // Type TYPE_FAILURE: The request failed
     // Package: Package of app that was autofilled
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_DATA_SAVE_REQUEST = 918;
 
     // An auto-fill session was finished
     // Package: Package of app that was autofilled
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SESSION_FINISHED = 919;
 
     // meta-event: a reader has checkpointed the log here.
@@ -4167,6 +4180,8 @@
     // Package: Real package of the app being autofilled
     // Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request
     // TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948;
 
     // FIELD - The component that an app tried tro forged.
@@ -4624,6 +4639,8 @@
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_PREVIOUS_LENGTH: the previous length of the value
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_VALUE_RESET = 1124;
 
     // Tag of AUTOFILL_VALUE_RESET
@@ -4634,18 +4651,24 @@
     // Package: Package of app that was autofilled
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_DATASET_AUTHENTICATED = 1126;
 
     // An autofill service provided an invalid dataset authentication
     // Package: Package of app that was autofilled
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_INVALID_DATASET_AUTHENTICATION = 1127;
 
     // An autofill service provided an invalid authentication extra
     // Package: Package of app that was autofilled
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_INVALID_AUTHENTICATION = 1128;
 
     // An autofill service used a custom description (using RemoteViews) in the autofill save UI
@@ -4653,6 +4676,8 @@
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_CUSTOM_DESCRIPTION = 1129;
 
     // FIELD - Type of save object passed by the service when the Save UI is shown
@@ -4664,6 +4689,8 @@
     // OS: O MR
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_CUSTOM_SUBTITLE = 1131;
 
     // User tapped a link in the custom description of the autofill save UI provided by an autofill service
@@ -4674,6 +4701,8 @@
     // Type TYPE_FAILURE: The link could not launc an activity
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_LINK_TAPPED = 1132;
 
     // Result of the validation on save when an autofill service provided a validator
@@ -4684,6 +4713,8 @@
     // Type TYPE_DISMISS: The validation failed
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_VALIDATION = 1133;
 
     // Result of an operation in the autofill save UI after the user tapped a link in the custom description
@@ -4693,6 +4724,8 @@
     // Type TYPE_OPEN: The autofill save UI was restored
     // Type TYPE_DISMISS: The autofill save UI was destroyed
     // Type TYPE_FAILURE: An invalid opperation was reported by the app's AutofillManager
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_PENDING_SAVE_UI_OPERATION = 1134;
 
     // Autofill service called API that disables itself
@@ -4705,6 +4738,8 @@
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Package: Package of the autofill service
     // OS: O MR
+    // NOTE: starting on OS P, it also added the following field:
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_UI_LATENCY = 1136;
 
     // Action: the snooze leave-behind was shown after the user clicked the snooze icon
@@ -4872,12 +4907,14 @@
     // Package: Package of app that is autofilled
     // OS: P
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION = 1228;
 
     // The autofill context was commited when the user clicked a view explicitly marked by the
     // service as committing it
     // Package: Package of app that is autofilled
     // OS: P
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229;
 
     // OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling
@@ -4890,6 +4927,7 @@
     // OS: P
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SERVICE_DISABLED_APP = 1231;
 
     // An autofill service asked to disable autofill for a given activity.
@@ -4898,6 +4936,7 @@
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_CLASS_NAME: Class name of the activity that is being disabled for autofill
     // Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_SERVICE_DISABLED_ACTIVITY = 1232;
 
     // ACTION: Stop an app and turn on background check
@@ -5109,6 +5148,7 @@
     // OS: P
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
     // Tag FIELD_AUTOFILL_MATCH_SCORE: Average score of the matches, in the range of 0 to 100
+    // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
     AUTOFILL_FIELD_CLASSIFICATION_MATCHES = 1273;
 
     // Tag used to report autofill field classification scores
@@ -5775,6 +5815,9 @@
     // OS: P
     ACTION_STORAGE_MIGRATE_LATER = 1413;
 
+    // Tag used to report whether an activity is being autofilled  on compatibility mode.
+    FIELD_AUTOFILL_COMPAT_MODE = 1414;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index e582daa..6ff9539 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -504,7 +504,7 @@
             sessionId = sRandom.nextInt();
         } while (sessionId == NO_SESSION || mSessions.indexOfKey(sessionId) >= 0);
 
-        assertCallerLocked(componentName);
+        assertCallerLocked(componentName, compatMode);
 
         final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock,
                 sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory,
@@ -518,7 +518,7 @@
     /**
      * Asserts the component is owned by the caller.
      */
-    private void assertCallerLocked(@NonNull ComponentName componentName) {
+    private void assertCallerLocked(@NonNull ComponentName componentName, boolean compatMode) {
         final String packageName = componentName.getPackageName();
         final PackageManager pm = mContext.getPackageManager();
         final int callingUid = Binder.getCallingUid();
@@ -536,7 +536,7 @@
                     + ") passed component (" + componentName + ") owned by UID " + packageUid);
             mMetricsLogger.write(
                     Helper.newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT,
-                            callingPackage, getServicePackageName())
+                            callingPackage, getServicePackageName(), compatMode)
                     .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
                             componentName == null ? "null" : componentName.flattenToShortString()));
 
@@ -774,10 +774,10 @@
             @Nullable ArrayList<String> changedDatasetIds,
             @Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
             @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
-            @NonNull String appPackageName) {
+            @NonNull String appPackageName, boolean compatMode) {
         logContextCommittedLocked(sessionId, clientState, selectedDatasets, ignoredDatasets,
                 changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
-                manuallyFilledDatasetIds, null, null, appPackageName);
+                manuallyFilledDatasetIds, null, null, appPackageName, compatMode);
     }
 
     @GuardedBy("mLock")
@@ -790,7 +790,7 @@
             @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
             @Nullable ArrayList<AutofillId> detectedFieldIdsList,
             @Nullable ArrayList<FieldClassification> detectedFieldClassificationsList,
-            @NonNull String appPackageName) {
+            @NonNull String appPackageName, boolean compatMode) {
         if (isValidEventLocked("logDatasetNotSelected()", sessionId)) {
             if (sVerbose) {
                 Slog.v(TAG, "logContextCommitted() with FieldClassification: id=" + sessionId
@@ -800,7 +800,8 @@
                         + ", changedDatasetIds=" + changedDatasetIds
                         + ", manuallyFilledFieldIds=" + manuallyFilledFieldIds
                         + ", detectedFieldIds=" + detectedFieldIdsList
-                        + ", detectedFieldClassifications=" + detectedFieldClassificationsList);
+                        + ", detectedFieldClassifications=" + detectedFieldClassificationsList
+                        + ", compatMode=" + compatMode);
             }
             AutofillId[] detectedFieldsIds = null;
             FieldClassification[] detectedFieldClassifications = null;
@@ -827,7 +828,7 @@
                 final int averageScore = (int) ((totalScore * 100) / totalSize);
                 mMetricsLogger.write(Helper
                         .newLogMaker(MetricsEvent.AUTOFILL_FIELD_CLASSIFICATION_MATCHES,
-                                appPackageName, getServicePackageName())
+                                appPackageName, getServicePackageName(), compatMode)
                         .setCounterValue(numberFields)
                         .addTaggedData(MetricsEvent.FIELD_AUTOFILL_MATCH_SCORE,
                                 averageScore));
@@ -1122,7 +1123,7 @@
     /**
      * Called by {@link Session} when service asked to disable autofill for an app.
      */
-    void disableAutofillForApp(@NonNull String packageName, long duration) {
+    void disableAutofillForApp(@NonNull String packageName, long duration, boolean compatMode) {
         synchronized (mLock) {
             if (mDisabledApps == null) {
                 mDisabledApps = new ArrayMap<>(1);
@@ -1135,7 +1136,7 @@
             mDisabledApps.put(packageName, expiration);
             int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration;
             mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_APP,
-                    packageName, getServicePackageName())
+                    packageName, getServicePackageName(), compatMode)
                     .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration));
         }
     }
@@ -1143,7 +1144,8 @@
     /**
      * Called by {@link Session} when service asked to disable autofill an app.
      */
-    void disableAutofillForActivity(@NonNull ComponentName componentName, long duration) {
+    void disableAutofillForActivity(@NonNull ComponentName componentName, long duration,
+            boolean compatMode) {
         synchronized (mLock) {
             if (mDisabledActivities == null) {
                 mDisabledActivities = new ArrayMap<>(1);
@@ -1160,7 +1162,8 @@
             mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY)
                     .setComponentName(componentName)
                     .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
-                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration));
+                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration)
+                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0));
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 78526f5..5372d0c 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -21,7 +21,6 @@
 import android.app.assist.AssistStructure;
 import android.app.assist.AssistStructure.ViewNode;
 import android.metrics.LogMaker;
-import android.os.Bundle;
 import android.service.autofill.Dataset;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -35,10 +34,7 @@
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.LinkedList;
-import java.util.Objects;
-import java.util.Set;
 
 public final class Helper {
 
@@ -119,6 +115,13 @@
         return log;
     }
 
+    @NonNull
+    public static LogMaker newLogMaker(int category, String packageName,
+            String servicePackageName, boolean compatMode) {
+        return newLogMaker(category, packageName, servicePackageName)
+                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0);
+    }
+
     public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable CharSequence text) {
         if (text == null) {
             pw.println("null");
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index c055060..88a679b 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -644,9 +644,10 @@
                 Slog.d(TAG, message.toString());
             }
             if ((flags & FillResponse.FLAG_DISABLE_ACTIVITY_ONLY) != 0) {
-                mService.disableAutofillForActivity(mComponentName, disableDuration);
+                mService.disableAutofillForActivity(mComponentName, disableDuration, mCompatMode);
             } else {
-                mService.disableAutofillForApp(mComponentName.getPackageName(), disableDuration);
+                mService.disableAutofillForApp(mComponentName.getPackageName(), disableDuration,
+                        mCompatMode);
             }
             sessionFinishedState = AutofillManager.STATE_DISABLED_BY_SERVICE;
         }
@@ -1251,7 +1252,7 @@
             mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
                     ignoredDatasets, changedFieldIds, changedDatasetIds,
                     manuallyFilledFieldIds, manuallyFilledDatasetIds,
-                    mComponentName.getPackageName());
+                    mComponentName.getPackageName(), mCompatMode);
         }
     }
 
@@ -1306,7 +1307,7 @@
                 mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
                         ignoredDatasets, changedFieldIds, changedDatasetIds,
                         manuallyFilledFieldIds, manuallyFilledDatasetIds,
-                        mComponentName.getPackageName());
+                        mComponentName.getPackageName(), mCompatMode);
                 return;
             }
             final Scores scores = result.getParcelable(EXTRA_SCORES);
@@ -1371,7 +1372,7 @@
             mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
                     ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
                     manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
-                    mComponentName.getPackageName());
+                    mComponentName.getPackageName(), mCompatMode);
         });
 
         fcStrategy.getScores(callback, algorithm, algorithmArgs, currentValues, userValues);
@@ -1602,7 +1603,7 @@
                 getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(),
                         mService.getServicePackageName(), saveInfo, this,
                         mComponentName.getPackageName(), this,
-                        mPendingSaveUi);
+                        mPendingSaveUi, mCompatMode);
                 if (client != null) {
                     try {
                         client.setSaveUiState(id, true);
@@ -2080,7 +2081,7 @@
 
         getUiForShowing().showFillUi(filledId, response, filterText,
                 mService.getServicePackageName(), mComponentName.getPackageName(),
-                mService.getServiceLabel(), mService.getServiceIcon(), this);
+                mService.getServiceLabel(), mService.getServiceIcon(), this, mCompatMode);
 
         synchronized (mLock) {
             if (mUiShownTime == 0) {
@@ -2717,7 +2718,8 @@
     }
 
     private LogMaker newLogMaker(int category, String servicePackageName) {
-        return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName);
+        return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName,
+                mCompatMode);
     }
 
     private void writeLog(int category) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index ee18dc2..811d87be 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -170,13 +170,14 @@
     public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
             @Nullable String filterText, @Nullable String servicePackageName,
             @NonNull String packageName, @NonNull CharSequence serviceLabel,
-            @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback) {
+            @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback, boolean compatMode) {
         if (sDebug) {
             final int size = filterText == null ? 0 : filterText.length();
             Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars");
         }
-        final LogMaker log =
-                Helper.newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, packageName, servicePackageName)
+        final LogMaker log = Helper
+                .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, packageName, servicePackageName,
+                        compatMode)
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FILTERTEXT_LEN,
                         filterText == null ? 0 : filterText.length())
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
@@ -262,14 +263,16 @@
     public void showSaveUi(@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
             @Nullable String servicePackageName, @NonNull SaveInfo info,
             @NonNull ValueFinder valueFinder, @NonNull String packageName,
-            @NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi) {
+            @NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi,
+            boolean compatMode) {
         if (sVerbose) Slog.v(TAG, "showSaveUi() for " + packageName + ": " + info);
         int numIds = 0;
         numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
         numIds += info.getOptionalIds() == null ? 0 : info.getOptionalIds().length;
 
-        final LogMaker log =
-                Helper.newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, packageName, servicePackageName)
+        final LogMaker log = Helper
+                .newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, packageName, servicePackageName,
+                        compatMode)
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_IDS, numIds);
 
         mHandler.post(() -> {
@@ -319,7 +322,7 @@
                     }
                     mMetricsLogger.write(log);
                 }
-            });
+            }, compatMode);
         });
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 80903c1..fa2a0d9 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -60,6 +60,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.server.UiThread;
+import com.android.server.autofill.Helper;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -134,6 +135,7 @@
     private final PendingUi mPendingUi;
     private final String mServicePackageName;
     private final String mPackageName;
+    private final boolean mCompatMode;
 
     private boolean mDestroyed;
 
@@ -141,12 +143,14 @@
            @NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
            @Nullable String servicePackageName, @NonNull String packageName,
            @NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
-           @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener) {
+           @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
+           boolean compatMode) {
         mPendingUi= pendingUi;
         mListener = new OneTimeListener(listener);
         mOverlayControl = overlayControl;
         mServicePackageName = servicePackageName;
         mPackageName = packageName;
+        mCompatMode = compatMode;
 
         context = new ContextThemeWrapper(context, THEME_ID);
         final LayoutInflater inflater = LayoutInflater.from(context);
@@ -409,14 +413,12 @@
     }
 
     private LogMaker newLogMaker(int category, int saveType) {
-        return newLogMaker(category)
+        return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode)
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType);
     }
 
     private LogMaker newLogMaker(int category) {
-        return new LogMaker(category)
-                .setPackageName(mPackageName)
-                .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, mServicePackageName);
+        return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode);
     }
 
     private void writeLog(int category, int saveType) {
@@ -505,6 +507,7 @@
         pw.print(prefix); pw.print("pendingUi: "); pw.println(mPendingUi);
         pw.print(prefix); pw.print("service: "); pw.println(mServicePackageName);
         pw.print(prefix); pw.print("app: "); pw.println(mPackageName);
+        pw.print(prefix); pw.print("compat mode: "); pw.println(mCompatMode);
 
         final View view = mDialog.getWindow().getDecorView();
         final int[] loc = view.getLocationOnScreen();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 9621edd..c0dc750 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1510,6 +1510,10 @@
         return (stack != null && stack.isVisible()) ? stack : null;
     }
 
+    boolean hasSplitScreenPrimaryStack() {
+        return getSplitScreenPrimaryStack() != null;
+    }
+
     /**
      * Like {@link #getSplitScreenPrimaryStack}, but also returns the stack if it's currently
      * not visible.
@@ -1613,6 +1617,18 @@
         mService.mWindowsChanged = true;
     }
 
+    /**
+     * In split-screen mode we process the IME containers above the docked divider
+     * rather than directly above their target.
+     */
+    private boolean skipTraverseChild(WindowContainer child) {
+        if (child == mImeWindowsContainers && mService.mInputMethodTarget != null
+                && !hasSplitScreenPrimaryStack()) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         // Special handling so we can process IME windows with #forAllImeWindows above their IME
@@ -1620,11 +1636,10 @@
         if (traverseTopToBottom) {
             for (int i = mChildren.size() - 1; i >= 0; --i) {
                 final DisplayChildWindowContainer child = mChildren.get(i);
-                if (child == mImeWindowsContainers && mService.mInputMethodTarget != null) {
-                    // In this case the Ime windows will be processed above their target so we skip
-                    // here.
+                if (skipTraverseChild(child)) {
                     continue;
                 }
+
                 if (child.forAllWindows(callback, traverseTopToBottom)) {
                     return true;
                 }
@@ -1633,11 +1648,10 @@
             final int count = mChildren.size();
             for (int i = 0; i < count; i++) {
                 final DisplayChildWindowContainer child = mChildren.get(i);
-                if (child == mImeWindowsContainers && mService.mInputMethodTarget != null) {
-                    // In this case the Ime windows will be processed above their target so we skip
-                    // here.
+                if (skipTraverseChild(child)) {
                     continue;
                 }
+
                 if (child.forAllWindows(callback, traverseTopToBottom)) {
                     return true;
                 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0de3c92..c710c97 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3997,32 +3997,33 @@
         return false;
     }
 
+    private boolean applyImeWindowsIfNeeded(ToBooleanFunction<WindowState> callback,
+            boolean traverseTopToBottom) {
+        // If this window is the current IME target, so we need to process the IME windows
+        // directly above it. The exception is if we are in split screen
+        // in which case we process the IME at the DisplayContent level to
+        // ensure it is above the docked divider.
+        if (isInputMethodTarget() && !inSplitScreenWindowingMode()) {
+            if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private boolean applyInOrderWithImeWindows(ToBooleanFunction<WindowState> callback,
             boolean traverseTopToBottom) {
         if (traverseTopToBottom) {
-            if (isInputMethodTarget()) {
-                // This window is the current IME target, so we need to process the IME windows
-                // directly above it.
-                if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
-                    return true;
-                }
-            }
-            if (callback.apply(this)) {
+            if (applyImeWindowsIfNeeded(callback, traverseTopToBottom)
+                    || callback.apply(this)) {
                 return true;
             }
         } else {
-            if (callback.apply(this)) {
+            if (callback.apply(this)
+                    || applyImeWindowsIfNeeded(callback, traverseTopToBottom)) {
                 return true;
             }
-            if (isInputMethodTarget()) {
-                // This window is the current IME target, so we need to process the IME windows
-                // directly above it.
-                if (getDisplayContent().forAllImeWindows(callback, traverseTopToBottom)) {
-                    return true;
-                }
-            }
         }
-
         return false;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
new file mode 100644
index 0000000..e076399
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Matchers.eq;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.mockito.Mock;
+
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link WindowContainer#forAllWindows} and various implementations.
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class WindowContainerTraversalTests extends WindowTestsBase {
+
+    @Test
+    public void testDockedDividerPosition() throws Exception {
+        final WindowState splitScreenWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
+                mDisplayContent, "splitScreenWindow");
+        final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
+                WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
+                TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
+
+        sWm.mInputMethodTarget = splitScreenWindow;
+
+        Consumer<WindowState> c = mock(Consumer.class);
+        mDisplayContent.forAllWindows(c, false);
+
+        verify(c).accept(eq(mDockedDividerWindow));
+        verify(c).accept(eq(mImeWindow));
+    }
+}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index cd524a5..13e3069 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -46,6 +46,10 @@
 import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
 import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
 import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
 import android.media.soundtrigger.ISoundTriggerDetectionService;
 import android.media.soundtrigger.ISoundTriggerDetectionServiceClient;
 import android.media.soundtrigger.SoundTriggerDetectionService;
@@ -654,8 +658,45 @@
         }
     }
 
-    private interface Operation {
-        void run(int opId, ISoundTriggerDetectionService service) throws RemoteException;
+    /**
+     * A single operation run in a {@link RemoteSoundTriggerDetectionService}.
+     *
+     * <p>Once the remote service is connected either setup + execute or setup + stop is executed.
+     */
+    private static class Operation {
+        private interface ExecuteOp {
+            void run(int opId, ISoundTriggerDetectionService service) throws RemoteException;
+        }
+
+        private final @Nullable Runnable mSetupOp;
+        private final @NonNull ExecuteOp mExecuteOp;
+        private final @Nullable Runnable mDropOp;
+
+        private Operation(@Nullable Runnable setupOp, @NonNull ExecuteOp executeOp,
+                @Nullable Runnable cancelOp) {
+            mSetupOp = setupOp;
+            mExecuteOp = executeOp;
+            mDropOp = cancelOp;
+        }
+
+        private void setup() {
+            if (mSetupOp != null) {
+                mSetupOp.run();
+            }
+        }
+
+        void run(int opId, @NonNull ISoundTriggerDetectionService service) throws RemoteException {
+            setup();
+            mExecuteOp.run(opId, service);
+        }
+
+        void drop() {
+            setup();
+
+            if (mDropOp != null) {
+                mDropOp.run();
+            }
+        }
     }
 
     /**
@@ -902,6 +943,10 @@
         private void runOrAddOperation(Operation op) {
             synchronized (mRemoteServiceLock) {
                 if (mIsDestroyed || mDestroyOnceRunningOpsDone) {
+                    Slog.w(TAG, mPuuid + ": Dropped operation as already destroyed or marked for "
+                            + "destruction");
+
+                    op.drop();
                     return;
                 }
 
@@ -922,9 +967,15 @@
 
                     int opsAdded = mNumOps.getOpsAdded();
                     if (mNumOps.getOpsAdded() >= opsAllowed) {
-                        if (DEBUG || opsAllowed + 10 > opsAdded) {
-                            Slog.w(TAG, mPuuid + ": Dropped operation as too many operations were "
-                                    + "run in last 24 hours");
+                        try {
+                            if (DEBUG || opsAllowed + 10 > opsAdded) {
+                                Slog.w(TAG, mPuuid + ": Dropped operation as too many operations "
+                                        + "were run in last 24 hours");
+                            }
+
+                            op.drop();
+                        } catch (Exception e) {
+                            Slog.e(TAG, mPuuid + ": Could not drop operation", e);
                         }
                     } else {
                         mNumOps.addOp(currentTime);
@@ -972,34 +1023,87 @@
                     + ")");
         }
 
+        /**
+         * Create an AudioRecord enough for starting and releasing the data buffered for the event.
+         *
+         * @param event The event that was received
+         * @return The initialized AudioRecord
+         */
+        private @NonNull AudioRecord createAudioRecordForEvent(
+                @NonNull SoundTrigger.GenericRecognitionEvent event) {
+            AudioAttributes.Builder attributesBuilder = new AudioAttributes.Builder();
+            attributesBuilder.setInternalCapturePreset(MediaRecorder.AudioSource.HOTWORD);
+            AudioAttributes attributes = attributesBuilder.build();
+
+            // Use same AudioFormat processing as in RecognitionEvent.fromParcel
+            AudioFormat originalFormat = event.getCaptureFormat();
+            AudioFormat captureFormat = (new AudioFormat.Builder())
+                    .setChannelMask(originalFormat.getChannelMask())
+                    .setEncoding(originalFormat.getEncoding())
+                    .setSampleRate(originalFormat.getSampleRate())
+                    .build();
+
+            int bufferSize = AudioRecord.getMinBufferSize(
+                    captureFormat.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
+                            ? AudioFormat.SAMPLE_RATE_HZ_MAX
+                            : captureFormat.getSampleRate(),
+                    captureFormat.getChannelCount() == 2
+                            ? AudioFormat.CHANNEL_IN_STEREO
+                            : AudioFormat.CHANNEL_IN_MONO,
+                    captureFormat.getEncoding());
+
+            return new AudioRecord(attributes, captureFormat, bufferSize,
+                    event.getCaptureSession());
+        }
+
         @Override
         public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
             if (DEBUG) Slog.v(TAG, mPuuid + ": Generic sound trigger event: " + event);
 
-            runOrAddOperation((opId, service) -> {
-                if (!mRecognitionConfig.allowMultipleTriggers) {
-                    synchronized (mCallbacksLock) {
-                        mCallbacks.remove(mPuuid.getUuid());
-                    }
-                    mDestroyOnceRunningOpsDone = true;
-                }
+            runOrAddOperation(new Operation(
+                    // always execute:
+                    () -> {
+                        if (!mRecognitionConfig.allowMultipleTriggers) {
+                            // Unregister this remoteService once op is done
+                            synchronized (mCallbacksLock) {
+                                mCallbacks.remove(mPuuid.getUuid());
+                            }
+                            mDestroyOnceRunningOpsDone = true;
+                        }
+                    },
+                    // execute if not throttled:
+                    (opId, service) -> service.onGenericRecognitionEvent(mPuuid, opId, event),
+                    // execute if throttled:
+                    () -> {
+                        if (event.isCaptureAvailable()) {
+                            AudioRecord capturedData = createAudioRecordForEvent(event);
 
-                service.onGenericRecognitionEvent(mPuuid, opId, event);
-            });
+                            // Currently we need to start and release the audio record to reset
+                            // the DSP even if we don't want to process the event
+                            capturedData.startRecording();
+                            capturedData.release();
+                        }
+                    }));
         }
 
         @Override
         public void onError(int status) {
             if (DEBUG) Slog.v(TAG, mPuuid + ": onError: " + status);
 
-            runOrAddOperation((opId, service) -> {
-                synchronized (mCallbacksLock) {
-                    mCallbacks.remove(mPuuid.getUuid());
-                }
-                mDestroyOnceRunningOpsDone = true;
-
-                service.onError(mPuuid, opId, status);
-            });
+            runOrAddOperation(
+                    new Operation(
+                            // always execute:
+                            () -> {
+                                // Unregister this remoteService once op is done
+                                synchronized (mCallbacksLock) {
+                                    mCallbacks.remove(mPuuid.getUuid());
+                                }
+                                mDestroyOnceRunningOpsDone = true;
+                            },
+                            // execute if not throttled:
+                            (opId, service) -> service.onError(mPuuid, opId, status),
+                            // nothing to do if throttled
+                            null));
         }
 
         @Override