Merge "Convert services to Android.bp"
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index f08b402..75cb229 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -11,8 +11,9 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
     apct-perftests-utils \
-    guava \
-    legacy-android-test
+    guava
+
+LOCAL_JAVA_LIBRARIES := android.test.base
 
 LOCAL_PACKAGE_NAME := CorePerfTests
 
diff --git a/cmds/statsd/src/atoms_copy.proto b/cmds/statsd/src/atoms_copy.proto
index 18b2144..72bb38a 100644
--- a/cmds/statsd/src/atoms_copy.proto
+++ b/cmds/statsd/src/atoms_copy.proto
@@ -48,12 +48,14 @@
         SyncStateChanged sync_state_changed = 7;
         ScheduledJobStateChanged scheduled_job_state_changed = 8;
         ScreenBrightnessChanged screen_brightness_changed = 9;
-        // 10-20 are temporarily reserved for wakelocks etc.
         WakelockStateChanged wakelock_state_changed = 10;
-        UidWakelockStateChanged uid_wakelock_state_changed = 11;
-        LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 12;
-        BatterySaverModeStateChanged battery_saver_mode_state_changed = 21;
-        DeviceIdleModeStateChanged device_idle_mode_state_changed = 22;
+        LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11;
+        MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12;
+        WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13;
+        // TODO: 14-19 are blank, but need not be
+        BatterySaverModeStateChanged battery_saver_mode_state_changed = 20;
+        DeviceIdleModeStateChanged device_idle_mode_state_changed = 21;
+        DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22;
         AudioStateChanged audio_state_changed = 23;
         MediaCodecActivityChanged media_codec_activity_changed = 24;
         CameraStateChanged camera_state_changed = 25;
@@ -75,6 +77,8 @@
         SettingChanged setting_changed = 41;
         ActivityForegroundStateChanged activity_foreground_state_changed = 42;
         IsolatedUidChanged isolated_uid_changed = 43;
+        PacketWakeupOccurred packet_wakeup_occurred = 44;
+        DropboxErrorChanged dropbox_error_changed = 45;
         // TODO: Reorder the numbering so that the most frequent occur events occur in the first 15.
     }
 
@@ -91,6 +95,8 @@
         CpuTimePerFreqPulled cpu_time_per_freq_pulled = 1008;
         CpuTimePerUidPulled cpu_time_per_uid_pulled = 1009;
         CpuTimePerUidFreqPulled cpu_time_per_uid_freq_pulled = 1010;
+        WifiActivityEnergyInfoPulled wifi_activity_energy_info_pulled = 1011;
+        ModemActivityInfoPulled modem_activity_info_pulled = 1012;
     }
 }
 
@@ -147,6 +153,7 @@
         STATE_DOZE = 3;
         STATE_DOZE_SUSPEND = 4;
         STATE_VR = 5;
+        STATE_ON_SUSPEND = 6;
     }
     // New screen state.
     optional State display_state = 1;
@@ -179,13 +186,17 @@
     // TODO: What is this?
     optional string name = 2;
 
-    // The state.
-    // TODO: Use an enum.
-    optional int32 event = 3;
+    // What lifecycle state the process changed to.
+    // This enum is specific to atoms.proto.
+    enum Event {
+        PROCESS_FINISHED = 0;
+        PROCESS_STARTED = 1;
+        PROCESS_CRASHED = 2;
+        PROCESS_ANRED = 3;
+    }
+    optional Event event = 3;
 }
 
-
-
 /**
  * Logs when the ble scan state changes.
  *
@@ -417,31 +428,6 @@
 }
 
 /**
- * Logs when an app is holding a wakelock, regardless of the wakelock's name.
- *
- * Logged from:
- *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
- */
-message UidWakelockStateChanged {
-    // TODO: Add attribution instead of uid.
-    optional int32 uid = 1;
-
-    // Type of wakelock.
-    enum Type {
-        PARTIAL = 0;
-        FULL = 1;
-        WINDOW = 2;
-    }
-    optional Type type = 2;
-
-    enum State {
-        OFF = 0;
-        ON = 1;
-    }
-    optional State state = 3;
-}
-
-/**
  * Logs when a partial wakelock is considered 'long' (over 1 min).
  *
  * Logged from:
@@ -482,11 +468,33 @@
  * Logs Doze mode state change.
  *
  * Logged from:
- *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
  */
 message DeviceIdleModeStateChanged {
     // TODO: Use the enum matching BatteryStats.DEVICE_IDLE_MODE_.
-    optional int32 state = 1;
+    enum State {
+        DEVICE_IDLE_MODE_OFF = 0;
+        DEVICE_IDLE_MODE_LIGHT = 1;
+        DEVICE_IDLE_MODE_DEEP = 2;
+    }
+    optional State state = 1;
+}
+
+
+/**
+ * Logs state change of Doze mode including maintenance windows.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ */
+message DeviceIdlingModeStateChanged {
+    // TODO: Use the enum matching BatteryStats.DEVICE_IDLE_MODE_.
+    enum State {
+        DEVICE_IDLE_MODE_OFF = 0;
+        DEVICE_IDLE_MODE_LIGHT = 1;
+        DEVICE_IDLE_MODE_DEEP = 2;
+    }
+    optional State state = 1;
 }
 
 /**
@@ -586,6 +594,49 @@
 message WakeupAlarmOccurred {
     // TODO: Add attribution instead of uid?
     optional int32 uid = 1;
+
+    // Name of the wakeup alarm.
+    optional string tag = 2;
+}
+
+/**
+ * Logs when an an app causes the mobile radio to change state.
+ * Changing from LOW to MEDIUM or HIGH can be considered the app waking the mobile radio.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ */
+message MobileRadioPowerStateChanged {
+    // TODO: Add attribution instead of uid?
+    optional int32 uid = 1;
+
+    // TODO: Reference telephony/java/android/telephony/DataConnectionRealTimeInfo.java states.
+    enum PowerState {
+        DC_POWER_STATE_LOW = 1;
+        DC_POWER_STATE_MEDIUM = 2;
+        DC_POWER_STATE_HIGH = 3;
+    }
+    optional PowerState power_state = 2;
+}
+
+/**
+ * Logs when an an app causes the wifi radio to change state.
+ * Changing from LOW to MEDIUM or HIGH can be considered the app waking the wifi radio.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ */
+message WifiRadioPowerStateChanged {
+    // TODO: Add attribution instead of uid?
+    optional int32 uid = 1;
+
+    // TODO: Reference telephony/java/android/telephony/DataConnectionRealTimeInfo.java states.
+    enum PowerState {
+        DC_POWER_STATE_LOW = 1;
+        DC_POWER_STATE_MEDIUM = 2;
+        DC_POWER_STATE_HIGH = 3;
+    }
+    optional PowerState power_state = 2;
 }
 
 /**
@@ -705,7 +756,7 @@
     optional int32 user = 7;
 }
 
-/*
+/**
  * Logs activity going to foreground or background
  *
  * Logged from:
@@ -723,6 +774,34 @@
 }
 
 /**
+ * Logs when an error is written to dropbox.
+ * Logged from:
+ *      frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
+ */
+message DropboxErrorChanged {
+    // The uid if available. -1 means not available.
+    optional int32 uid = 1;
+
+    // Tag used when recording this error to dropbox. Contains data_ or system_ prefix.
+    optional string tag = 2;
+
+    // The name of the process.
+    optional string process_name = 3;
+
+    // The pid if available. -1 means not available.
+    optional int32 pid = 4;
+
+    // 1 indicates is instant app. -1 indicates Not applicable.
+    optional int32 is_instant_app = 5;
+
+    // The activity name if available.
+    optional string activity_name = 6;
+
+    // 1 indicates in foreground. -1 indicates not available.
+    optional int32 is_foreground = 7;
+}
+
+/**
  * Pulls bytes transferred via wifi (Sum of foreground and background usage).
  *
  * Pulled from:
@@ -817,7 +896,7 @@
     optional int64 time = 4;
 }
 
-/*
+/**
  * Pulls PowerStatePlatformSleepState.
  *
  * Definition here:
@@ -877,7 +956,7 @@
     optional int32 is_create = 3;
 }
 
-/*
+/**
  * Pulls Cpu time per frequency.
  * Note: this should be pulled for gauge metric only, without condition.
  * The puller keeps internal state of last values. It should not be pulled by
@@ -894,7 +973,7 @@
     optional uint64 time = 3;
 }
 
-/*
+/**
  * Pulls Cpu Time Per Uid.
  * Note that isolated process uid time should be attributed to host uids.
  */
@@ -913,4 +992,86 @@
     optional uint64 uid = 1;
     optional uint64 freq_idx = 2;
     optional uint64 time_ms = 3;
+}
+
+/*
+ * Logs the reception of an incoming network packet causing the main system to wake up for
+ * processing that packet. These events are notified by the kernel via Netlink NFLOG to Netd
+ * and processed by WakeupController.cpp.
+ */
+message PacketWakeupOccurred {
+    // The uid owning the socket into which the packet was delivered, or -1 if the packet was
+    // delivered nowhere.
+    optional int32 uid = 1;
+    // The interface name on which the packet was received.
+    optional string iface = 2;
+    // The ethertype value of the packet.
+    optional int32 ethertype = 3;
+    // String representation of the destination MAC address of the packet.
+    optional string destination_hardware_address = 4;
+    // String representation of the source address of the packet if this was an IP packet.
+    optional string source_ip = 5;
+    // String representation of the destination address of the packet if this was an IP packet.
+    optional string destination_ip = 6;
+    // The value of the protocol field if this was an IPv4 packet or the value of the Next Header
+    // field if this was an IPv6 packet. The range of possible values is the same for both IP
+    // families.
+    optional int32 ip_next_header = 7;
+    // The source port if this was a TCP or UDP packet.
+    optional int32 source_port = 8;
+    // The destination port if this was a TCP or UDP packet.
+    optional int32 destination_port = 9;
+}
+
+/**
+ * Pulls Wifi Controller Activity Energy Info
+ */
+message WifiActivityEnergyInfoPulled {
+    // timestamp(wall clock) of record creation
+    optional uint64 timestamp_ms = 1;
+    // stack reported state
+    // TODO: replace this with proto enum
+    optional int32 stack_state = 2;
+    // tx time in ms
+    optional uint64 controller_tx_time_ms = 3;
+    // rx time in ms
+    optional uint64 controller_rx_time_ms = 4;
+    // idle time in ms
+    optional uint64 controller_idle_time_ms = 5;
+    // product of current(mA), voltage(V) and time(ms)
+    optional uint64 controller_energy_used = 6;
+}
+
+/**
+ * Pulls Modem Activity Energy Info
+ */
+message ModemActivityInfoPulled {
+    // timestamp(wall clock) of record creation
+    optional uint64 timestamp_ms = 1;
+    // sleep time in ms.
+    optional uint64 sleep_time_ms = 2;
+    // idle time in ms
+    optional uint64 controller_idle_time_ms = 3;
+    /**
+     * Tx power index
+     * index 0 = tx_power < 0dBm
+     * index 1 = 0dBm < tx_power < 5dBm
+     * index 2 = 5dBm < tx_power < 15dBm
+     * index 3 = 15dBm < tx_power < 20dBm
+     * index 4 = tx_power > 20dBm
+     */
+    // tx time in ms at power level 0
+    optional uint64 controller_tx_time_pl0_ms = 4;
+    // tx time in ms at power level 1
+    optional uint64 controller_tx_time_pl1_ms = 5;
+    // tx time in ms at power level 2
+    optional uint64 controller_tx_time_pl2_ms = 6;
+    // tx time in ms at power level 3
+    optional uint64 controller_tx_time_pl3_ms = 7;
+    // tx time in ms at power level 4
+    optional uint64 controller_tx_time_pl4_ms = 8;
+    // rx time in ms at power level 5
+    optional uint64 controller_rx_time_ms = 9;
+    // product of current(mA), voltage(V) and time(ms)
+    optional uint64 energy_used = 10;
 }
\ No newline at end of file
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
index 5e8f26d..735a327 100644
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
+++ b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
@@ -110,113 +110,7 @@
                 log.getEventMetrics();
         for (StatsLog.EventMetricData event : eventMetricDataWrapper.getDataList()) {
             sb.append(getDateStr(event.getTimestampNanos())).append(": ");
-            switch (event.getAtom().getPushedCase()) {
-                case SETTING_CHANGED:
-                    sb.append("SETTING_CHANGED\n");
-                    break;
-                case SYNC_STATE_CHANGED:
-                    sb.append("SYNC_STATE_CHANGED\n");
-                    break;
-                case AUDIO_STATE_CHANGED:
-                    sb.append("AUDIO_STATE_CHANGED\n");
-                    break;
-                case CAMERA_STATE_CHANGED:
-                    sb.append("CAMERA_STATE_CHANGED\n");
-                    break;
-                case ISOLATED_UID_CHANGED:
-                    sb.append("ISOLATED_UID_CHANGED\n");
-                    break;
-                case SCREEN_STATE_CHANGED:
-                    sb.append("SCREEN_STATE_CHANGED\n");
-                    break;
-                case SENSOR_STATE_CHANGED:
-                    sb.append("SENSOR_STATE_CHANGED\n");
-                    break;
-                case BATTERY_LEVEL_CHANGED:
-                    sb.append("BATTERY_LEVEL_CHANGED\n");
-                    break;
-                case PLUGGED_STATE_CHANGED:
-                    sb.append("PLUGGED_STATE_CHANGED\n");
-                    break;
-                case WAKEUP_ALARM_OCCURRED:
-                    sb.append("WAKEUP_ALARM_OCCURRED\n");
-                    break;
-                case BLE_SCAN_STATE_CHANGED:
-                    sb.append("BLE_SCAN_STATE_CHANGED\n");
-                    break;
-                case CHARGING_STATE_CHANGED:
-                    sb.append("CHARGING_STATE_CHANGED\n");
-                    break;
-                case GPS_SCAN_STATE_CHANGED:
-                    sb.append("GPS_SCAN_STATE_CHANGED\n");
-                    break;
-                case KERNEL_WAKEUP_REPORTED:
-                    sb.append("KERNEL_WAKEUP_REPORTED\n");
-                    break;
-                case WAKELOCK_STATE_CHANGED:
-                    sb.append("WAKELOCK_STATE_CHANGED\n");
-                    break;
-                case WIFI_LOCK_STATE_CHANGED:
-                    sb.append("WIFI_LOCK_STATE_CHANGED\n");
-                    break;
-                case WIFI_SCAN_STATE_CHANGED:
-                    sb.append("WIFI_SCAN_STATE_CHANGED\n");
-                    break;
-                case BLE_SCAN_RESULT_RECEIVED:
-                    sb.append("BLE_SCAN_RESULT_RECEIVED\n");
-                    break;
-                case DEVICE_ON_STATUS_CHANGED:
-                    sb.append("DEVICE_ON_STATUS_CHANGED\n");
-                    break;
-                case FLASHLIGHT_STATE_CHANGED:
-                    sb.append("FLASHLIGHT_STATE_CHANGED\n");
-                    break;
-                case SCREEN_BRIGHTNESS_CHANGED:
-                    sb.append("SCREEN_BRIGHTNESS_CHANGED\n");
-                    break;
-                case UID_PROCESS_STATE_CHANGED:
-                    sb.append("UID_PROCESS_STATE_CHANGED\n");
-                    break;
-                case UID_WAKELOCK_STATE_CHANGED:
-                    sb.append("UID_WAKELOCK_STATE_CHANGED\n");
-                    break;
-                case DEVICE_TEMPERATURE_REPORTED:
-                    sb.append("DEVICE_TEMPERATURE_REPORTED\n");
-                    break;
-                case SCHEDULED_JOB_STATE_CHANGED:
-                    sb.append("SCHEDULED_JOB_STATE_CHANGED\n");
-                    break;
-                case MEDIA_CODEC_ACTIVITY_CHANGED:
-                    sb.append("MEDIA_CODEC_ACTIVITY_CHANGED\n");
-                    break;
-                case WIFI_SIGNAL_STRENGTH_CHANGED:
-                    sb.append("WIFI_SIGNAL_STRENGTH_CHANGED\n");
-                    break;
-                case PHONE_SIGNAL_STRENGTH_CHANGED:
-                    sb.append("PHONE_SIGNAL_STRENGTH_CHANGED\n");
-                    break;
-                case DEVICE_IDLE_MODE_STATE_CHANGED:
-                    sb.append("DEVICE_IDLE_MODE_STATE_CHANGED\n");
-                    break;
-                case BATTERY_SAVER_MODE_STATE_CHANGED:
-                    sb.append("BATTERY_SAVER_MODE_STATE_CHANGED\n");
-                    break;
-                case PROCESS_LIFE_CYCLE_STATE_CHANGED:
-                    sb.append("PROCESS_LIFE_CYCLE_STATE_CHANGED\n");
-                    break;
-                case ACTIVITY_FOREGROUND_STATE_CHANGED:
-                    sb.append("ACTIVITY_FOREGROUND_STATE_CHANGED\n");
-                    break;
-                case BLE_UNOPTIMIZED_SCAN_STATE_CHANGED:
-                    sb.append("BLE_UNOPTIMIZED_SCAN_STATE_CHANGED\n");
-                    break;
-                case LONG_PARTIAL_WAKELOCK_STATE_CHANGED:
-                    sb.append("LONG_PARTIAL_WAKELOCK_STATE_CHANGED\n");
-                    break;
-                case PUSHED_NOT_SET:
-                    sb.append("PUSHED_NOT_SET\n");
-                    break;
-            }
+            sb.append(event.getAtom().getPushedCase().toString()).append("\n");
         }
     }
 
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
index 55c3a73..73a2e74 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
@@ -71,7 +71,7 @@
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mSyncHandle);
-        dest.writeLong(mTxPower);
+        dest.writeInt(mTxPower);
         dest.writeInt(mRssi);
         dest.writeInt(mDataStatus);
         if (mData != null) {
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 1afa8b3..97fdcef 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -445,7 +445,7 @@
  *
  * <p>The {@link #onFillRequest(FillRequest, CancellationSignal, FillCallback)} method is called
  * without the user content. The Android system strips some properties of the
- * {@link android.app.assist.AssistStructure.ViewNode view nodes} passed to these calls, but not all
+ * {@link android.app.assist.AssistStructure.ViewNode view nodes} passed to this call, but not all
  * of them. For example, the data provided in the {@link android.view.ViewStructure.HtmlInfo}
  * objects set by {@link android.webkit.WebView} is never stripped out.
  *
diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java
index 3a84224..ddc92f6 100644
--- a/core/java/android/service/autofill/FillRequest.java
+++ b/core/java/android/service/autofill/FillRequest.java
@@ -127,12 +127,15 @@
     }
 
     /**
-     * Gets the extra client state returned from the last {@link
-     * AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal, FillCallback)
-     * fill request}, so the service can use it for state management.
+     * Gets the latest client state bundle set by the service in a
+     * {@link FillResponse.Builder#setClientState(Bundle) fill response}.
      *
-     * <p>Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
-     * save request} is made, the client state is cleared.
+     * <p><b>Note:</b> Prior to Android {@link android.os.Build.VERSION_CODES#P}, only client state
+     * bundles set by {@link FillResponse.Builder#setClientState(Bundle)} were considered. On
+     * Android {@link android.os.Build.VERSION_CODES#P} and higher, bundles set in the result of
+     * an authenticated request through the
+     * {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE} extra are
+     * also considered (and take precedence when set).
      *
      * @return The client state.
      */
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 06d2b07..04db698 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -49,14 +49,16 @@
 public final class FillResponse implements Parcelable {
 
     /**
-     * Must be set in the last response to generate
-     * {@link FillEventHistory.Event#TYPE_CONTEXT_COMMITTED} events.
+     * Flag used to generate {@link FillEventHistory.Event events} of type
+     * {@link FillEventHistory.Event#TYPE_CONTEXT_COMMITTED}&mdash;if this flag is not passed to
+     * {@link Builder#setFlags(int)}, these events are not generated.
      */
     public static final int FLAG_TRACK_CONTEXT_COMMITED = 0x1;
 
     /**
-     * Used in conjunction to {@link FillResponse.Builder#disableAutofill(long)} to disable autofill
-     * only for the activiy associated with the {@link FillResponse}, instead of the whole app.
+     * Flag used to change the behavior of {@link FillResponse.Builder#disableAutofill(long)}&mdash;
+     * when this flag is passed to {@link Builder#setFlags(int)}, autofill is disabled only for the
+     * activiy that generated the {@link FillRequest}, not the whole app.
      */
     public static final int FLAG_DISABLE_ACTIVITY_ONLY = 0x2;
 
@@ -329,19 +331,16 @@
         }
 
         /**
-         * Sets a {@link Bundle state} that will be passed to subsequent APIs that
-         * manipulate this response. For example, they are passed to subsequent
-         * calls to {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
-         * FillCallback)} and {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}.
-         * You can use this to store intermediate state that is persistent across multiple
-         * fill requests and the subsequent save request.
+         * Sets a bundle with state that is passed to subsequent APIs that manipulate this response.
+         *
+         * <p>You can use this bundle to store intermediate state that is passed to subsequent calls
+         * to {@link AutofillService#onFillRequest(FillRequest, android.os.CancellationSignal,
+         * FillCallback)} and {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)}, and
+         * you can also retrieve it by calling {@link FillEventHistory.Event#getClientState()}.
          *
          * <p>If this method is called on multiple {@link FillResponse} objects for the same
          * screen, just the latest bundle is passed back to the service.
          *
-         * <p>Once a {@link AutofillService#onSaveRequest(SaveRequest, SaveCallback)
-         * save request} is made the client state is cleared.
-         *
          * @param clientState The custom client state.
          * @return This builder.
          */
diff --git a/core/java/android/service/autofill/SaveRequest.java b/core/java/android/service/autofill/SaveRequest.java
index f53967b..4f85e6b 100644
--- a/core/java/android/service/autofill/SaveRequest.java
+++ b/core/java/android/service/autofill/SaveRequest.java
@@ -59,10 +59,11 @@
     }
 
     /**
-     * Gets the latest client state extra returned from the service.
+     * Gets the latest client state bundle set by the service in a
+     * {@link FillResponse.Builder#setClientState(Bundle) fill response}.
      *
      * <p><b>Note:</b> Prior to Android {@link android.os.Build.VERSION_CODES#P}, only client state
-     * bundles set by {@link FillResponse.Builder#setClientState(Bundle)} where considered. On
+     * bundles set by {@link FillResponse.Builder#setClientState(Bundle)} were considered. On
      * Android {@link android.os.Build.VERSION_CODES#P} and higher, bundles set in the result of
      * an authenticated request through the
      * {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE} extra are
diff --git a/core/java/android/service/autofill/Validators.java b/core/java/android/service/autofill/Validators.java
index 1c83868..0f1ba98 100644
--- a/core/java/android/service/autofill/Validators.java
+++ b/core/java/android/service/autofill/Validators.java
@@ -33,6 +33,8 @@
     /**
      * Creates a validator that is only valid if all {@code validators} are valid.
      *
+     * <p>Used to represent an {@code AND} boolean operation in a chain of validators.
+     *
      * @throws IllegalArgumentException if any element of {@code validators} is an instance of a
      * class that is not provided by the Android System.
      */
@@ -44,6 +46,8 @@
     /**
      * Creates a validator that is valid if any of the {@code validators} is valid.
      *
+     * <p>Used to represent an {@code OR} boolean operation in a chain of validators.
+     *
      * @throws IllegalArgumentException if any element of {@code validators} is an instance of a
      * class that is not provided by the Android System.
      */
@@ -53,7 +57,9 @@
     }
 
     /**
-     * Creates a validator that is valid only if {@code validator} is not.
+     * Creates a validator that is valid when {@code validator} is not, and vice versa.
+     *
+     * <p>Used to represent a {@code NOT} boolean operation in a chain of validators.
      *
      * @throws IllegalArgumentException if {@code validator} is an instance of a class that is not
      * provided by the Android System.
diff --git a/core/jni/eventlog_helper.h b/core/jni/eventlog_helper.h
index 3a05195..19628e5 100644
--- a/core/jni/eventlog_helper.h
+++ b/core/jni/eventlog_helper.h
@@ -155,11 +155,6 @@
             return;
         }
 
-        ScopedIntArrayRO tags(env);
-        if (jTags != nullptr) {
-            tags.reset(jTags);
-        }
-
         while (1) {
             log_msg log_msg;
             int ret = android_logger_list_read(logger_list.get(), &log_msg);
@@ -187,6 +182,7 @@
 
             if (jTags != nullptr) {
                 bool found = false;
+                ScopedIntArrayRO tags(env, jTags);
                 for (size_t i = 0; !found && i < tags.size(); ++i) {
                     found = (tag == tags[i]);
                 }
diff --git a/core/tests/ConnectivityManagerTest/Android.mk b/core/tests/ConnectivityManagerTest/Android.mk
index 39cf4a4..5ed93f3 100644
--- a/core/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/ConnectivityManagerTest/Android.mk
@@ -18,8 +18,8 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/core/tests/bandwidthtests/Android.mk b/core/tests/bandwidthtests/Android.mk
index 2af92df..ff9a0fe 100644
--- a/core/tests/bandwidthtests/Android.mk
+++ b/core/tests/bandwidthtests/Android.mk
@@ -22,8 +22,12 @@
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := \
+    android.test.runner \
+    org.apache.http.legacy \
+    android.test.base \
+
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := BandwidthTests
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/bluetoothtests/Android.mk b/core/tests/bluetoothtests/Android.mk
index f53419a..744e5b0 100644
--- a/core/tests/bluetoothtests/Android.mk
+++ b/core/tests/bluetoothtests/Android.mk
@@ -8,8 +8,8 @@
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := BluetoothTests
 LOCAL_CERTIFICATE := platform
 
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
index 47ee2cf..1d9f624 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/Android.mk
@@ -20,8 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-common mockwebserver junit legacy-android-test
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := android-common mockwebserver junit
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := DownloadManagerTestApp
 
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
index b35cbae..193e601 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPerms/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
index 06812b5..9f44767 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsBT/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
index 48bceaf..b4d354c 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsDiffKey/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk b/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
index 569d102..969e588 100644
--- a/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalSharedPermsFL/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_SDK_VERSION := current
 
diff --git a/core/tests/notificationtests/Android.mk b/core/tests/notificationtests/Android.mk
index 0551eb6..30c2dca 100644
--- a/core/tests/notificationtests/Android.mk
+++ b/core/tests/notificationtests/Android.mk
@@ -8,12 +8,11 @@
 LOCAL_SRC_FILES := \
 	$(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 LOCAL_PACKAGE_NAME := NotificationStressTests
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     junit \
-    legacy-android-test \
     ub-uiautomator
 
 include $(BUILD_PACKAGE)
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
index 51adde4..1167f76 100644
--- a/keystore/tests/Android.mk
+++ b/keystore/tests/Android.mk
@@ -21,8 +21,7 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-test \
-    legacy-android-test
+    android-support-test
 
 LOCAL_PACKAGE_NAME := KeystoreTests
 
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
index 77d7bef..4ddacc8 100644
--- a/libs/hwui/Outline.h
+++ b/libs/hwui/Outline.h
@@ -42,8 +42,15 @@
         mBounds.set(left, top, right, bottom);
         mRadius = radius;
 
+
+        // Reuse memory if previous outline was the same shape (rect or round rect).
+        if ( mPath.countVerbs() > 10) {
+            mPath.reset();
+        } else {
+            mPath.rewind();
+        }
+
         // update mPath to reflect new outline
-        mPath.reset();
         if (MathUtils::isPositive(radius)) {
             mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom), radius, radius);
         } else {
diff --git a/media/mca/tests/Android.mk b/media/mca/tests/Android.mk
index eb451f7..394f542 100644
--- a/media/mca/tests/Android.mk
+++ b/media/mca/tests/Android.mk
@@ -4,8 +4,8 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/media/tests/MediaFrameworkTest/Android.mk b/media/tests/MediaFrameworkTest/Android.mk
index 0d9f42b..145cde6 100644
--- a/media/tests/MediaFrameworkTest/Android.mk
+++ b/media/tests/MediaFrameworkTest/Android.mk
@@ -5,13 +5,12 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     mockito-target-minus-junit4 \
     android-support-test \
-    android-ex-camera2 \
-    legacy-android-test
+    android-ex-camera2
 
 LOCAL_PACKAGE_NAME := mediaframeworktest
 
diff --git a/nfc-extras/tests/Android.mk b/nfc-extras/tests/Android.mk
index d8fe5a6..be2bb53 100644
--- a/nfc-extras/tests/Android.mk
+++ b/nfc-extras/tests/Android.mk
@@ -22,7 +22,7 @@
     android.test.runner \
     com.android.nfc_extras
 
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/CarrierDefaultApp/tests/unit/Android.mk b/packages/CarrierDefaultApp/tests/unit/Android.mk
index 63bd0b1..6e120a6 100644
--- a/packages/CarrierDefaultApp/tests/unit/Android.mk
+++ b/packages/CarrierDefaultApp/tests/unit/Android.mk
@@ -19,9 +19,9 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.test.base
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test mockito-target-minus-junit4 legacy-android-test
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test mockito-target-minus-junit4
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/ExtServices/tests/Android.mk b/packages/ExtServices/tests/Android.mk
index 92afbeb..1eb5847 100644
--- a/packages/ExtServices/tests/Android.mk
+++ b/packages/ExtServices/tests/Android.mk
@@ -5,14 +5,13 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
     mockito-target-minus-junit4 \
     espresso-core \
     truth-prebuilt \
-    legacy-android-test \
     testables
 
 # Include all test java files.
diff --git a/packages/InputDevices/res/raw/keyboard_layout_azerbaijani.kcm b/packages/InputDevices/res/raw/keyboard_layout_azerbaijani.kcm
new file mode 100644
index 0000000..69490cc
--- /dev/null
+++ b/packages/InputDevices/res/raw/keyboard_layout_azerbaijani.kcm
@@ -0,0 +1,312 @@
+# Copyright (C) 2017 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.
+
+#
+# Azerbaijan (AZ) keyboard layout.
+#
+
+type OVERLAY
+
+### ROW 1
+
+key GRAVE {
+    label:                              '`'
+    base:                               '`'
+    shift:                              '~'
+}
+
+key 1 {
+    label:                              '1'
+    base:                               '1'
+    shift:                              '!'
+}
+
+key 2 {
+    label:                              '2'
+    base:                               '2'
+    shift:                              '"'
+    ralt:                               '@'
+}
+
+key 3 {
+    label:                              '3'
+    base:                               '3'
+    shift:                              '\u2166'
+}
+
+key 4 {
+    label:                              '4'
+    base:                               '4'
+    shift:                              ';'
+}
+
+key 5 {
+    label:                              '5'
+    base:                               '5'
+    shift:                              '%'
+}
+
+key 6 {
+    label:                              '6'
+    base:                               '6'
+    shift:                              ':'
+    shift+ralt:                         '^'
+}
+
+key 7 {
+    label:                              '7'
+    base:                               '7'
+    shift:                              '?'
+    ralt:                               '&'
+}
+
+key 8 {
+    label:                              '8'
+    base:                               '8'
+    shift:                              '*'
+}
+
+key 9 {
+    label:                              '9'
+    base:                               '9'
+    shift:                              '('
+}
+
+key 0 {
+    label:                              '0'
+    base:                               '0'
+    shift:                              ')'
+}
+
+key MINUS {
+    label:                              '-'
+    base:                               '-'
+    shift:                              '_'
+}
+
+key EQUALS {
+    label:                              '='
+    base:                               '='
+    shift:                              '+'
+}
+
+### ROW 2
+
+key Q {
+    label:                              'Q'
+    base:                               'q'
+    shift, capslock:                    'Q'
+}
+
+key W {
+    label:                              '\u00dc'
+    base:                               '\u00fc'
+    shift, capslock:                    '\u00dc'
+}
+
+key E {
+    label:                              'E'
+    base:                               'e'
+    shift, capslock:                    'E'
+}
+
+key R {
+    label:                              'R'
+    base:                               'r'
+    shift, capslock:                    'R'
+}
+
+key T {
+    label:                              'T'
+    base:                               't'
+    shift, capslock:                    'T'
+}
+
+key Y {
+    label:                              'Y'
+    base:                               'y'
+    shift, capslock:                    'Y'
+}
+
+key U {
+    label:                              'U'
+    base:                               'u'
+    shift, capslock:                    'U'
+}
+
+key I {
+    label:                              '\u0130'
+    base:                               'i'
+    shift, capslock:                    '\u0130'
+}
+
+key O {
+    label:                              'O'
+    base:                               'o'
+    shift, capslock:                    'O'
+}
+
+key P {
+    label:                              'P'
+    base:                               'p'
+    shift, capslock:                    'P'
+}
+
+key LEFT_BRACKET {
+    label:                              '\u00d6'
+    base:                               '\u00f6'
+    shift:                              '\u00d6'
+}
+
+key RIGHT_BRACKET {
+    label:                              '\u011e'
+    base:                               '\u011f'
+    shift:                              '\u011e'
+}
+
+key BACKSLASH {
+    label:                              '\\'
+    base:                               '\\'
+    shift:                              '|'
+}
+
+### ROW 3
+
+key A {
+    label:                              'A'
+    base:                               'a'
+    shift, capslock:                    'A'
+}
+
+key S {
+    label:                              'S'
+    base:                               's'
+    shift, capslock:                    'S'
+}
+
+key D {
+    label:                              'D'
+    base:                               'd'
+    shift, capslock:                    'D'
+}
+
+key F {
+    label:                              'F'
+    base:                               'f'
+    shift, capslock:                    'F'
+}
+
+key G {
+    label:                              'G'
+    base:                               'g'
+    shift, capslock:                    'G'
+}
+
+key H {
+    label:                              'H'
+    base:                               'h'
+    shift, capslock:                    'H'
+}
+
+key J {
+    label:                              'J'
+    base:                               'j'
+    shift, capslock:                    'J'
+}
+
+key K {
+    label:                              'K'
+    base:                               'k'
+    shift, capslock:                    'K'
+}
+
+key L {
+    label:                              'L'
+    base:                               'l'
+    shift, capslock:                    'L'
+}
+
+key SEMICOLON {
+    label:                              'I'
+    base:                               '\u0131'
+    shift:                              'I'
+}
+
+key APOSTROPHE {
+    label:                              '\u018f'
+    base:                               '\u0259'
+    shift:                              '\u018f'
+}
+
+### ROW 4
+
+key Z {
+    label:                              'Z'
+    base:                               'z'
+    shift, capslock:                    'Z'
+}
+
+key X {
+    label:                              'X'
+    base:                               'x'
+    shift, capslock:                    'X'
+}
+
+key C {
+    label:                              'C'
+    base:                               'c'
+    shift, capslock:                    'C'
+}
+
+key V {
+    label:                              'V'
+    base:                               'v'
+    shift, capslock:                    'V'
+}
+
+key B {
+    label:                              'B'
+    base:                               'b'
+    shift, capslock:                    'B'
+}
+
+key N {
+    label:                              'N'
+    base:                               'n'
+    shift, capslock:                    'N'
+}
+
+key M {
+    label:                              'M'
+    base:                               'm'
+    shift, capslock:                    'M'
+}
+
+key COMMA {
+    label:                              '\u00c7'
+    base:                               '\u00e7'
+    shift:                              '\u00c7'
+}
+
+key PERIOD {
+    label:                              '\u015e'
+    base:                               '\u015f'
+    shift:                              '\u015e'
+}
+
+key SLASH {
+    label:                              '.'
+    base:                               '.'
+    shift:                              ','
+}
diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml
index 1e26226..61d3234 100644
--- a/packages/InputDevices/res/values/strings.xml
+++ b/packages/InputDevices/res/values/strings.xml
@@ -122,4 +122,7 @@
 
     <!-- Persian keyboard layout label. [CHAR LIMIT=35] -->
     <string name="keyboard_layout_persian">Persian</string>
+
+    <!-- Azerbaijani keyboard layout label. [CHAR LIMIT=35] -->
+    <string name="keyboard_layout_azerbaijani">Azerbaijani</string>
 </resources>
diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml
index c55711a..c6bfc1f 100644
--- a/packages/InputDevices/res/xml/keyboard_layouts.xml
+++ b/packages/InputDevices/res/xml/keyboard_layouts.xml
@@ -155,4 +155,8 @@
     <keyboard-layout android:name="keyboard_layout_persian"
             android:label="@string/keyboard_layout_persian"
             android:keyboardLayout="@raw/keyboard_layout_persian" />
+
+    <keyboard-layout android:name="keyboard_layout_azerbaijani"
+            android:label="@string/keyboard_layout_azerbaijani"
+            android:keyboardLayout="@raw/keyboard_layout_azerbaijani" />
 </keyboard-layouts>
diff --git a/packages/MtpDocumentsProvider/tests/Android.mk b/packages/MtpDocumentsProvider/tests/Android.mk
index 148cd0d..ba346f4 100644
--- a/packages/MtpDocumentsProvider/tests/Android.mk
+++ b/packages/MtpDocumentsProvider/tests/Android.mk
@@ -3,8 +3,8 @@
 
 LOCAL_MODULE_TAGS := tests
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := MtpDocumentsProviderTests
 LOCAL_INSTRUMENTATION_FOR := MtpDocumentsProvider
 LOCAL_CERTIFICATE := media
diff --git a/packages/SettingsLib/tests/integ/Android.mk b/packages/SettingsLib/tests/integ/Android.mk
index 3c8c8ac..cfb3519d 100644
--- a/packages/SettingsLib/tests/integ/Android.mk
+++ b/packages/SettingsLib/tests/integ/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.test.base
 
 LOCAL_JACK_FLAGS := --multi-dex native
 
@@ -33,7 +33,6 @@
     android-support-test \
     espresso-core \
     mockito-target-minus-junit4 \
-    legacy-android-test \
     truth-prebuilt
 
 # Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
diff --git a/packages/SettingsProvider/Android.mk b/packages/SettingsProvider/Android.mk
index 069e83a..0f2c5ab 100644
--- a/packages/SettingsProvider/Android.mk
+++ b/packages/SettingsProvider/Android.mk
@@ -7,7 +7,7 @@
     src/com/android/providers/settings/EventLogTags.logtags
 
 LOCAL_JAVA_LIBRARIES := telephony-common ims-common
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_PACKAGE_NAME := SettingsProvider
 LOCAL_CERTIFICATE := platform
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 9374d52..287a888 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -11,6 +11,8 @@
                  android:icon="@mipmap/ic_launcher_settings"
                  android:defaultToDeviceProtectedStorage="true"
                  android:directBootAware="true">
+        <uses-library android:name="android.test.runner" />
+
 
         <provider android:name="SettingsProvider"
                   android:authorities="settings"
diff --git a/packages/Shell/tests/Android.mk b/packages/Shell/tests/Android.mk
index 48b757c..7f24a38 100644
--- a/packages/Shell/tests/Android.mk
+++ b/packages/Shell/tests/Android.mk
@@ -6,14 +6,13 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
     mockito-target-minus-junit4 \
     ub-uiautomator \
     junit \
-    legacy-android-test \
 
 LOCAL_PACKAGE_NAME := ShellTests
 LOCAL_COMPATIBILITY_SUITE := device-tests
diff --git a/packages/SystemUI/shared/tests/Android.mk b/packages/SystemUI/shared/tests/Android.mk
index ce3b442..239a4e3 100644
--- a/packages/SystemUI/shared/tests/Android.mk
+++ b/packages/SystemUI/shared/tests/Android.mk
@@ -38,7 +38,6 @@
     mockito-target-minus-junit4 \
     SystemUI-proto \
     SystemUI-tags \
-    legacy-android-test \
     testables \
     truth-prebuilt \
 
@@ -50,4 +49,4 @@
 
 ifeq ($(EXCLUDE_SYSTEMUI_TESTS),)
     include $(BUILD_PACKAGE)
-endif
\ No newline at end of file
+endif
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3a36776..05fcbb0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -204,12 +204,15 @@
             throw new IllegalArgumentException("Cannot change to UNINITIALIZED.");
         }
 
+        final ScrimState oldState = mState;
+        mState = state;
+
         if (mCallback != null) {
             mCallback.onCancelled();
         }
         mCallback = callback;
 
-        state.prepare(mState);
+        state.prepare(oldState);
         mScreenBlankingCallbackCalled = false;
         mAnimationDelay = 0;
         mBlankScreen = state.getBlanksScreen();
@@ -228,8 +231,6 @@
             mKeyguardFadeoutAnimation.cancel();
         }
 
-        mState = state;
-
         // Do not let the device sleep until we're done with all animations
         if (!mWakeLockHeld) {
             if (mWakeLock != null) {
@@ -310,7 +311,6 @@
                     mCurrentInFrontAlpha = 0;
                 }
             } else {
-                Log.w(TAG, "Invalid state, cannot set panel expansion when: " + mState);
                 return;
             }
 
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 80bab72..2566b30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -661,8 +661,7 @@
 
         @Override
         public void onCancelled() {
-            // Transition was cancelled because another one took over.
-            // Nothing to do in here but wait.
+            onFinished();
         }
     };
 
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index b695919..9d44895 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -54,11 +54,15 @@
     mockito-target-minus-junit4 \
     SystemUI-proto \
     SystemUI-tags \
-    legacy-android-test \
     testables \
     truth-prebuilt \
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.car
+LOCAL_JAVA_LIBRARIES := \
+    android.test.runner \
+    telephony-common \
+    android.car \
+    android.test.base \
+
 
 LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
 
diff --git a/packages/VpnDialogs/res/values-bs/strings.xml b/packages/VpnDialogs/res/values-bs/strings.xml
index 1862bb7..56812d5 100644
--- a/packages/VpnDialogs/res/values-bs/strings.xml
+++ b/packages/VpnDialogs/res/values-bs/strings.xml
@@ -24,7 +24,7 @@
     <string name="data_transmitted" msgid="7988167672982199061">"Poslano:"</string>
     <string name="data_received" msgid="4062776929376067820">"Primljeno:"</string>
     <string name="data_value_format" msgid="2192466557826897580">"Broj bajtova: <xliff:g id="NUMBER_0">%1$s</xliff:g>/Broj paketa: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
-    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Ne može se povezati na stalno uključen VPN"</string>
+    <string name="always_on_disconnected_title" msgid="1906740176262776166">"Nije se moguće povezati na stalno uključen VPN"</string>
     <string name="always_on_disconnected_message" msgid="555634519845992917">"Aplikacija <xliff:g id="VPN_APP_0">%1$s</xliff:g> je postavljena da ostane povezana sve vrijeme, ali se trenutno ne može povezati. Telefon će koristiti javnu mrežu dok se ponovo ne mogne povezati s aplikacijom <xliff:g id="VPN_APP_1">%1$s</xliff:g>."</string>
     <string name="always_on_disconnected_message_lockdown" msgid="4232225539869452120">"Aplikacija <xliff:g id="VPN_APP">%1$s</xliff:g> je postavljena da ostane povezana sve vrijeme, ali se trenutno ne može povezati. Nećete biti imati vezu dok se VPN ne mogne ponovo povezati."</string>
     <string name="always_on_disconnected_message_separator" msgid="3310614409322581371">" "</string>
diff --git a/packages/WAPPushManager/tests/Android.mk b/packages/WAPPushManager/tests/Android.mk
index 1dea798..bfc85ab 100644
--- a/packages/WAPPushManager/tests/Android.mk
+++ b/packages/WAPPushManager/tests/Android.mk
@@ -18,8 +18,8 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index ba6bb23..935b787 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3953,6 +3953,10 @@
 
     // An autofill session was started
     // Package: Package of app that is autofilled
+    // NOTE: starting on OS MR1, it also added the following field:
+    // 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
     AUTOFILL_SESSION_STARTED = 906;
 
     // An autofill request was processed by a service
@@ -3960,7 +3964,11 @@
     // Type TYPE_FAILURE: The request failed
     // Package: Package of app that is autofilled
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
-    // Tag FIELD_AUTOFILL_NUM_DATASET: The number of datasets returned (only in success case)
+    // Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets returned (only in success case)
+    // NOTE: starting on OS P, it also added:
+    // 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.
     AUTOFILL_REQUEST = 907;
 
     // Tag of a field for a package of an autofill service
@@ -4863,7 +4871,6 @@
     // Counter: duration (in ms) that autofill will be disabled
     // OS: P
     // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
-    // Tag FIELD_CLASS_NAME: Name of the Package of service that processed the request
     AUTOFILL_SERVICE_DISABLED_APP = 1231;
 
     // An autofill service asked to disable autofill for a given activity.
@@ -5067,6 +5074,26 @@
     // OS: P
     NOTIFICATION_ZEN_MODE_RULE_SELECTION_DIALOG = 1270;
 
+    // Tag of a field for the number of ids in an autofill field classification request.
+    FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS = 1271;
+
+    // An autofill service updated its user data
+    // Package: Package of the autofill service that updated the user data
+    // Counter: number of fields added (or 0 if reset)
+    // OS: P
+    AUTOFILL_USERDATA_UPDATED = 1272;
+
+    // Some data entered by the user matched the field classification requested by the service.
+    // Package: Package of app that is autofilled
+    // Counter: number of matches found
+    // 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
+    AUTOFILL_FIELD_CLASSIFICATION_MATCHES = 1273;
+
+    // Tag used to report autofill field classification scores
+    FIELD_AUTOFILL_MATCH_SCORE = 1274;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/sax/tests/saxtests/Android.mk b/sax/tests/saxtests/Android.mk
index d3fbd05..e0e490c 100644
--- a/sax/tests/saxtests/Android.mk
+++ b/sax/tests/saxtests/Android.mk
@@ -7,8 +7,8 @@
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := FrameworksSaxTests
 
 include $(BUILD_PACKAGE)
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index b2a0ce5..7bc63f0 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -36,6 +36,7 @@
 import android.content.pm.ServiceInfo;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.metrics.LogMaker;
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
@@ -352,7 +353,7 @@
         pruneAbandonedSessionsLocked();
 
         final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken,
-                hasCallback, componentName);
+                hasCallback, componentName, flags);
         if (newSession == null) {
             return NO_SESSION;
         }
@@ -453,7 +454,7 @@
 
     private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid,
             @NonNull IBinder appCallbackToken, boolean hasCallback,
-            @NonNull ComponentName componentName) {
+            @NonNull ComponentName componentName, int flags) {
         // use random ids so that one app cannot know that another app creates sessions
         int sessionId;
         int tries = 0;
@@ -471,7 +472,7 @@
 
         final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock,
                 sessionId, uid, activityToken, appCallbackToken, hasCallback,
-                mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), componentName);
+                mUiLatencyHistory, mInfo.getServiceInfo().getComponentName(), componentName, flags);
         mSessions.put(newSession.id, newSession);
 
         return newSession;
@@ -716,7 +717,8 @@
             @Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
             @Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
             @Nullable ArrayList<AutofillId> detectedFieldIdsList,
-            @Nullable ArrayList<Match> detectedMatchesList) {
+            @Nullable ArrayList<Match> detectedMatchesList,
+            @NonNull String appPackageName) {
 
         synchronized (mLock) {
             if (isValidEventLocked("logDatasetNotSelected()", sessionId)) {
@@ -727,6 +729,19 @@
                     detectedFieldIdsList.toArray(detectedFieldsIds);
                     detectedMatches = new Match[detectedMatchesList.size()];
                     detectedMatchesList.toArray(detectedMatches);
+
+                    final int size = detectedMatchesList.size();
+                    float totalScore = 0;
+                    for (int i = 0; i < size; i++) {
+                        totalScore += detectedMatches[i].getScore();
+                    }
+                    final int averageScore = (int) ((totalScore * 100) / size);
+                    mMetricsLogger.write(
+                            Helper.newLogMaker(MetricsEvent.AUTOFILL_FIELD_CLASSIFICATION_MATCHES,
+                                    appPackageName, getServicePackageName())
+                            .setCounterValue(size)
+                            .addTaggedData(MetricsEvent.FIELD_AUTOFILL_MATCH_SCORE, averageScore));
+
                 }
                 mEventHistory.addEvent(new Event(Event.TYPE_CONTEXT_COMMITTED, null,
                         clientState, selectedDatasets, ignoredDatasets,
@@ -776,6 +791,11 @@
         synchronized (mLock) {
             if (isCalledByServiceLocked("setUserData", callingUid)) {
                 mUserData = userData;
+                // Log it
+                int numberFields = mUserData == null ? 0: mUserData.getRemoteIds().length;
+                mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_USERDATA_UPDATED,
+                        getServicePackageName(), null)
+                        .setCounterValue(numberFields));
             }
         }
     }
@@ -1013,10 +1033,12 @@
                 expiration = Long.MAX_VALUE;
             }
             mDisabledActivities.put(componentName, expiration);
-            int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration;
-            mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY,
-                    componentName.getPackageName(), getServicePackageName())
-                    .addTaggedData(MetricsEvent.FIELD_CLASS_NAME, componentName.getClassName())
+            final int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration;
+            // NOTE: not using Helper.newLogMaker() because we're setting the componentName instead
+            // of package name
+            mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY)
+                    .setComponentName(componentName)
+                    .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
                     .setCounterValue(intDuration));
         }
     }
@@ -1034,7 +1056,8 @@
                 if (expiration >= elapsedTime) return true;
                 // Restriction expired - clean it up.
                 if (sVerbose) {
-                    Slog.v(TAG, "Removing " + componentName.toShortString() + " from disabled list");
+                    Slog.v(TAG, "Removing " + componentName.toShortString()
+                        + " from disabled list");
                 }
                 mDisabledActivities.remove(componentName);
             }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 4e64afb..56f5f64 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -128,6 +128,9 @@
     /** uid the session is for */
     public final int uid;
 
+    /** Flags used to start the session */
+    public final int mFlags;
+
     @GuardedBy("mLock")
     @NonNull private IBinder mActivityToken;
 
@@ -441,8 +444,10 @@
             @NonNull Context context, @NonNull HandlerCaller handlerCaller, int userId,
             @NonNull Object lock, int sessionId, int uid, @NonNull IBinder activityToken,
             @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory,
-            @NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName) {
+            @NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName,
+            int flags) {
         id = sessionId;
+        mFlags = flags;
         this.uid = uid;
         mStartTime = SystemClock.elapsedRealtime();
         mService = service;
@@ -456,7 +461,8 @@
         mComponentName = componentName;
         mClient = IAutoFillManagerClient.Stub.asInterface(client);
 
-        writeLog(MetricsEvent.AUTOFILL_SESSION_STARTED);
+        mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
+                .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
     }
 
     /**
@@ -505,8 +511,9 @@
             }
         }
 
-        // TODO(b/67867469): remove once feature is finished
-        if (response.getFieldClassificationIds() != null && !mService.isFieldClassificationEnabled()) {
+        final AutofillId[] fieldClassificationIds = response.getFieldClassificationIds();
+        // TODO(b/67867469): remove once feature is finished (or use method from AFM to check)
+        if (fieldClassificationIds != null && !mService.isFieldClassificationEnabled()) {
             Slog.w(TAG, "Ignoring " + response + " because field detection is disabled");
             processNullResponseLocked(requestFlags);
             return;
@@ -548,6 +555,10 @@
                 .setType(MetricsEvent.TYPE_SUCCESS)
                 .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
                         response.getDatasets() == null ? 0 : response.getDatasets().size());
+        if (fieldClassificationIds != null) {
+            log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS,
+                    fieldClassificationIds.length);
+        }
         mMetricsLogger.write(log);
     }
 
@@ -1106,7 +1117,7 @@
         mService.logContextCommitted(id, mClientState, mSelectedDatasetIds, ignoredDatasets,
                 changedFieldIds, changedDatasetIds,
                 manuallyFilledFieldIds, manuallyFilledDatasetIds,
-                detectedFieldIds, detectedMatches);
+                detectedFieldIds, detectedMatches, mComponentName.getPackageName());
     }
 
     /**
@@ -2115,6 +2126,7 @@
         final String prefix2 = prefix + "  ";
         pw.print(prefix); pw.print("id: "); pw.println(id);
         pw.print(prefix); pw.print("uid: "); pw.println(uid);
+        pw.print(prefix); pw.print("flags: "); pw.println(mFlags);
         pw.print(prefix); pw.print("mComponentName: "); pw.println(mComponentName);
         pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
         pw.print(prefix); pw.print("mStartTime: "); pw.println(mStartTime);
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index a97b93c..aed49e0 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -105,7 +105,8 @@
     /**
      * TODO(b/64750076): Capture information necessary for dump and
      * {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
-     * around */
+     * around
+     */
     private ActivityStarter mLastStarter;
 
     ActivityStartController(ActivityManagerService service) {
@@ -130,10 +131,16 @@
      *         considered invalid and no longer modified or used.
      */
     ActivityStarter obtainStarter(Intent intent, String reason) {
-        final ActivityStarter starter = mFactory.obtainStarter();
-        mLastStarter = starter;
+        return mFactory.obtain().setIntent(intent).setReason(reason);
+    }
 
-        return starter.setIntent(intent).setReason(reason);
+    void onExecutionComplete(ActivityStarter starter) {
+        if (mLastStarter == null) {
+            mLastStarter = mFactory.obtain();
+        }
+
+        mLastStarter.set(starter);
+        mFactory.recycle(starter);
     }
 
     /**
@@ -142,6 +149,10 @@
      */
     void postStartActivityProcessingForLastStarter(ActivityRecord r, int result,
             ActivityStack targetStack) {
+        if (mLastStarter == null) {
+            return;
+        }
+
         mLastStarter.postStartActivityProcessing(r, result, targetStack);
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 10fb6e2..69cc3c7 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -102,6 +102,7 @@
 import android.service.voice.IVoiceInteractionSession;
 import android.text.TextUtils;
 import android.util.EventLog;
+import android.util.Pools.SynchronizedPool;
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -131,7 +132,6 @@
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mSupervisor;
     private final ActivityStartInterceptor mInterceptor;
-
     private final ActivityStartController mController;
 
     // Share state variable among methods when starting an activity.
@@ -209,18 +209,34 @@
          *                   this instance.
          * @return an {@link ActivityStarter}
          */
-        ActivityStarter obtainStarter();
+        ActivityStarter obtain();
+
+        /**
+         * Recycles a starter for reuse.
+         */
+        void recycle(ActivityStarter starter);
     }
 
     /**
      * Default implementation of {@link StarterFactory}.
      */
     static class DefaultFactory implements Factory {
+        /**
+         * The maximum count of starters that should be active at one time:
+         * 1. last ran starter (for logging and post activity processing)
+         * 2. current running starter
+         * 3. starter from re-entry in (2)
+         */
+        private final int MAX_STARTER_COUNT = 3;
+
         private ActivityStartController mController;
         private ActivityManagerService mService;
         private ActivityStackSupervisor mSupervisor;
         private ActivityStartInterceptor mInterceptor;
 
+        private SynchronizedPool<ActivityStarter> mStarterPool =
+                new SynchronizedPool<>(MAX_STARTER_COUNT);
+
         DefaultFactory(ActivityManagerService service,
                 ActivityStackSupervisor supervisor, ActivityStartInterceptor interceptor) {
             mService = service;
@@ -234,9 +250,20 @@
         }
 
         @Override
-        public ActivityStarter obtainStarter() {
-            // TODO(b/64750076): Investigate recycling instances to reduce object creation overhead.
-            return new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
+        public ActivityStarter obtain() {
+            ActivityStarter starter = mStarterPool.acquire();
+
+            if (starter == null) {
+                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
+            }
+
+            return starter;
+        }
+
+        @Override
+        public void recycle(ActivityStarter starter) {
+            starter.reset(true /* clearRequest*/);
+            mStarterPool.release(starter);
         }
     }
 
@@ -289,6 +316,76 @@
          * {@see ActivityStarter#startActivityMayWait}.
          */
         boolean mayWait;
+
+        /**
+         * Sets values back to the initial state, clearing any held references.
+         */
+        void reset() {
+            caller = null;
+            intent = null;
+            ephemeralIntent = null;
+            resolvedType = null;
+            activityInfo = null;
+            resolveInfo = null;
+            voiceSession = null;
+            voiceInteractor = null;
+            resultTo = null;
+            resultWho = null;
+            requestCode = 0;
+            callingPid = 0;
+            callingUid = 0;
+            callingPackage = null;
+            realCallingPid = 0;
+            realCallingUid = 0;
+            startFlags = 0;
+            activityOptions = null;
+            ignoreTargetSecurity = false;
+            componentSpecified = false;
+            outActivity = null;
+            inTask = null;
+            reason = null;
+            profilerInfo = null;
+            globalConfig = null;
+            waitOptions = null;
+            userId = 0;
+            waitResult = null;
+            mayWait = false;
+        }
+
+        /**
+         * Adopts all values from passed in request.
+         */
+        void set(Request request) {
+            caller = request.caller;
+            intent = request.intent;
+            ephemeralIntent = request.ephemeralIntent;
+            resolvedType = request.resolvedType;
+            activityInfo = request.activityInfo;
+            resolveInfo = request.resolveInfo;
+            voiceSession = request.voiceSession;
+            voiceInteractor = request.voiceInteractor;
+            resultTo = request.resultTo;
+            resultWho = request.resultWho;
+            requestCode = request.requestCode;
+            callingPid = request.callingPid;
+            callingUid = request.callingUid;
+            callingPackage = request.callingPackage;
+            realCallingPid = request.realCallingPid;
+            realCallingUid = request.realCallingUid;
+            startFlags = request.startFlags;
+            activityOptions = request.activityOptions;
+            ignoreTargetSecurity = request.ignoreTargetSecurity;
+            componentSpecified = request.componentSpecified;
+            outActivity = request.outActivity;
+            inTask = request.inTask;
+            reason = request.reason;
+            profilerInfo = request.profilerInfo;
+            globalConfig = request.globalConfig;
+            waitOptions = request.waitOptions;
+            userId = request.userId;
+            waitResult = request.waitResult;
+            mayWait = request.mayWait;
+        }
     }
 
     ActivityStarter(ActivityStartController controller, ActivityManagerService service,
@@ -297,6 +394,52 @@
         mService = service;
         mSupervisor = supervisor;
         mInterceptor = interceptor;
+        reset(true);
+    }
+
+    /**
+     * Effectively duplicates the starter passed in. All state and request values will be
+     * mirrored.
+     * @param starter
+     */
+    void set(ActivityStarter starter) {
+        mStartActivity = starter.mStartActivity;
+        mIntent = starter.mIntent;
+        mCallingUid = starter.mCallingUid;
+        mOptions = starter.mOptions;
+
+        mLaunchTaskBehind = starter.mLaunchTaskBehind;
+        mLaunchFlags = starter.mLaunchFlags;
+        mLaunchMode = starter.mLaunchMode;
+
+        mLaunchBounds.set(starter.mLaunchBounds);
+
+        mNotTop = starter.mNotTop;
+        mDoResume = starter.mDoResume;
+        mStartFlags = starter.mStartFlags;
+        mSourceRecord = starter.mSourceRecord;
+        mPreferredDisplayId = starter.mPreferredDisplayId;
+
+        mInTask = starter.mInTask;
+        mAddingToTask = starter.mAddingToTask;
+        mReuseTask = starter.mReuseTask;
+
+        mNewTaskInfo = starter.mNewTaskInfo;
+        mNewTaskIntent = starter.mNewTaskIntent;
+        mSourceStack = starter.mSourceStack;
+
+        mTargetStack = starter.mTargetStack;
+        mMovedToFront = starter.mMovedToFront;
+        mNoAnimation = starter.mNoAnimation;
+        mKeepCurTransition = starter.mKeepCurTransition;
+        mAvoidMoveToFront = starter.mAvoidMoveToFront;
+
+        mVoiceSession = starter.mVoiceSession;
+        mVoiceInteractor = starter.mVoiceInteractor;
+
+        mIntentDelivered = starter.mIntentDelivered;
+
+        mRequest.set(starter.mRequest);
     }
 
     ActivityRecord getStartActivity() {
@@ -314,25 +457,47 @@
      * @return The starter result.
      */
     int execute() {
-        // TODO(b/64750076): Look into passing request directly to these methods to allow
-        // for transactional diffs and preprocessing.
-        if (mRequest.mayWait) {
-            return startActivityMayWait(mRequest.caller, mRequest.callingUid,
-                    mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
-                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
-                    mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
-                    mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
-                    mRequest.waitOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
-                    mRequest.inTask, mRequest.reason);
-        } else {
-            return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
-                    mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
-                    mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
-                    mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
-                    mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
-                    mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
-                    mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
-                    mRequest.outActivity, mRequest.inTask, mRequest.reason);
+        try {
+            // TODO(b/64750076): Look into passing request directly to these methods to allow
+            // for transactional diffs and preprocessing.
+            if (mRequest.mayWait) {
+                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
+                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
+                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
+                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
+                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
+                        mRequest.waitOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
+                        mRequest.inTask, mRequest.reason);
+            } else {
+                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
+                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
+                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
+                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
+                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
+                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
+                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
+                        mRequest.outActivity, mRequest.inTask, mRequest.reason);
+            }
+        } finally {
+            onExecutionComplete();
+        }
+    }
+
+    /**
+     * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
+     * Note that this method is called internally as well as part of {@link #startActivity}.
+     *
+     * @return The start result.
+     */
+    int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
+            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
+            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+            ActivityRecord[] outActivity) {
+        try {
+            return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
+                    doResume, options, inTask, outActivity);
+        } finally {
+            onExecutionComplete();
         }
     }
 
@@ -370,6 +535,14 @@
         return result != START_ABORTED ? result : START_SUCCESS;
     }
 
+    /**
+     * Called when execution is complete. Sets state indicating completion and proceeds with
+     * recycling if appropriate.
+     */
+    private void onExecutionComplete() {
+        mController.onExecutionComplete(this);
+    }
+
     private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
             String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
@@ -652,7 +825,7 @@
 
         mController.doPendingActivityLaunches(false);
 
-        return startResolvedActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
+        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                 true /* doResume */, options, inTask, outActivity);
     }
 
@@ -925,16 +1098,10 @@
         }
     }
 
-    /**
-     * Starts an activity based on the provided {@link ActivityRecord} and environment parameters.
-     * Note that this method is called internally as well as part of {@link #startActivity}.
-     *
-     * @return The start result.
-     */
-    int startResolvedActivity(final ActivityRecord r, ActivityRecord sourceRecord,
-        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
-        ActivityRecord[] outActivity) {
+    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
+                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
+                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
+                ActivityRecord[] outActivity) {
         int result = START_CANCELED;
         try {
             mService.mWindowManager.deferSurfaceLayout();
@@ -1190,9 +1357,57 @@
         return START_SUCCESS;
     }
 
+    /**
+     * Resets the {@link ActivityStarter} state.
+     * @param clearRequest whether the request should be reset to default values.
+     */
+    void reset(boolean clearRequest) {
+        mStartActivity = null;
+        mIntent = null;
+        mCallingUid = -1;
+        mOptions = null;
+
+        mLaunchTaskBehind = false;
+        mLaunchFlags = 0;
+        mLaunchMode = INVALID_LAUNCH_MODE;
+
+        mLaunchBounds.setEmpty();
+
+        mNotTop = null;
+        mDoResume = false;
+        mStartFlags = 0;
+        mSourceRecord = null;
+        mPreferredDisplayId = INVALID_DISPLAY;
+
+        mInTask = null;
+        mAddingToTask = false;
+        mReuseTask = null;
+
+        mNewTaskInfo = null;
+        mNewTaskIntent = null;
+        mSourceStack = null;
+
+        mTargetStack = null;
+        mMovedToFront = false;
+        mNoAnimation = false;
+        mKeepCurTransition = false;
+        mAvoidMoveToFront = false;
+
+        mVoiceSession = null;
+        mVoiceInteractor = null;
+
+        mIntentDelivered = false;
+
+        if (clearRequest) {
+            mRequest.reset();
+        }
+    }
+
     private void setInitialState(ActivityRecord r, ActivityOptions options, TaskRecord inTask,
             boolean doResume, int startFlags, ActivityRecord sourceRecord,
             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
+        reset(false /* clearRequest */);
+
         mStartActivity = r;
         mIntent = r.intent;
         mOptions = options;
diff --git a/services/core/jni/com_android_server_GraphicsStatsService.cpp b/services/core/jni/com_android_server_GraphicsStatsService.cpp
index 8385020..44e27a5 100644
--- a/services/core/jni/com_android_server_GraphicsStatsService.cpp
+++ b/services/core/jni/com_android_server_GraphicsStatsService.cpp
@@ -41,14 +41,11 @@
 static void addToDump(JNIEnv* env, jobject, jlong dumpPtr, jstring jpath, jstring jpackage,
         jint versionCode, jlong startTime, jlong endTime, jbyteArray jdata) {
     std::string path;
-    const ProfileData* data = nullptr;
     LOG_ALWAYS_FATAL_IF(jdata == nullptr && jpath == nullptr, "Path and data can't both be null");
-    ScopedByteArrayRO buffer{env};
-    if (jdata != nullptr) {
-        buffer.reset(jdata);
+    ScopedNullableByteArrayRO buffer(env, jdata);
+    if (buffer.size() != -1) {
         LOG_ALWAYS_FATAL_IF(buffer.size() != sizeof(ProfileData),
-                "Buffer size %zu doesn't match expected %zu!", buffer.size(), sizeof(ProfileData));
-        data = reinterpret_cast<const ProfileData*>(buffer.get());
+                "Buffer size %zd doesn't match expected %zu!", buffer.size(), sizeof(ProfileData));
     }
     if (jpath != nullptr) {
         ScopedUtfChars pathChars(env, jpath);
@@ -61,7 +58,8 @@
     LOG_ALWAYS_FATAL_IF(!dump, "null passed for dump pointer");
 
     const std::string package(packageChars.c_str(), packageChars.size());
-    GraphicsStatsService::addToDump(dump, path, package, versionCode, startTime, endTime, data);
+    GraphicsStatsService::addToDump(dump, path, package, versionCode, startTime, endTime,
+                                    reinterpret_cast<const ProfileData*>(buffer.get()));
 }
 
 static void addFileToDump(JNIEnv* env, jobject, jlong dumpPtr, jstring jpath) {
@@ -108,4 +106,4 @@
                                     sMethods, NELEM(sMethods));
 }
 
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index 7160d7f..a44f5c4 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
+import android.content.Intent;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
@@ -61,14 +62,13 @@
         mController = new ActivityStartController(mService, mService.mStackSupervisor, mFactory);
         mStarter = spy(new ActivityStarter(mController, mService, mService.mStackSupervisor,
                 mock(ActivityStartInterceptor.class)));
-        doReturn(mStarter).when(mFactory).obtainStarter();
+        doReturn(mStarter).when(mFactory).obtain();
     }
 
     /**
      * Ensures that pending launches are processed.
      */
     @Test
-    @Presubmit
     public void testPendingActivityLaunches() {
         final Random random = new Random();
 
@@ -88,4 +88,20 @@
         verify(mStarter, times(1)).startResolvedActivity(eq(activity), eq(source), eq(null),
                 eq(null), eq(startFlags), eq(resume), eq(null), eq(null), eq(null));
     }
+
+
+    /**
+     * Ensures instances are recycled after execution.
+     */
+    @Test
+    public void testRecycling() throws Exception {
+        final Intent intent = new Intent();
+        final ActivityStarter optionStarter = new ActivityStarter(mController, mService,
+                mService.mStackSupervisor, mock(ActivityStartInterceptor.class));
+        optionStarter
+                .setIntent(intent)
+                .setReason("Test")
+                .execute();
+        verify(mFactory, times(1)).recycle(eq(optionStarter));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index e8194dd..589a89b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -63,6 +63,7 @@
 import static android.app.ActivityManager.START_INTENT_NOT_RESOLVED;
 
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.am.ActivityStarter.Factory;
 
 /**
  * Tests for the {@link ActivityStarter} class.
diff --git a/tests/BrowserPowerTest/Android.mk b/tests/BrowserPowerTest/Android.mk
index 59bc729..5765575 100644
--- a/tests/BrowserPowerTest/Android.mk
+++ b/tests/BrowserPowerTest/Android.mk
@@ -18,8 +18,8 @@
 # We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/CanvasCompare/Android.mk b/tests/CanvasCompare/Android.mk
index 90de503..b071ec4 100644
--- a/tests/CanvasCompare/Android.mk
+++ b/tests/CanvasCompare/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 include $(BUILD_PACKAGE)
diff --git a/tests/CoreTests/android/Android.mk b/tests/CoreTests/android/Android.mk
index c9f1161..56d7918 100644
--- a/tests/CoreTests/android/Android.mk
+++ b/tests/CoreTests/android/Android.mk
@@ -6,8 +6,14 @@
 LOCAL_SRC_FILES := \
 	$(call all-subdir-java-files)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt org.apache.http.legacy
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := \
+    android.test.runner \
+    bouncycastle \
+    conscrypt \
+    org.apache.http.legacy \
+    android.test.base \
+
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_PACKAGE_NAME := CoreTests
 
diff --git a/tests/DataIdleTest/Android.mk b/tests/DataIdleTest/Android.mk
index 4e15729..85f7edf 100644
--- a/tests/DataIdleTest/Android.mk
+++ b/tests/DataIdleTest/Android.mk
@@ -20,8 +20,8 @@
 LOCAL_MODULE_TAGS := tests
 
 LOCAL_PACKAGE_NAME := DataIdleTest
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # We need to sign it to get access to the network usage history.
diff --git a/tests/FrameworkPerf/Android.mk b/tests/FrameworkPerf/Android.mk
index d2ec753..1873cc1 100644
--- a/tests/FrameworkPerf/Android.mk
+++ b/tests/FrameworkPerf/Android.mk
@@ -7,8 +7,8 @@
 
 LOCAL_PACKAGE_NAME := FrameworkPerf
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_AAPT_FLAGS = -c 120dpi,240dpi,160dpi,161dpi,320dpi,nodpi
 
diff --git a/tests/HierarchyViewerTest/Android.mk b/tests/HierarchyViewerTest/Android.mk
index f8c8656..8550d70 100644
--- a/tests/HierarchyViewerTest/Android.mk
+++ b/tests/HierarchyViewerTest/Android.mk
@@ -7,7 +7,7 @@
 
 LOCAL_PACKAGE_NAME := HierarchyViewerTest
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 include $(BUILD_PACKAGE)
diff --git a/tests/ImfTest/tests/Android.mk b/tests/ImfTest/tests/Android.mk
index 6042471..a0df959 100644
--- a/tests/ImfTest/tests/Android.mk
+++ b/tests/ImfTest/tests/Android.mk
@@ -7,8 +7,8 @@
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 LOCAL_PACKAGE_NAME := ImfTestTests
 
diff --git a/tests/Internal/Android.mk b/tests/Internal/Android.mk
index fc001e9..73181ec 100644
--- a/tests/Internal/Android.mk
+++ b/tests/Internal/Android.mk
@@ -11,7 +11,6 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 LOCAL_STATIC_JAVA_LIBRARIES := junit \
-    legacy-android-test \
     android-support-test \
     mockito-target-minus-junit4
 
diff --git a/tests/MemoryUsage/Android.mk b/tests/MemoryUsage/Android.mk
index 578e628..e186e9f 100644
--- a/tests/MemoryUsage/Android.mk
+++ b/tests/MemoryUsage/Android.mk
@@ -9,8 +9,8 @@
 LOCAL_PACKAGE_NAME := MemoryUsage
 
 LOCAL_CERTIFICATE := platform
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 include $(BUILD_PACKAGE)
 
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
index dd9ff11..6fb6025 100644
--- a/tests/NetworkSecurityConfigTest/Android.mk
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -5,8 +5,13 @@
 LOCAL_MODULE_TAGS := tests
 LOCAL_CERTIFICATE := platform
 
-LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle conscrypt
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := \
+    android.test.runner \
+    bouncycastle \
+    conscrypt \
+    android.test.base \
+
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/SoundTriggerTests/Android.mk b/tests/SoundTriggerTests/Android.mk
index 359484e..030d5f4 100644
--- a/tests/SoundTriggerTests/Android.mk
+++ b/tests/SoundTriggerTests/Android.mk
@@ -27,8 +27,8 @@
   LOCAL_SRC_FILES := src/android/hardware/soundtrigger/SoundTriggerTest.java
 endif
 
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target legacy-android-test
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := SoundTriggerTests
 
diff --git a/tests/SurfaceComposition/Android.mk b/tests/SurfaceComposition/Android.mk
index d97c3f4..1962791 100644
--- a/tests/SurfaceComposition/Android.mk
+++ b/tests/SurfaceComposition/Android.mk
@@ -27,7 +27,9 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_STATIC_JAVA_LIBRARIES := legacy-android-test junit
+LOCAL_STATIC_JAVA_LIBRARIES := junit
+
+LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
 
 LOCAL_PACKAGE_NAME := SurfaceComposition
 
diff --git a/tests/TtsTests/Android.mk b/tests/TtsTests/Android.mk
index 3c3cd77..2fa1950 100644
--- a/tests/TtsTests/Android.mk
+++ b/tests/TtsTests/Android.mk
@@ -20,8 +20,8 @@
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target legacy-android-test
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
 
 LOCAL_PACKAGE_NAME := TtsTests
 
diff --git a/tests/WindowAnimationJank/Android.mk b/tests/WindowAnimationJank/Android.mk
index f356afb..8aac8a1 100644
--- a/tests/WindowAnimationJank/Android.mk
+++ b/tests/WindowAnimationJank/Android.mk
@@ -27,7 +27,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     ub-uiautomator \
     ub-janktesthelper \
-    legacy-android-test \
     junit
 
 LOCAL_SDK_VERSION := current
diff --git a/tests/permission/Android.mk b/tests/permission/Android.mk
index 54688c8..7f81d9a3 100644
--- a/tests/permission/Android.mk
+++ b/tests/permission/Android.mk
@@ -7,8 +7,8 @@
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit
 LOCAL_PACKAGE_NAME := FrameworkPermissionTests
 
 include $(BUILD_PACKAGE)
diff --git a/tests/testables/tests/Android.mk b/tests/testables/tests/Android.mk
index 16fe535..6e20d797 100644
--- a/tests/testables/tests/Android.mk
+++ b/tests/testables/tests/Android.mk
@@ -28,10 +28,9 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-test \
     mockito-target-minus-junit4 \
-    legacy-android-test \
 	testables
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base android.test.mock
 
 LOCAL_CERTIFICATE := platform