diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 9b290c6..2fd2e33 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -12,6 +12,8 @@
                services/incremental/
 
 [Hook Scripts]
+checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
+
 strings_lint_hook = ${REPO_ROOT}/frameworks/base/tools/stringslint/stringslint_sha.sh ${PREUPLOAD_COMMIT}
 
 hidden_api_txt_checksorted_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
index 2312635..42725c5 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobScheduler.java
@@ -59,9 +59,9 @@
  *
  * <p class="caution"><strong>Note:</strong> Beginning with API 30
  * ({@link android.os.Build.VERSION_CODES#R}), JobScheduler will throttle runaway applications.
- * Calling {@link #schedule(JobInfo)} and other such methods with very high frequency is indicative
- * of an app bug and so, to make sure the system doesn't get overwhelmed, JobScheduler will begin
- * to throttle apps that show buggy behavior, regardless of target SDK version.
+ * Calling {@link #schedule(JobInfo)} and other such methods with very high frequency can have a
+ * high cost and so, to make sure the system doesn't get overwhelmed, JobScheduler will begin
+ * to throttle apps, regardless of target SDK version.
  */
 @SystemService(Context.JOB_SCHEDULER_SERVICE)
 public abstract class JobScheduler {
@@ -74,9 +74,16 @@
     public @interface Result {}
 
     /**
-     * Returned from {@link #schedule(JobInfo)} when an invalid parameter was supplied. This can occur
-     * if the run-time for your job is too short, or perhaps the system can't resolve the
-     * requisite {@link JobService} in your package.
+     * Returned from {@link #schedule(JobInfo)} if a job wasn't scheduled successfully. Scheduling
+     * can fail for a variety of reasons, including, but not limited to:
+     * <ul>
+     * <li>an invalid parameter was supplied (eg. the run-time for your job is too short, or the
+     * system can't resolve the requisite {@link JobService} in your package)</li>
+     * <li>the app has too many jobs scheduled</li>
+     * <li>the app has tried to schedule too many jobs in a short amount of time</li>
+     * </ul>
+     * Attempting to schedule the job again immediately after receiving this result will not
+     * guarantee a successful schedule.
      */
     public static final int RESULT_FAILURE = 0;
     /**
@@ -89,6 +96,11 @@
      * ID with the new information in the {@link JobInfo}.  If a job with the given ID is currently
      * running, it will be stopped.
      *
+     * <p class="caution"><strong>Note:</strong> Scheduling a job can have a high cost, even if it's
+     * rescheduling the same job and the job didn't execute, especially on platform versions before
+     * version {@link android.os.Build.VERSION_CODES#Q}. As such, the system may throttle calls to
+     * this API if calls are made too frequently in a short amount of time.
+     *
      * @param job The job you wish scheduled. See
      * {@link android.app.job.JobInfo.Builder JobInfo.Builder} for more detail on the sorts of jobs
      * you can schedule.
diff --git a/apex/jobscheduler/service/Android.bp b/apex/jobscheduler/service/Android.bp
index 47267df..8aa88c2 100644
--- a/apex/jobscheduler/service/Android.bp
+++ b/apex/jobscheduler/service/Android.bp
@@ -19,4 +19,8 @@
 
     // Rename classes shared with the framework
     jarjar_rules: "jarjar-rules.txt",
+
+    required: [
+        "libalarm_jni",
+    ],
 }
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 3e43dcb..5ca3b33 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -3831,6 +3831,7 @@
         }
 
         void init() {
+            System.loadLibrary("alarm_jni");
             mNativeData = AlarmManagerService.init();
         }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index ec9bdad..68b22c0 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -254,6 +254,18 @@
 
     private final CountQuotaTracker mQuotaTracker;
     private static final String QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG = ".schedulePersisted()";
+    private static final String QUOTA_TRACKER_SCHEDULE_LOGGED =
+            ".schedulePersisted out-of-quota logged";
+    private static final Category QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED = new Category(
+            ".schedulePersisted()");
+    private static final Category QUOTA_TRACKER_CATEGORY_SCHEDULE_LOGGED = new Category(
+            ".schedulePersisted out-of-quota logged");
+    private static final Categorizer QUOTA_CATEGORIZER = (userId, packageName, tag) -> {
+        if (QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG.equals(tag)) {
+            return QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED;
+        }
+        return QUOTA_TRACKER_CATEGORY_SCHEDULE_LOGGED;
+    };
 
     /**
      * Queue of pending jobs. The JobServiceContext class will receive jobs from this list
@@ -270,6 +282,7 @@
     ActivityManagerInternal mActivityManagerInternal;
     IBatteryStats mBatteryStats;
     DeviceIdleInternal mLocalDeviceIdleController;
+    @VisibleForTesting
     AppStateTracker mAppStateTracker;
     final UsageStatsManagerInternal mUsageStats;
     private final AppStandbyInternal mAppStandbyInternal;
@@ -342,10 +355,7 @@
                         final StateController sc = mControllers.get(controller);
                         sc.onConstantsUpdatedLocked();
                     }
-                    mQuotaTracker.setEnabled(mConstants.ENABLE_API_QUOTAS);
-                    mQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY,
-                            mConstants.API_QUOTA_SCHEDULE_COUNT,
-                            mConstants.API_QUOTA_SCHEDULE_WINDOW_MS);
+                    updateQuotaTracker();
                 } catch (IllegalArgumentException e) {
                     // Failed to parse the settings string, log this and move on
                     // with defaults.
@@ -355,6 +365,14 @@
         }
     }
 
+    @VisibleForTesting
+    void updateQuotaTracker() {
+        mQuotaTracker.setEnabled(mConstants.ENABLE_API_QUOTAS);
+        mQuotaTracker.setCountLimit(QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED,
+                mConstants.API_QUOTA_SCHEDULE_COUNT,
+                mConstants.API_QUOTA_SCHEDULE_WINDOW_MS);
+    }
+
     static class MaxJobCounts {
         private final KeyValueListParser.IntValue mTotal;
         private final KeyValueListParser.IntValue mMaxBg;
@@ -507,6 +525,8 @@
         private static final String KEY_API_QUOTA_SCHEDULE_WINDOW_MS = "aq_schedule_window_ms";
         private static final String KEY_API_QUOTA_SCHEDULE_THROW_EXCEPTION =
                 "aq_schedule_throw_exception";
+        private static final String KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT =
+                "aq_schedule_return_failure";
 
         private static final int DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT = 5;
         private static final long DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = 31 * MINUTE_IN_MILLIS;
@@ -520,6 +540,7 @@
         private static final int DEFAULT_API_QUOTA_SCHEDULE_COUNT = 250;
         private static final long DEFAULT_API_QUOTA_SCHEDULE_WINDOW_MS = MINUTE_IN_MILLIS;
         private static final boolean DEFAULT_API_QUOTA_SCHEDULE_THROW_EXCEPTION = true;
+        private static final boolean DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false;
 
         /**
          * Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
@@ -623,6 +644,11 @@
          */
         public boolean API_QUOTA_SCHEDULE_THROW_EXCEPTION =
                 DEFAULT_API_QUOTA_SCHEDULE_THROW_EXCEPTION;
+        /**
+         * Whether or not to return a failure result when an app hits its schedule quota limit.
+         */
+        public boolean API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT =
+                DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT;
 
         private final KeyValueListParser mParser = new KeyValueListParser(',');
 
@@ -678,6 +704,9 @@
             API_QUOTA_SCHEDULE_THROW_EXCEPTION = mParser.getBoolean(
                     KEY_API_QUOTA_SCHEDULE_THROW_EXCEPTION,
                     DEFAULT_API_QUOTA_SCHEDULE_THROW_EXCEPTION);
+            API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = mParser.getBoolean(
+                    KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT,
+                    DEFAULT_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT);
         }
 
         void dump(IndentingPrintWriter pw) {
@@ -712,6 +741,8 @@
             pw.print(KEY_API_QUOTA_SCHEDULE_WINDOW_MS, API_QUOTA_SCHEDULE_WINDOW_MS).println();
             pw.print(KEY_API_QUOTA_SCHEDULE_THROW_EXCEPTION,
                     API_QUOTA_SCHEDULE_THROW_EXCEPTION).println();
+            pw.print(KEY_API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT,
+                    API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT).println();
 
             pw.decreaseIndent();
         }
@@ -740,6 +771,8 @@
             proto.write(ConstantsProto.API_QUOTA_SCHEDULE_WINDOW_MS, API_QUOTA_SCHEDULE_WINDOW_MS);
             proto.write(ConstantsProto.API_QUOTA_SCHEDULE_THROW_EXCEPTION,
                     API_QUOTA_SCHEDULE_THROW_EXCEPTION);
+            proto.write(ConstantsProto.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT,
+                    API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT);
         }
     }
 
@@ -973,12 +1006,17 @@
 
     public int scheduleAsPackage(JobInfo job, JobWorkItem work, int uId, String packageName,
             int userId, String tag) {
-        if (job.isPersisted()) {
-            // Only limit schedule calls for persisted jobs.
+        final String servicePkg = job.getService().getPackageName();
+        if (job.isPersisted() && (packageName == null || packageName.equals(servicePkg))) {
+            // Only limit schedule calls for persisted jobs scheduled by the app itself.
             final String pkg =
                     packageName == null ? job.getService().getPackageName() : packageName;
             if (!mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG)) {
-                Slog.e(TAG, userId + "-" + pkg + " has called schedule() too many times");
+                if (mQuotaTracker.isWithinQuota(userId, pkg, QUOTA_TRACKER_SCHEDULE_LOGGED)) {
+                    // Don't log too frequently
+                    Slog.wtf(TAG, userId + "-" + pkg + " has called schedule() too many times");
+                    mQuotaTracker.noteEvent(userId, pkg, QUOTA_TRACKER_SCHEDULE_LOGGED);
+                }
                 mAppStandbyInternal.restrictApp(
                         pkg, userId, UsageStatsManager.REASON_SUB_FORCED_SYSTEM_FLAG_BUGGY);
                 if (mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION) {
@@ -1004,13 +1042,17 @@
                         // Only throw the exception for debuggable apps.
                         throw new LimitExceededException(
                                 "schedule()/enqueue() called more than "
-                                        + mQuotaTracker.getLimit(Category.SINGLE_CATEGORY)
+                                        + mQuotaTracker.getLimit(
+                                        QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED)
                                         + " times in the past "
-                                        + mQuotaTracker.getWindowSizeMs(Category.SINGLE_CATEGORY)
-                                        + "ms");
+                                        + mQuotaTracker.getWindowSizeMs(
+                                        QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED)
+                                        + "ms. See the documentation for more information.");
                     }
                 }
-                return JobScheduler.RESULT_FAILURE;
+                if (mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT) {
+                    return JobScheduler.RESULT_FAILURE;
+                }
             }
             mQuotaTracker.noteEvent(userId, pkg, QUOTA_TRACKER_SCHEDULE_PERSISTED_TAG);
         }
@@ -1371,10 +1413,12 @@
         // Set up the app standby bucketing tracker
         mStandbyTracker = new StandbyTracker();
         mUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
-        mQuotaTracker = new CountQuotaTracker(context, Categorizer.SINGLE_CATEGORIZER);
-        mQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY,
+        mQuotaTracker = new CountQuotaTracker(context, QUOTA_CATEGORIZER);
+        mQuotaTracker.setCountLimit(QUOTA_TRACKER_CATEGORY_SCHEDULE_PERSISTED,
                 mConstants.API_QUOTA_SCHEDULE_COUNT,
                 mConstants.API_QUOTA_SCHEDULE_WINDOW_MS);
+        // Log at most once per minute.
+        mQuotaTracker.setCountLimit(QUOTA_TRACKER_CATEGORY_SCHEDULE_LOGGED, 1, 60_000);
 
         mAppStandbyInternal = LocalServices.getService(AppStandbyInternal.class);
         mAppStandbyInternal.addListener(mStandbyTracker);
diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp
new file mode 100644
index 0000000..c502867
--- /dev/null
+++ b/apex/jobscheduler/service/jni/Android.bp
@@ -0,0 +1,41 @@
+cc_library_shared {
+    name: "libalarm_jni",
+
+    cpp_std: "c++2a",
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wno-unused-parameter",
+        "-Wthread-safety",
+    ],
+
+    srcs: [
+        "com_android_server_alarm_AlarmManagerService.cpp",
+        "onload.cpp",
+    ],
+
+    shared_libs: [
+         "libnativehelper",
+         "liblog",
+         "libbase",
+    ],
+
+    product_variables: {
+        arc: {
+            exclude_srcs: [
+                "com_android_server_alarm_AlarmManagerService.cpp",
+            ],
+            srcs: [
+                ":arctimersrcs",
+            ],
+        }
+    }
+
+}
+
+filegroup {
+    name: "lib_alarmManagerService_native",
+    srcs: [
+        "com_android_server_alarm_AlarmManagerService.cpp",
+    ],
+}
diff --git a/services/core/jni/com_android_server_alarm_AlarmManagerService.cpp b/apex/jobscheduler/service/jni/com_android_server_alarm_AlarmManagerService.cpp
similarity index 100%
rename from services/core/jni/com_android_server_alarm_AlarmManagerService.cpp
rename to apex/jobscheduler/service/jni/com_android_server_alarm_AlarmManagerService.cpp
diff --git a/apex/jobscheduler/service/jni/onload.cpp b/apex/jobscheduler/service/jni/onload.cpp
new file mode 100644
index 0000000..f40413f
--- /dev/null
+++ b/apex/jobscheduler/service/jni/onload.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <nativehelper/JNIHelp.h>
+#include "jni.h"
+#include "utils/Log.h"
+#include "utils/misc.h"
+
+namespace android {
+int register_android_server_alarm_AlarmManagerService(JNIEnv* env);
+};
+
+using namespace android;
+
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
+{
+    JNIEnv* env = NULL;
+    jint result = -1;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+        ALOGE("GetEnv failed!");
+        return result;
+    }
+    ALOG_ASSERT(env, "Could not retrieve the env!");
+
+    register_android_server_alarm_AlarmManagerService(env);
+    return JNI_VERSION_1_4;
+}
diff --git a/api/current.txt b/api/current.txt
index c754f10..651cda5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47044,7 +47044,7 @@
   public abstract class CellLocation {
     ctor public CellLocation();
     method public static android.telephony.CellLocation getEmpty();
-    method public static void requestLocationUpdate();
+    method @Deprecated public static void requestLocationUpdate();
   }
 
   public abstract class CellSignalStrength {
@@ -49106,6 +49106,7 @@
   }
 
   public static class MmTelFeature.MmTelCapabilities {
+    method public final boolean isCapable(int);
     field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
     field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
     field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
diff --git a/api/system-current.txt b/api/system-current.txt
index 6a044508..fa45430 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12250,7 +12250,6 @@
     ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
-    method public final boolean isCapable(int);
     method public final void removeCapabilities(int);
   }
 
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 09544c1..3acc225 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -180,11 +180,6 @@
 
 package android.telephony {
 
-  public final class PreciseDataConnectionState implements android.os.Parcelable {
-    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
-    method @Deprecated public int getDataConnectionNetworkType();
-  }
-
   public class TelephonyManager {
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall();
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall();
diff --git a/api/test-current.txt b/api/test-current.txt
index ab07613..dc66265 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4697,7 +4697,6 @@
     ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
-    method public final boolean isCapable(int);
     method public final void removeCapabilities(int);
   }
 
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index 3449010..ab2f42b 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -18839,7 +18839,6 @@
 HSPLandroid/telephony/PreciseDataConnectionState;-><init>(Landroid/os/Parcel;Landroid/telephony/PreciseDataConnectionState$1;)V
 HPLandroid/telephony/PreciseDataConnectionState;->equals(Ljava/lang/Object;)Z
 HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionApn()Ljava/lang/String;
-HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionLinkProperties()Landroid/net/LinkProperties;
 HPLandroid/telephony/PreciseDataConnectionState;->getNetworkType()I
 HPLandroid/telephony/PreciseDataConnectionState;->getState()I
 HSPLandroid/telephony/PreciseDataConnectionState;->toString()Ljava/lang/String;
@@ -42425,10 +42424,6 @@
 Landroid/hardware/camera2/impl/CameraMetadataNative;
 Landroid/hardware/camera2/impl/GetCommand;
 Landroid/hardware/camera2/impl/SetCommand;
-Landroid/hardware/camera2/legacy/LegacyCameraDevice;
-Landroid/hardware/camera2/legacy/LegacyExceptionUtils$BufferQueueAbandonedException;
-Landroid/hardware/camera2/legacy/LegacyMetadataMapper;
-Landroid/hardware/camera2/legacy/PerfMeasurement;
 Landroid/hardware/camera2/marshal/MarshalHelpers;
 Landroid/hardware/camera2/marshal/MarshalQueryable;
 Landroid/hardware/camera2/marshal/MarshalRegistry$MarshalToken;
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 0bff3aa..881cfa3 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2297,10 +2297,6 @@
 android.hardware.camera2.impl.CameraMetadataNative
 android.hardware.camera2.impl.GetCommand
 android.hardware.camera2.impl.SetCommand
-android.hardware.camera2.legacy.LegacyCameraDevice
-android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException
-android.hardware.camera2.legacy.LegacyMetadataMapper
-android.hardware.camera2.legacy.PerfMeasurement
 android.hardware.camera2.marshal.MarshalHelpers
 android.hardware.camera2.marshal.MarshalQueryable
 android.hardware.camera2.marshal.MarshalRegistry$MarshalToken
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index c498e92..d642f21 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -7542,6 +7542,7 @@
      *
      * @hide
      */
+    @SuppressWarnings("AndroidFrameworkClientSidePermissionCheck")
     public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
             @Nullable String proxiedAttributionTag, @Nullable String message) {
         int myUid = Process.myUid();
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 3bc043e..b1a62bf 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -16,6 +16,7 @@
 
 package android.app.backup;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -34,6 +35,8 @@
 import android.util.Log;
 import android.util.Pair;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -195,6 +198,19 @@
     @SystemApi
     public static final int ERROR_TRANSPORT_INVALID = -2;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        OperationType.BACKUP,
+        OperationType.MIGRATION
+    })
+    public @interface OperationType {
+        // A regular backup / restore operation.
+        int BACKUP = 0;
+        // A full migration: all app data for non-system apps is eligible.
+        int MIGRATION = 1;
+    }
+
     private Context mContext;
     @UnsupportedAppUsage
     private static IBackupManager sService;
@@ -736,7 +752,7 @@
     @SystemApi
     @RequiresPermission(android.Manifest.permission.BACKUP)
     public int requestBackup(String[] packages, BackupObserver observer) {
-        return requestBackup(packages, observer, null, 0);
+        return requestBackup(packages, observer, null, 0, OperationType.BACKUP);
     }
 
     /**
@@ -761,6 +777,31 @@
     @RequiresPermission(android.Manifest.permission.BACKUP)
     public int requestBackup(String[] packages, BackupObserver observer,
             BackupManagerMonitor monitor, int flags) {
+        return requestBackup(packages, observer, monitor, flags, OperationType.BACKUP);
+    }
+
+    /**
+     * Request an immediate backup, providing an observer to which results of the backup operation
+     * will be published. The Android backup system will decide for each package whether it will
+     * be full app data backup or key/value-pair-based backup.
+     *
+     * <p>If this method returns {@link BackupManager#SUCCESS}, the OS will attempt to backup all
+     * provided packages using the remote transport.
+     *
+     * @param packages List of package names to backup.
+     * @param observer The {@link BackupObserver} to receive callbacks during the backup
+     *                 operation. Could be {@code null}.
+     * @param monitor  The {@link BackupManagerMonitorWrapper} to receive callbacks of important
+     *                 events during the backup operation. Could be {@code null}.
+     * @param flags    {@link #FLAG_NON_INCREMENTAL_BACKUP}.
+     * @param operationType {@link OperationType}
+     * @return {@link BackupManager#SUCCESS} on success; nonzero on error.
+     * @throws IllegalArgumentException on null or empty {@code packages} param.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.BACKUP)
+    public int requestBackup(String[] packages, BackupObserver observer,
+            BackupManagerMonitor monitor, int flags, @OperationType int operationType) {
         checkServiceBinder();
         if (sService != null) {
             try {
@@ -770,7 +811,8 @@
                 BackupManagerMonitorWrapper monitorWrapper = monitor == null
                         ? null
                         : new BackupManagerMonitorWrapper(monitor);
-                return sService.requestBackup(packages, observerWrapper, monitorWrapper, flags);
+                return sService.requestBackup(packages, observerWrapper, monitorWrapper, flags,
+                        operationType);
             } catch (RemoteException e) {
                 Log.e(TAG, "requestBackup() couldn't connect");
             }
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index 4940976..96b5dd5 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -678,7 +678,7 @@
      * {@link android.app.backup.IBackupManager.requestBackupForUser} for the calling user id.
      */
     int requestBackup(in String[] packages, IBackupObserver observer, IBackupManagerMonitor monitor,
-        int flags);
+        int flags, int operationType);
 
     /**
      * Cancel all running backups. After this call returns, no currently running backups will
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f533760..9c7dc96 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8179,7 +8179,7 @@
     private static final PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>
             sPackageInfoCache =
             new PropertyInvalidatedCache<PackageInfoQuery, PackageInfo>(
-                    16, PermissionManager.CACHE_KEY_PACKAGE_INFO) {
+                    32, PermissionManager.CACHE_KEY_PACKAGE_INFO) {
                 @Override
                 protected PackageInfo recompute(PackageInfoQuery query) {
                     return getPackageInfoAsUserUncached(
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 25279b3..2159905 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -249,14 +249,10 @@
     public static final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
 
     /**
-     * A constant meaning the normal camera connect/open will be used.
+     * Camera HAL device API version 3.0
+     * @hide
      */
-    private static final int CAMERA_HAL_API_VERSION_NORMAL_CONNECT = -2;
-
-    /**
-     * Used to indicate HAL version un-specified.
-     */
-    private static final int CAMERA_HAL_API_VERSION_UNSPECIFIED = -1;
+    public static final int CAMERA_HAL_API_VERSION_3_0 = 0x300;
 
     /**
      * Hardware face detection. It does not use much CPU.
@@ -427,7 +423,7 @@
      * Creates a new Camera object to access a particular hardware camera with
      * given hal API version. If the same camera is opened by other applications
      * or the hal API version is not supported by this device, this will throw a
-     * RuntimeException.
+     * RuntimeException. As of Android 12, HAL version 1 is no longer supported.
      * <p>
      * You must call {@link #release()} when you are done using the camera,
      * otherwise it will remain locked and be unavailable to other applications.
@@ -463,49 +459,14 @@
      */
     @UnsupportedAppUsage
     public static Camera openLegacy(int cameraId, int halVersion) {
-        if (halVersion < CAMERA_HAL_API_VERSION_1_0) {
-            throw new IllegalArgumentException("Invalid HAL version " + halVersion);
+        if (halVersion < CAMERA_HAL_API_VERSION_3_0) {
+            throw new IllegalArgumentException("Unsupported HAL version " + halVersion);
         }
 
-        return new Camera(cameraId, halVersion);
+        return new Camera(cameraId);
     }
 
-    /**
-     * Create a legacy camera object.
-     *
-     * @param cameraId The hardware camera to access, between 0 and
-     * {@link #getNumberOfCameras()}-1.
-     * @param halVersion The HAL API version this camera device to be opened as.
-     */
-    private Camera(int cameraId, int halVersion) {
-        int err = cameraInitVersion(cameraId, halVersion);
-        if (checkInitErrors(err)) {
-            if (err == -EACCES) {
-                throw new RuntimeException("Fail to connect to camera service");
-            } else if (err == -ENODEV) {
-                throw new RuntimeException("Camera initialization failed");
-            } else if (err == -ENOSYS) {
-                throw new RuntimeException("Camera initialization failed because some methods"
-                        + " are not implemented");
-            } else if (err == -EOPNOTSUPP) {
-                throw new RuntimeException("Camera initialization failed because the hal"
-                        + " version is not supported by this device");
-            } else if (err == -EINVAL) {
-                throw new RuntimeException("Camera initialization failed because the input"
-                        + " arugments are invalid");
-            } else if (err == -EBUSY) {
-                throw new RuntimeException("Camera initialization failed because the camera"
-                        + " device was already opened");
-            } else if (err == -EUSERS) {
-                throw new RuntimeException("Camera initialization failed because the max"
-                        + " number of camera devices were already opened");
-            }
-            // Should never hit this.
-            throw new RuntimeException("Unknown camera error");
-        }
-    }
-
-    private int cameraInitVersion(int cameraId, int halVersion) {
+    private int cameraInit(int cameraId) {
         mShutterCallback = null;
         mRawImageCallback = null;
         mJpegCallback = null;
@@ -523,35 +484,13 @@
             mEventHandler = null;
         }
 
-        return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
+        return native_setup(new WeakReference<Camera>(this), cameraId,
                 ActivityThread.currentOpPackageName());
     }
 
-    private int cameraInitNormal(int cameraId) {
-        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
-    }
-
-    /**
-     * Connect to the camera service using #connectLegacy
-     *
-     * <p>
-     * This acts the same as normal except that it will return
-     * the detailed error code if open fails instead of
-     * converting everything into {@code NO_INIT}.</p>
-     *
-     * <p>Intended to use by the camera2 shim only, do <i>not</i> use this for other code.</p>
-     *
-     * @return a detailed errno error code, or {@code NO_ERROR} on success
-     *
-     * @hide
-     */
-    public int cameraInitUnspecified(int cameraId) {
-        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_UNSPECIFIED);
-    }
-
     /** used by Camera#open, Camera#open(int) */
     Camera(int cameraId) {
-        int err = cameraInitNormal(cameraId);
+        int err = cameraInit(cameraId);
         if (checkInitErrors(err)) {
             if (err == -EACCES) {
                 throw new RuntimeException("Fail to connect to camera service");
@@ -616,8 +555,7 @@
     }
 
     @UnsupportedAppUsage
-    private native final int native_setup(Object camera_this, int cameraId, int halVersion,
-                                           String packageName);
+    private native int native_setup(Object cameraThis, int cameraId, String packageName);
 
     private native final void native_release();
 
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl b/core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl
index aa5ac03..754162c 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl
@@ -26,5 +26,5 @@
     /**
      * A wakelock will be held until the reciever calls back into {@param callback}
      */
-    void onLockoutReset(IRemoteCallback callback);
+    void onLockoutReset(int sensorId, IRemoteCallback callback);
 }
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 7f834af..8469f5f 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -23,14 +23,11 @@
 import android.annotation.SystemService;
 import android.annotation.TestApi;
 import android.content.Context;
-import android.hardware.CameraInfo;
 import android.hardware.CameraStatus;
 import android.hardware.ICameraService;
 import android.hardware.ICameraServiceListener;
 import android.hardware.camera2.impl.CameraDeviceImpl;
 import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.legacy.CameraDeviceUserShim;
-import android.hardware.camera2.legacy.LegacyMetadataMapper;
 import android.hardware.camera2.params.SessionConfiguration;
 import android.hardware.camera2.utils.CameraIdAndSessionConfiguration;
 import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
@@ -405,10 +402,6 @@
             throw new IllegalArgumentException("No cameras available on device");
         }
         synchronized (mLock) {
-            /*
-             * Get the camera characteristics from the camera service directly if it supports it,
-             * otherwise get them from the legacy shim instead.
-             */
             ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
             if (cameraService == null) {
                 throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
@@ -417,34 +410,18 @@
             try {
                 Size displaySize = getDisplaySize();
 
-                // First check isHiddenPhysicalCamera to avoid supportsCamera2ApiLocked throwing
-                // exception in case cameraId is a hidden physical camera.
-                if (!isHiddenPhysicalCamera(cameraId) && !supportsCamera2ApiLocked(cameraId)) {
-                    // Legacy backwards compatibility path; build static info from the camera
-                    // parameters
-                    int id = Integer.parseInt(cameraId);
-
-                    String parameters = cameraService.getLegacyParameters(id);
-
-                    CameraInfo info = cameraService.getCameraInfo(id);
-
-                    characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info,
-                            id, displaySize);
-                } else {
-                    // Normal path: Get the camera characteristics directly from the camera service
-                    CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
-                    try {
-                        info.setCameraId(Integer.parseInt(cameraId));
-                    } catch (NumberFormatException e) {
-                        // For external camera, reaching here is expected.
-                        Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
-                    }
-                    boolean hasConcurrentStreams =
-                            CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
-                    info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
-                    info.setDisplaySize(displaySize);
-                    characteristics = new CameraCharacteristics(info);
+                CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
+                try {
+                    info.setCameraId(Integer.parseInt(cameraId));
+                } catch (NumberFormatException e) {
+                    Log.v(TAG, "Failed to parse camera Id " + cameraId + " to integer");
                 }
+                boolean hasConcurrentStreams =
+                        CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId);
+                info.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
+                info.setDisplaySize(displaySize);
+                characteristics = new CameraCharacteristics(info);
+
             } catch (ServiceSpecificException e) {
                 throwAsPublicException(e);
             } catch (RemoteException e) {
@@ -500,30 +477,14 @@
             ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();
 
             try {
-                if (supportsCamera2ApiLocked(cameraId)) {
-                    // Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
-                    ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
-                    if (cameraService == null) {
-                        throw new ServiceSpecificException(
-                            ICameraService.ERROR_DISCONNECTED,
-                            "Camera service is currently unavailable");
-                    }
-                    cameraUser = cameraService.connectDevice(callbacks, cameraId,
-                            mContext.getOpPackageName(), mContext.getAttributionTag(), uid);
-                } else {
-                    // Use legacy camera implementation for HAL1 devices
-                    int id;
-                    try {
-                        id = Integer.parseInt(cameraId);
-                    } catch (NumberFormatException e) {
-                        throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "
-                                + cameraId);
-                    }
-
-                    Log.i(TAG, "Using legacy camera HAL.");
-                    cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id,
-                            getDisplaySize());
+                ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
+                if (cameraService == null) {
+                    throw new ServiceSpecificException(
+                        ICameraService.ERROR_DISCONNECTED,
+                        "Camera service is currently unavailable");
                 }
+                cameraUser = cameraService.connectDevice(callbacks, cameraId,
+                    mContext.getOpPackageName(),  mContext.getAttributionTag(), uid);
             } catch (ServiceSpecificException e) {
                 if (e.errorCode == ICameraService.ERROR_DEPRECATED_HAL) {
                     throw new AssertionError("Should've gone down the shim path");
@@ -1021,44 +982,6 @@
     }
 
     /**
-     * Queries the camera service if it supports the camera2 api directly, or needs a shim.
-     *
-     * @param cameraId a non-{@code null} camera identifier
-     * @return {@code false} if the legacy shim needs to be used, {@code true} otherwise.
-     */
-    private boolean supportsCamera2ApiLocked(String cameraId) {
-        return supportsCameraApiLocked(cameraId, API_VERSION_2);
-    }
-
-    /**
-     * Queries the camera service if it supports a camera api directly, or needs a shim.
-     *
-     * @param cameraId a non-{@code null} camera identifier
-     * @param apiVersion the version, i.e. {@code API_VERSION_1} or {@code API_VERSION_2}
-     * @return {@code true} if connecting will work for that device version.
-     */
-    private boolean supportsCameraApiLocked(String cameraId, int apiVersion) {
-        /*
-         * Possible return values:
-         * - NO_ERROR => CameraX API is supported
-         * - CAMERA_DEPRECATED_HAL => CameraX API is *not* supported (thrown as an exception)
-         * - Remote exception => If the camera service died
-         *
-         * Anything else is an unexpected error we don't want to recover from.
-         */
-        try {
-            ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
-            // If no camera service, no support
-            if (cameraService == null) return false;
-
-            return cameraService.supportsCameraApi(cameraId, apiVersion);
-        } catch (RemoteException e) {
-            // Camera service is now down, no support for any API level
-        }
-        return false;
-    }
-
-    /**
      * Queries the camera service if a cameraId is a hidden physical camera that belongs to a
      * logical camera device.
      *
diff --git a/core/java/android/hardware/camera2/legacy/BurstHolder.java b/core/java/android/hardware/camera2/legacy/BurstHolder.java
deleted file mode 100644
index 23efe15..0000000
--- a/core/java/android/hardware/camera2/legacy/BurstHolder.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.camera2.CaptureRequest;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Immutable container for a burst of capture results.
- */
-public class BurstHolder {
-    private static final String TAG = "BurstHolder";
-    private final ArrayList<RequestHolder.Builder> mRequestBuilders;
-    private final boolean mRepeating;
-    private final int mRequestId;
-
-    /**
-     * Immutable container for a burst of capture results.
-     *
-     * @param requestId id of the burst request.
-     * @param repeating true if this burst is repeating.
-     * @param requests the array of {@link CaptureRequest}s for this burst.
-     * @param jpegSurfaceIds a {@link Collection} of IDs for the surfaces that have jpeg outputs.
-     */
-    public BurstHolder(int requestId, boolean repeating, CaptureRequest[] requests,
-                       Collection<Long> jpegSurfaceIds) {
-        mRequestBuilders = new ArrayList<>();
-        int i = 0;
-        for (CaptureRequest r : requests) {
-            mRequestBuilders.add(new RequestHolder.Builder(requestId, /*subsequenceId*/i,
-                    /*request*/r, repeating, jpegSurfaceIds));
-            ++i;
-        }
-        mRepeating = repeating;
-        mRequestId = requestId;
-    }
-
-    /**
-     * Get the id of this request.
-     */
-    public int getRequestId() {
-        return mRequestId;
-    }
-
-    /**
-     * Return true if this repeating.
-     */
-    public boolean isRepeating() {
-        return mRepeating;
-    }
-
-    /**
-     * Return the number of requests in this burst sequence.
-     */
-    public int getNumberOfRequests() {
-        return mRequestBuilders.size();
-    }
-
-    /**
-     * Create a list of {@link RequestHolder} objects encapsulating the requests in this burst.
-     *
-     * @param frameNumber the starting framenumber for this burst.
-     * @return the list of {@link RequestHolder} objects.
-     */
-    public List<RequestHolder> produceRequestHolders(long frameNumber) {
-        ArrayList<RequestHolder> holders = new ArrayList<RequestHolder>();
-        int i = 0;
-        for (RequestHolder.Builder b : mRequestBuilders) {
-            holders.add(b.build(frameNumber + i));
-            ++i;
-        }
-        return holders;
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
deleted file mode 100644
index 89ecd5f1c..0000000
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.os.Handler;
-import android.util.Log;
-
-/**
- * Emulates a the state of a single Camera2 device.
- *
- * <p>
- * This class acts as the state machine for a camera device.  Valid state transitions are given
- * in the table below:
- * </p>
- *
- * <ul>
- *      <li>{@code UNCONFIGURED -> CONFIGURING}</li>
- *      <li>{@code CONFIGURING -> IDLE}</li>
- *      <li>{@code IDLE -> CONFIGURING}</li>
- *      <li>{@code IDLE -> CAPTURING}</li>
- *      <li>{@code IDLE -> IDLE}</li>
- *      <li>{@code CAPTURING -> IDLE}</li>
- *      <li>{@code ANY -> ERROR}</li>
- * </ul>
- */
-public class CameraDeviceState {
-    private static final String TAG = "CameraDeviceState";
-    private static final boolean DEBUG = false;
-
-    private static final int STATE_ERROR = 0;
-    private static final int STATE_UNCONFIGURED = 1;
-    private static final int STATE_CONFIGURING = 2;
-    private static final int STATE_IDLE = 3;
-    private static final int STATE_CAPTURING = 4;
-
-    private static final String[] sStateNames = { "ERROR", "UNCONFIGURED", "CONFIGURING", "IDLE",
-            "CAPTURING"};
-
-    private int mCurrentState = STATE_UNCONFIGURED;
-    private int mCurrentError = NO_CAPTURE_ERROR;
-
-    private RequestHolder mCurrentRequest = null;
-
-    private Handler mCurrentHandler = null;
-    private CameraDeviceStateListener mCurrentListener = null;
-
-    /**
-     * Error code used by {@link #setCaptureStart} and {@link #setCaptureResult} to indicate that no
-     * error has occurred.
-     */
-    public static final int NO_CAPTURE_ERROR = -1;
-
-    /**
-     * CameraDeviceStateListener callbacks to be called after state transitions.
-     */
-    public interface CameraDeviceStateListener {
-        void onError(int errorCode, Object errorArg, RequestHolder holder);
-        void onConfiguring();
-        void onIdle();
-        void onBusy();
-        void onCaptureStarted(RequestHolder holder, long timestamp);
-        void onCaptureResult(CameraMetadataNative result, RequestHolder holder);
-        void onRequestQueueEmpty();
-        void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId);
-    }
-
-    /**
-     * Transition to the {@code ERROR} state.
-     *
-     * <p>
-     * The device cannot exit the {@code ERROR} state.  If the device was not already in the
-     * {@code ERROR} state, {@link CameraDeviceStateListener#onError(int, RequestHolder)} will be
-     * called.
-     * </p>
-     *
-     * @param error the error to set.  Should be one of the error codes defined in
-     *      {@link CameraDeviceImpl.CameraDeviceCallbacks}.
-     */
-    public synchronized void setError(int error) {
-        mCurrentError = error;
-        doStateTransition(STATE_ERROR);
-    }
-
-    /**
-     * Transition to the {@code CONFIGURING} state, or {@code ERROR} if in an invalid state.
-     *
-     * <p>
-     * If the device was not already in the {@code CONFIGURING} state,
-     * {@link CameraDeviceStateListener#onConfiguring()} will be called.
-     * </p>
-     *
-     * @return {@code false} if an error has occurred.
-     */
-    public synchronized boolean setConfiguring() {
-        doStateTransition(STATE_CONFIGURING);
-        return mCurrentError == NO_CAPTURE_ERROR;
-    }
-
-    /**
-     * Transition to the {@code IDLE} state, or {@code ERROR} if in an invalid state.
-     *
-     * <p>
-     * If the device was not already in the {@code IDLE} state,
-     * {@link CameraDeviceStateListener#onIdle()} will be called.
-     * </p>
-     *
-     * @return {@code false} if an error has occurred.
-     */
-    public synchronized boolean setIdle() {
-        doStateTransition(STATE_IDLE);
-        return mCurrentError == NO_CAPTURE_ERROR;
-    }
-
-    /**
-     * Transition to the {@code CAPTURING} state, or {@code ERROR} if in an invalid state.
-     *
-     * <p>
-     * If the device was not already in the {@code CAPTURING} state,
-     * {@link CameraDeviceStateListener#onCaptureStarted(RequestHolder)} will be called.
-     * </p>
-     *
-     * @param request A {@link RequestHolder} containing the request for the current capture.
-     * @param timestamp The timestamp of the capture start in nanoseconds.
-     * @param captureError Report a recoverable error for a single request using a valid
-     *                     error code for {@code ICameraDeviceCallbacks}, or
-     *                     {@link #NO_CAPTURE_ERROR}
-     * @return {@code false} if an error has occurred.
-     */
-    public synchronized boolean setCaptureStart(final RequestHolder request, long timestamp,
-                                            int captureError) {
-        mCurrentRequest = request;
-        doStateTransition(STATE_CAPTURING, timestamp, captureError);
-        return mCurrentError == NO_CAPTURE_ERROR;
-    }
-
-    /**
-     * Set the result for a capture.
-     *
-     * <p>
-     * If the device was in the {@code CAPTURING} state,
-     * {@link CameraDeviceStateListener#onCaptureResult(CameraMetadataNative, RequestHolder)} will
-     * be called with the given result, otherwise this will result in the device transitioning to
-     * the {@code ERROR} state,
-     * </p>
-     *
-     * @param request The {@link RequestHolder} request that created this result.
-     * @param result The {@link CameraMetadataNative} result to set.
-     * @param captureError Report a recoverable error for a single buffer or result using a valid
-     *                     error code for {@code ICameraDeviceCallbacks}, or
-     *                     {@link #NO_CAPTURE_ERROR}.
-     * @param captureErrorArg An argument for some error captureError codes.
-     * @return {@code false} if an error has occurred.
-     */
-    public synchronized boolean setCaptureResult(final RequestHolder request,
-            final CameraMetadataNative result,
-            final int captureError, final Object captureErrorArg) {
-        if (mCurrentState != STATE_CAPTURING) {
-            Log.e(TAG, "Cannot receive result while in state: " + mCurrentState);
-            mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
-            doStateTransition(STATE_ERROR);
-            return mCurrentError == NO_CAPTURE_ERROR;
-        }
-
-        if (mCurrentHandler != null && mCurrentListener != null) {
-            if (captureError != NO_CAPTURE_ERROR) {
-                mCurrentHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mCurrentListener.onError(captureError, captureErrorArg, request);
-                    }
-                });
-            } else {
-                mCurrentHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mCurrentListener.onCaptureResult(result, request);
-                    }
-                });
-            }
-        }
-        return mCurrentError == NO_CAPTURE_ERROR;
-    }
-
-    public synchronized boolean setCaptureResult(final RequestHolder request,
-            final CameraMetadataNative result) {
-        return setCaptureResult(request, result, NO_CAPTURE_ERROR, /*errorArg*/null);
-    }
-
-    /**
-     * Set repeating request error.
-     *
-     * <p>Repeating request has been stopped due to an error such as abandoned output surfaces.</p>
-     *
-     * @param lastFrameNumber Frame number of the last repeating request before it is stopped.
-     * @param repeatingRequestId The ID of the repeating request being stopped
-     */
-    public synchronized void setRepeatingRequestError(final long lastFrameNumber,
-            final int repeatingRequestId) {
-        mCurrentHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mCurrentListener.onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
-            }
-        });
-    }
-
-    /**
-     * Indicate that request queue (non-repeating) becomes empty.
-     *
-     * <p> Send notification that all non-repeating requests have been sent to camera device. </p>
-     */
-    public synchronized void setRequestQueueEmpty() {
-        mCurrentHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                mCurrentListener.onRequestQueueEmpty();
-            }
-        });
-    }
-
-    /**
-     * Set the listener for state transition callbacks.
-     *
-     * @param handler handler on which to call the callbacks.
-     * @param listener the {@link CameraDeviceStateListener} callbacks to call.
-     */
-    public synchronized void setCameraDeviceCallbacks(Handler handler,
-                                                      CameraDeviceStateListener listener) {
-        mCurrentHandler = handler;
-        mCurrentListener = listener;
-    }
-
-    private void doStateTransition(int newState) {
-        doStateTransition(newState, /*timestamp*/0, NO_CAPTURE_ERROR);
-    }
-
-    private void doStateTransition(int newState, final long timestamp, final int error) {
-        if (newState != mCurrentState) {
-            String stateName = "UNKNOWN";
-            if (newState >= 0 && newState < sStateNames.length) {
-                stateName = sStateNames[newState];
-            }
-            Log.i(TAG, "Legacy camera service transitioning to state " + stateName);
-        }
-
-        // If we transitioned into a non-IDLE/non-ERROR state then mark the device as busy
-        if(newState != STATE_ERROR && newState != STATE_IDLE) {
-            if (mCurrentState != newState && mCurrentHandler != null &&
-                    mCurrentListener != null) {
-                mCurrentHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        mCurrentListener.onBusy();
-                    }
-                });
-            }
-        }
-
-        switch(newState) {
-            case STATE_ERROR:
-                if (mCurrentState != STATE_ERROR && mCurrentHandler != null &&
-                        mCurrentListener != null) {
-                    mCurrentHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mCurrentListener.onError(mCurrentError, /*errorArg*/null, mCurrentRequest);
-                        }
-                    });
-                }
-                mCurrentState = STATE_ERROR;
-                break;
-            case STATE_CONFIGURING:
-                if (mCurrentState != STATE_UNCONFIGURED && mCurrentState != STATE_IDLE) {
-                    Log.e(TAG, "Cannot call configure while in state: " + mCurrentState);
-                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
-                    doStateTransition(STATE_ERROR);
-                    break;
-                }
-                if (mCurrentState != STATE_CONFIGURING && mCurrentHandler != null &&
-                        mCurrentListener != null) {
-                    mCurrentHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mCurrentListener.onConfiguring();
-                        }
-                    });
-                }
-                mCurrentState = STATE_CONFIGURING;
-                break;
-            case STATE_IDLE:
-                if (mCurrentState == STATE_IDLE) {
-                    break;
-                }
-
-                if (mCurrentState != STATE_CONFIGURING && mCurrentState != STATE_CAPTURING) {
-                    Log.e(TAG, "Cannot call idle while in state: " + mCurrentState);
-                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
-                    doStateTransition(STATE_ERROR);
-                    break;
-                }
-
-                if (mCurrentState != STATE_IDLE && mCurrentHandler != null &&
-                        mCurrentListener != null) {
-                    mCurrentHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            mCurrentListener.onIdle();
-                        }
-                    });
-                }
-                mCurrentState = STATE_IDLE;
-                break;
-            case STATE_CAPTURING:
-                if (mCurrentState != STATE_IDLE && mCurrentState != STATE_CAPTURING) {
-                    Log.e(TAG, "Cannot call capture while in state: " + mCurrentState);
-                    mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE;
-                    doStateTransition(STATE_ERROR);
-                    break;
-                }
-
-                if (mCurrentHandler != null && mCurrentListener != null) {
-                    if (error != NO_CAPTURE_ERROR) {
-                        mCurrentHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                mCurrentListener.onError(error, /*errorArg*/null, mCurrentRequest);
-                            }
-                        });
-                    } else {
-                        mCurrentHandler.post(new Runnable() {
-                            @Override
-                            public void run() {
-                                mCurrentListener.onCaptureStarted(mCurrentRequest, timestamp);
-                            }
-                        });
-                    }
-                }
-                mCurrentState = STATE_CAPTURING;
-                break;
-            default:
-                throw new IllegalStateException("Transition to unknown state: " + newState);
-        }
-    }
-
-
-}
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
deleted file mode 100644
index cf8cab2..0000000
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.ICameraService;
-import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.ICameraDeviceUser;
-import android.hardware.camera2.ICameraOfflineSession;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.impl.CaptureResultExtras;
-import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
-import android.hardware.camera2.params.OutputConfiguration;
-import android.hardware.camera2.params.SessionConfiguration;
-import android.hardware.camera2.utils.SubmitInfo;
-import android.os.ConditionVariable;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.util.Log;
-import android.util.Size;
-import android.util.SparseArray;
-import android.view.Surface;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.system.OsConstants.EACCES;
-import static android.system.OsConstants.ENODEV;
-
-/**
- * Compatibility implementation of the Camera2 API binder interface.
- *
- * <p>
- * This is intended to be called from the same process as client
- * {@link android.hardware.camera2.CameraDevice}, and wraps a
- * {@link android.hardware.camera2.legacy.LegacyCameraDevice} that emulates Camera2 service using
- * the Camera1 API.
- * </p>
- *
- * <p>
- * Keep up to date with ICameraDeviceUser.aidl.
- * </p>
- */
-@SuppressWarnings("deprecation")
-public class CameraDeviceUserShim implements ICameraDeviceUser {
-    private static final String TAG = "CameraDeviceUserShim";
-
-    private static final boolean DEBUG = false;
-    private static final int OPEN_CAMERA_TIMEOUT_MS = 5000; // 5 sec (same as api1 cts timeout)
-
-    private final LegacyCameraDevice mLegacyDevice;
-
-    private final Object mConfigureLock = new Object();
-    private int mSurfaceIdCounter;
-    private boolean mConfiguring;
-    private final SparseArray<Surface> mSurfaces;
-    private final CameraCharacteristics mCameraCharacteristics;
-    private final CameraLooper mCameraInit;
-    private final CameraCallbackThread mCameraCallbacks;
-
-
-    protected CameraDeviceUserShim(int cameraId, LegacyCameraDevice legacyCamera,
-            CameraCharacteristics characteristics, CameraLooper cameraInit,
-            CameraCallbackThread cameraCallbacks) {
-        mLegacyDevice = legacyCamera;
-        mConfiguring = false;
-        mSurfaces = new SparseArray<Surface>();
-        mCameraCharacteristics = characteristics;
-        mCameraInit = cameraInit;
-        mCameraCallbacks = cameraCallbacks;
-
-        mSurfaceIdCounter = 0;
-    }
-
-    private static int translateErrorsFromCamera1(int errorCode) {
-        if (errorCode == -EACCES) {
-            return ICameraService.ERROR_PERMISSION_DENIED;
-        }
-
-        return errorCode;
-    }
-
-    /**
-     * Create a separate looper/thread for the camera to run on; open the camera.
-     *
-     * <p>Since the camera automatically latches on to the current thread's looper,
-     * it's important that we have our own thread with our own looper to guarantee
-     * that the camera callbacks get correctly posted to our own thread.</p>
-     */
-    private static class CameraLooper implements Runnable, AutoCloseable {
-        private final int mCameraId;
-        private Looper mLooper;
-        private volatile int mInitErrors;
-        private final Camera mCamera = Camera.openUninitialized();
-        private final ConditionVariable mStartDone = new ConditionVariable();
-        private final Thread mThread;
-
-        /**
-         * Spin up a new thread, immediately open the camera in the background.
-         *
-         * <p>Use {@link #waitForOpen} to block until the camera is finished opening.</p>
-         *
-         * @param cameraId numeric camera Id
-         *
-         * @see #waitForOpen
-         */
-        public CameraLooper(int cameraId) {
-            mCameraId = cameraId;
-
-            mThread = new Thread(this, "LegacyCameraLooper");
-            mThread.start();
-        }
-
-        public Camera getCamera() {
-            return mCamera;
-        }
-
-        @Override
-        public void run() {
-            // Set up a looper to be used by camera.
-            Looper.prepare();
-
-            // Save the looper so that we can terminate this thread
-            // after we are done with it.
-            mLooper = Looper.myLooper();
-            mInitErrors = mCamera.cameraInitUnspecified(mCameraId);
-            mStartDone.open();
-            Looper.loop();  // Blocks forever until #close is called.
-        }
-
-        /**
-         * Quit the looper safely; then join until the thread shuts down.
-         */
-        @Override
-        public void close() {
-            if (mLooper == null) {
-                return;
-            }
-
-            mLooper.quitSafely();
-            try {
-                mThread.join();
-            } catch (InterruptedException e) {
-                throw new AssertionError(e);
-            }
-
-            mLooper = null;
-        }
-
-        /**
-         * Block until the camera opens; then return its initialization error code (if any).
-         *
-         * @param timeoutMs timeout in milliseconds
-         *
-         * @return int error code
-         *
-         * @throws ServiceSpecificException if the camera open times out with ({@code CAMERA_ERROR})
-         */
-        public int waitForOpen(int timeoutMs) {
-            // Block until the camera is open asynchronously
-            if (!mStartDone.block(timeoutMs)) {
-                Log.e(TAG, "waitForOpen - Camera failed to open after timeout of "
-                        + OPEN_CAMERA_TIMEOUT_MS + " ms");
-                try {
-                    mCamera.release();
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "connectBinderShim - Failed to release camera after timeout ", e);
-                }
-
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION);
-            }
-
-            return mInitErrors;
-        }
-    }
-
-    /**
-     * A thread to process callbacks to send back to the camera client.
-     *
-     * <p>This effectively emulates one-way binder semantics when in the same process as the
-     * callee.</p>
-     */
-    private static class CameraCallbackThread implements ICameraDeviceCallbacks {
-        private static final int CAMERA_ERROR = 0;
-        private static final int CAMERA_IDLE = 1;
-        private static final int CAPTURE_STARTED = 2;
-        private static final int RESULT_RECEIVED = 3;
-        private static final int PREPARED = 4;
-        private static final int REPEATING_REQUEST_ERROR = 5;
-        private static final int REQUEST_QUEUE_EMPTY = 6;
-
-        private final HandlerThread mHandlerThread;
-        private Handler mHandler;
-
-        private final ICameraDeviceCallbacks mCallbacks;
-
-        public CameraCallbackThread(ICameraDeviceCallbacks callbacks) {
-            mCallbacks = callbacks;
-
-            mHandlerThread = new HandlerThread("LegacyCameraCallback");
-            mHandlerThread.start();
-        }
-
-        public void close() {
-            mHandlerThread.quitSafely();
-        }
-
-        @Override
-        public void onDeviceError(final int errorCode, final CaptureResultExtras resultExtras) {
-            Message msg = getHandler().obtainMessage(CAMERA_ERROR,
-                /*arg1*/ errorCode, /*arg2*/ 0,
-                /*obj*/ resultExtras);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onDeviceIdle() {
-            Message msg = getHandler().obtainMessage(CAMERA_IDLE);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onCaptureStarted(final CaptureResultExtras resultExtras, final long timestamp) {
-            Message msg = getHandler().obtainMessage(CAPTURE_STARTED,
-                    /*arg1*/ (int) (timestamp & 0xFFFFFFFFL),
-                    /*arg2*/ (int) ( (timestamp >> 32) & 0xFFFFFFFFL),
-                    /*obj*/ resultExtras);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onResultReceived(final CameraMetadataNative result,
-                final CaptureResultExtras resultExtras,
-                PhysicalCaptureResultInfo physicalResults[]) {
-            Object[] resultArray = new Object[] { result, resultExtras };
-            Message msg = getHandler().obtainMessage(RESULT_RECEIVED,
-                    /*obj*/ resultArray);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onPrepared(int streamId) {
-            Message msg = getHandler().obtainMessage(PREPARED,
-                    /*arg1*/ streamId, /*arg2*/ 0);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onRepeatingRequestError(long lastFrameNumber, int repeatingRequestId) {
-            Object[] objArray = new Object[] { lastFrameNumber, repeatingRequestId };
-            Message msg = getHandler().obtainMessage(REPEATING_REQUEST_ERROR,
-                    /*obj*/ objArray);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public void onRequestQueueEmpty() {
-            Message msg = getHandler().obtainMessage(REQUEST_QUEUE_EMPTY,
-                    /* arg1 */ 0, /* arg2 */ 0);
-            getHandler().sendMessage(msg);
-        }
-
-        @Override
-        public IBinder asBinder() {
-            // This is solely intended to be used for in-process binding.
-            return null;
-        }
-
-        private Handler getHandler() {
-            if (mHandler == null) {
-                mHandler = new CallbackHandler(mHandlerThread.getLooper());
-            }
-            return mHandler;
-        }
-
-        private class CallbackHandler extends Handler {
-            public CallbackHandler(Looper l) {
-                super(l);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                try {
-                    switch (msg.what) {
-                        case CAMERA_ERROR: {
-                            int errorCode = msg.arg1;
-                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
-                            mCallbacks.onDeviceError(errorCode, resultExtras);
-                            break;
-                        }
-                        case CAMERA_IDLE:
-                            mCallbacks.onDeviceIdle();
-                            break;
-                        case CAPTURE_STARTED: {
-                            long timestamp = msg.arg2 & 0xFFFFFFFFL;
-                            timestamp = (timestamp << 32) | (msg.arg1 & 0xFFFFFFFFL);
-                            CaptureResultExtras resultExtras = (CaptureResultExtras) msg.obj;
-                            mCallbacks.onCaptureStarted(resultExtras, timestamp);
-                            break;
-                        }
-                        case RESULT_RECEIVED: {
-                            Object[] resultArray = (Object[]) msg.obj;
-                            CameraMetadataNative result = (CameraMetadataNative) resultArray[0];
-                            CaptureResultExtras resultExtras = (CaptureResultExtras) resultArray[1];
-                            mCallbacks.onResultReceived(result, resultExtras,
-                                    new PhysicalCaptureResultInfo[0]);
-                            break;
-                        }
-                        case PREPARED: {
-                            int streamId = msg.arg1;
-                            mCallbacks.onPrepared(streamId);
-                            break;
-                        }
-                        case REPEATING_REQUEST_ERROR: {
-                            Object[] objArray = (Object[]) msg.obj;
-                            long lastFrameNumber = (Long) objArray[0];
-                            int repeatingRequestId = (Integer) objArray[1];
-                            mCallbacks.onRepeatingRequestError(lastFrameNumber, repeatingRequestId);
-                            break;
-                        }
-                        case REQUEST_QUEUE_EMPTY: {
-                            mCallbacks.onRequestQueueEmpty();
-                            break;
-                        }
-                        default:
-                            throw new IllegalArgumentException(
-                                "Unknown callback message " + msg.what);
-                    }
-                } catch (RemoteException e) {
-                    throw new IllegalStateException(
-                        "Received remote exception during camera callback " + msg.what, e);
-                }
-            }
-        }
-    }
-
-    public static CameraDeviceUserShim connectBinderShim(ICameraDeviceCallbacks callbacks,
-                                                         int cameraId, Size displaySize) {
-        if (DEBUG) {
-            Log.d(TAG, "Opening shim Camera device");
-        }
-
-        /*
-         * Put the camera open on a separate thread with its own looper; otherwise
-         * if the main thread is used then the callbacks might never get delivered
-         * (e.g. in CTS which run its own default looper only after tests)
-         */
-
-        CameraLooper init = new CameraLooper(cameraId);
-
-        CameraCallbackThread threadCallbacks = new CameraCallbackThread(callbacks);
-
-        // TODO: Make this async instead of blocking
-        int initErrors = init.waitForOpen(OPEN_CAMERA_TIMEOUT_MS);
-        Camera legacyCamera = init.getCamera();
-
-        // Check errors old HAL initialization
-        LegacyExceptionUtils.throwOnServiceError(initErrors);
-
-        // Disable shutter sounds (this will work unconditionally) for api2 clients
-        legacyCamera.disableShutterSound();
-
-        CameraInfo info = new CameraInfo();
-        Camera.getCameraInfo(cameraId, info);
-
-        Camera.Parameters legacyParameters = null;
-        try {
-            legacyParameters = legacyCamera.getParameters();
-        } catch (RuntimeException e) {
-            throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION,
-                    "Unable to get initial parameters: " + e.getMessage());
-        }
-
-        CameraCharacteristics characteristics =
-                LegacyMetadataMapper.createCharacteristics(legacyParameters, info, cameraId,
-                        displaySize);
-        LegacyCameraDevice device = new LegacyCameraDevice(
-                cameraId, legacyCamera, characteristics, threadCallbacks);
-        return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks);
-    }
-
-    @Override
-    public void disconnect() {
-        if (DEBUG) {
-            Log.d(TAG, "disconnect called.");
-        }
-
-        if (mLegacyDevice.isClosed()) {
-            Log.w(TAG, "Cannot disconnect, device has already been closed.");
-        }
-
-        try {
-            mLegacyDevice.close();
-        } finally {
-            mCameraInit.close();
-            mCameraCallbacks.close();
-        }
-    }
-
-    @Override
-    public SubmitInfo submitRequest(CaptureRequest request, boolean streaming) {
-        if (DEBUG) {
-            Log.d(TAG, "submitRequest called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot submit request, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot submit request, configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-        }
-        return mLegacyDevice.submitRequest(request, streaming);
-    }
-
-    @Override
-    public SubmitInfo submitRequestList(CaptureRequest[] request, boolean streaming) {
-        if (DEBUG) {
-            Log.d(TAG, "submitRequestList called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot submit request list, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot submit request, configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-        }
-        return mLegacyDevice.submitRequestList(request, streaming);
-    }
-
-    @Override
-    public long cancelRequest(int requestId) {
-        if (DEBUG) {
-            Log.d(TAG, "cancelRequest called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot cancel request, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot cancel request, configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-        }
-        return mLegacyDevice.cancelRequest(requestId);
-    }
-
-    @Override
-    public boolean isSessionConfigurationSupported(SessionConfiguration sessionConfig) {
-        if (sessionConfig.getSessionType() != SessionConfiguration.SESSION_REGULAR) {
-            Log.e(TAG, "Session type: " + sessionConfig.getSessionType() + " is different from " +
-                    " regular. Legacy devices support only regular session types!");
-            return false;
-        }
-
-        if (sessionConfig.getInputConfiguration() != null) {
-            Log.e(TAG, "Input configuration present, legacy devices do not support this feature!");
-            return false;
-        }
-
-        List<OutputConfiguration> outputConfigs = sessionConfig.getOutputConfigurations();
-        if (outputConfigs.isEmpty()) {
-            Log.e(TAG, "Empty output configuration list!");
-            return false;
-        }
-
-        SparseArray<Surface> surfaces = new SparseArray<Surface>(outputConfigs.size());
-        int idx = 0;
-        for (OutputConfiguration outputConfig : outputConfigs) {
-            List<Surface> surfaceList = outputConfig.getSurfaces();
-            if (surfaceList.isEmpty() || (surfaceList.size() > 1)) {
-                Log.e(TAG, "Legacy devices do not support deferred or shared surfaces!");
-                return false;
-            }
-
-            surfaces.put(idx++, outputConfig.getSurface());
-        }
-
-        int ret = mLegacyDevice.configureOutputs(surfaces, /*validateSurfacesOnly*/true);
-
-        return ret == LegacyExceptionUtils.NO_ERROR;
-    }
-
-    @Override
-    public void beginConfigure() {
-        if (DEBUG) {
-            Log.d(TAG, "beginConfigure called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot begin configure, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot begin configure, configuration change already in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-            mConfiguring = true;
-        }
-    }
-
-    @Override
-    public int[] endConfigure(int operatingMode, CameraMetadataNative sessionParams) {
-        if (DEBUG) {
-            Log.d(TAG, "endConfigure called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot end configure, device has been closed.";
-            Log.e(TAG, err);
-            synchronized(mConfigureLock) {
-                mConfiguring = false;
-            }
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        if (operatingMode != ICameraDeviceUser.NORMAL_MODE) {
-            String err = "LEGACY devices do not support this operating mode";
-            Log.e(TAG, err);
-            synchronized(mConfigureLock) {
-                mConfiguring = false;
-            }
-            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
-        }
-
-        SparseArray<Surface> surfaces = null;
-        synchronized(mConfigureLock) {
-            if (!mConfiguring) {
-                String err = "Cannot end configure, no configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-            if (mSurfaces != null) {
-                surfaces = mSurfaces.clone();
-            }
-            mConfiguring = false;
-        }
-        mLegacyDevice.configureOutputs(surfaces);
-
-        return new int[0]; // Offline mode is not supported
-    }
-
-    @Override
-    public void deleteStream(int streamId) {
-        if (DEBUG) {
-            Log.d(TAG, "deleteStream called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot delete stream, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (!mConfiguring) {
-                String err = "Cannot delete stream, no configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-            int index = mSurfaces.indexOfKey(streamId);
-            if (index < 0) {
-                String err = "Cannot delete stream, stream id " + streamId + " doesn't exist.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
-            }
-            mSurfaces.removeAt(index);
-        }
-    }
-
-    @Override
-    public int createStream(OutputConfiguration outputConfiguration) {
-        if (DEBUG) {
-            Log.d(TAG, "createStream called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot create stream, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (!mConfiguring) {
-                String err = "Cannot create stream, beginConfigure hasn't been called yet.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-            if (outputConfiguration.getRotation() != OutputConfiguration.ROTATION_0) {
-                String err = "Cannot create stream, stream rotation is not supported.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
-            }
-            int id = ++mSurfaceIdCounter;
-            mSurfaces.put(id, outputConfiguration.getSurface());
-            return id;
-        }
-    }
-
-    @Override
-    public void finalizeOutputConfigurations(int steamId, OutputConfiguration config) {
-        String err = "Finalizing output configuration is not supported on legacy devices";
-        Log.e(TAG, err);
-        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-    }
-
-    @Override
-    public int createInputStream(int width, int height, int format) {
-        String err = "Creating input stream is not supported on legacy devices";
-        Log.e(TAG, err);
-        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-    }
-
-    @Override
-    public Surface getInputSurface() {
-        String err = "Getting input surface is not supported on legacy devices";
-        Log.e(TAG, err);
-        throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-    }
-
-    @Override
-    public CameraMetadataNative createDefaultRequest(int templateId) {
-        if (DEBUG) {
-            Log.d(TAG, "createDefaultRequest called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot create default request, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        CameraMetadataNative template;
-        try {
-            template =
-                    LegacyMetadataMapper.createRequestTemplate(mCameraCharacteristics, templateId);
-        } catch (IllegalArgumentException e) {
-            String err = "createDefaultRequest - invalid templateId specified";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_ILLEGAL_ARGUMENT, err);
-        }
-
-        return template;
-    }
-
-    @Override
-    public CameraMetadataNative getCameraInfo() {
-        if (DEBUG) {
-            Log.d(TAG, "getCameraInfo called.");
-        }
-        // TODO: implement getCameraInfo.
-        Log.e(TAG, "getCameraInfo unimplemented.");
-        return null;
-    }
-
-    @Override
-    public void updateOutputConfiguration(int streamId, OutputConfiguration config) {
-        // TODO: b/63912484 implement updateOutputConfiguration.
-    }
-
-    @Override
-    public void waitUntilIdle() throws RemoteException {
-        if (DEBUG) {
-            Log.d(TAG, "waitUntilIdle called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot wait until idle, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot wait until idle, configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-        }
-        mLegacyDevice.waitUntilIdle();
-    }
-
-    @Override
-    public long flush() {
-        if (DEBUG) {
-            Log.d(TAG, "flush called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot flush, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        synchronized(mConfigureLock) {
-            if (mConfiguring) {
-                String err = "Cannot flush, configuration change in progress.";
-                Log.e(TAG, err);
-                throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err);
-            }
-        }
-        return mLegacyDevice.flush();
-    }
-
-    public void prepare(int streamId) {
-        if (DEBUG) {
-            Log.d(TAG, "prepare called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot prepare stream, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        // LEGACY doesn't support actual prepare, just signal success right away
-        mCameraCallbacks.onPrepared(streamId);
-    }
-
-    public void prepare2(int maxCount, int streamId) {
-        // We don't support this in LEGACY mode.
-        prepare(streamId);
-    }
-
-    public void tearDown(int streamId) {
-        if (DEBUG) {
-            Log.d(TAG, "tearDown called.");
-        }
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot tear down stream, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        // LEGACY doesn't support actual teardown, so just a no-op
-    }
-
-    @Override
-    public void setCameraAudioRestriction(int mode) {
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot set camera audio restriction, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        mLegacyDevice.setAudioRestriction(mode);
-    }
-
-    @Override
-    public int getGlobalAudioRestriction() {
-        if (mLegacyDevice.isClosed()) {
-            String err = "Cannot set camera audio restriction, device has been closed.";
-            Log.e(TAG, err);
-            throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err);
-        }
-
-        return mLegacyDevice.getAudioRestriction();
-    }
-
-    @Override
-    public ICameraOfflineSession switchToOffline(ICameraDeviceCallbacks cbs,
-            int[] offlineOutputIds) {
-        throw new UnsupportedOperationException("Legacy device does not support offline mode");
-    }
-
-    @Override
-    public IBinder asBinder() {
-        // This is solely intended to be used for in-process binding.
-        return null;
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/CaptureCollector.java b/core/java/android/hardware/camera2/legacy/CaptureCollector.java
deleted file mode 100644
index 113927c..0000000
--- a/core/java/android/hardware/camera2/legacy/CaptureCollector.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.camera2.legacy;
-
-import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.util.Log;
-import android.util.MutableLong;
-import android.util.Pair;
-import android.view.Surface;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.TreeSet;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.ReentrantLock;
-
-/**
- * Collect timestamps and state for each {@link CaptureRequest} as it passes through
- * the Legacy camera pipeline.
- */
-public class CaptureCollector {
-    private static final String TAG = "CaptureCollector";
-
-    private static final boolean DEBUG = false;
-
-    private static final int FLAG_RECEIVED_JPEG = 1;
-    private static final int FLAG_RECEIVED_JPEG_TS = 2;
-    private static final int FLAG_RECEIVED_PREVIEW = 4;
-    private static final int FLAG_RECEIVED_PREVIEW_TS = 8;
-    private static final int FLAG_RECEIVED_ALL_JPEG = FLAG_RECEIVED_JPEG | FLAG_RECEIVED_JPEG_TS;
-    private static final int FLAG_RECEIVED_ALL_PREVIEW = FLAG_RECEIVED_PREVIEW |
-            FLAG_RECEIVED_PREVIEW_TS;
-
-    private static final int MAX_JPEGS_IN_FLIGHT = 1;
-
-    private class CaptureHolder implements Comparable<CaptureHolder>{
-        private final RequestHolder mRequest;
-        private final LegacyRequest mLegacy;
-        public final boolean needsJpeg;
-        public final boolean needsPreview;
-
-        private long mTimestamp = 0;
-        private int mReceivedFlags = 0;
-        private boolean mHasStarted = false;
-        private boolean mFailedJpeg = false;
-        private boolean mFailedPreview = false;
-        private boolean mCompleted = false;
-        private boolean mPreviewCompleted = false;
-
-        public CaptureHolder(RequestHolder request, LegacyRequest legacyHolder) {
-            mRequest = request;
-            mLegacy = legacyHolder;
-            needsJpeg = request.hasJpegTargets();
-            needsPreview = request.hasPreviewTargets();
-        }
-
-        public boolean isPreviewCompleted() {
-            return (mReceivedFlags & FLAG_RECEIVED_ALL_PREVIEW) == FLAG_RECEIVED_ALL_PREVIEW;
-        }
-
-        public  boolean isJpegCompleted() {
-            return (mReceivedFlags & FLAG_RECEIVED_ALL_JPEG) == FLAG_RECEIVED_ALL_JPEG;
-        }
-
-        public boolean isCompleted() {
-            return (needsJpeg == isJpegCompleted()) && (needsPreview == isPreviewCompleted());
-        }
-
-        public void tryComplete() {
-            if (!mPreviewCompleted && needsPreview && isPreviewCompleted()) {
-                CaptureCollector.this.onPreviewCompleted();
-                mPreviewCompleted = true;
-            }
-
-            if (isCompleted() && !mCompleted) {
-                if (mFailedPreview || mFailedJpeg) {
-                    if (!mHasStarted) {
-                        // Send a request error if the capture has not yet started.
-                        mRequest.failRequest();
-                        CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp,
-                                CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_REQUEST);
-                    } else {
-                        // Send buffer dropped errors for each pending buffer if the request has
-                        // started.
-                        for (Surface targetSurface : mRequest.getRequest().getTargets() ) {
-                            try {
-                                if (mRequest.jpegType(targetSurface)) {
-                                    if (mFailedJpeg) {
-                                        CaptureCollector.this.mDeviceState.setCaptureResult(mRequest,
-                                                /*result*/null,
-                                                CameraDeviceImpl.CameraDeviceCallbacks.
-                                                        ERROR_CAMERA_BUFFER,
-                                                targetSurface);
-                                    }
-                                } else {
-                                    // preview buffer
-                                    if (mFailedPreview) {
-                                        CaptureCollector.this.mDeviceState.setCaptureResult(mRequest,
-                                                /*result*/null,
-                                                CameraDeviceImpl.CameraDeviceCallbacks.
-                                                        ERROR_CAMERA_BUFFER,
-                                                targetSurface);
-                                    }
-                                }
-                            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                                Log.e(TAG, "Unexpected exception when querying Surface: " + e);
-                            }
-                        }
-                    }
-                }
-                CaptureCollector.this.onRequestCompleted(CaptureHolder.this);
-                mCompleted = true;
-            }
-        }
-
-        public void setJpegTimestamp(long timestamp) {
-            if (DEBUG) {
-                Log.d(TAG, "setJpegTimestamp - called for request " + mRequest.getRequestId());
-            }
-            if (!needsJpeg) {
-                throw new IllegalStateException(
-                        "setJpegTimestamp called for capture with no jpeg targets.");
-            }
-            if (isCompleted()) {
-                throw new IllegalStateException(
-                        "setJpegTimestamp called on already completed request.");
-            }
-
-            mReceivedFlags |= FLAG_RECEIVED_JPEG_TS;
-
-            if (mTimestamp == 0) {
-                mTimestamp = timestamp;
-            }
-
-            if (!mHasStarted) {
-                mHasStarted = true;
-                CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp,
-                        CameraDeviceState.NO_CAPTURE_ERROR);
-            }
-
-            tryComplete();
-        }
-
-        public void setJpegProduced() {
-            if (DEBUG) {
-                Log.d(TAG, "setJpegProduced - called for request " + mRequest.getRequestId());
-            }
-            if (!needsJpeg) {
-                throw new IllegalStateException(
-                        "setJpegProduced called for capture with no jpeg targets.");
-            }
-            if (isCompleted()) {
-                throw new IllegalStateException(
-                        "setJpegProduced called on already completed request.");
-            }
-
-            mReceivedFlags |= FLAG_RECEIVED_JPEG;
-            tryComplete();
-        }
-
-        public void setJpegFailed() {
-            if (DEBUG) {
-                Log.d(TAG, "setJpegFailed - called for request " + mRequest.getRequestId());
-            }
-            if (!needsJpeg || isJpegCompleted()) {
-                return;
-            }
-            mFailedJpeg = true;
-
-            mReceivedFlags |= FLAG_RECEIVED_JPEG;
-            mReceivedFlags |= FLAG_RECEIVED_JPEG_TS;
-            tryComplete();
-        }
-
-        public void setPreviewTimestamp(long timestamp) {
-            if (DEBUG) {
-                Log.d(TAG, "setPreviewTimestamp - called for request " + mRequest.getRequestId());
-            }
-            if (!needsPreview) {
-                throw new IllegalStateException(
-                        "setPreviewTimestamp called for capture with no preview targets.");
-            }
-            if (isCompleted()) {
-                throw new IllegalStateException(
-                        "setPreviewTimestamp called on already completed request.");
-            }
-
-            mReceivedFlags |= FLAG_RECEIVED_PREVIEW_TS;
-
-            if (mTimestamp == 0) {
-                mTimestamp = timestamp;
-            }
-
-            if (!needsJpeg) {
-                if (!mHasStarted) {
-                    mHasStarted = true;
-                    CaptureCollector.this.mDeviceState.setCaptureStart(mRequest, mTimestamp,
-                            CameraDeviceState.NO_CAPTURE_ERROR);
-                }
-            }
-
-            tryComplete();
-        }
-
-        public void setPreviewProduced() {
-            if (DEBUG) {
-                Log.d(TAG, "setPreviewProduced - called for request " + mRequest.getRequestId());
-            }
-            if (!needsPreview) {
-                throw new IllegalStateException(
-                        "setPreviewProduced called for capture with no preview targets.");
-            }
-            if (isCompleted()) {
-                throw new IllegalStateException(
-                        "setPreviewProduced called on already completed request.");
-            }
-
-            mReceivedFlags |= FLAG_RECEIVED_PREVIEW;
-            tryComplete();
-        }
-
-        public void setPreviewFailed() {
-            if (DEBUG) {
-                Log.d(TAG, "setPreviewFailed - called for request " + mRequest.getRequestId());
-            }
-            if (!needsPreview || isPreviewCompleted()) {
-                return;
-            }
-            mFailedPreview = true;
-
-            mReceivedFlags |= FLAG_RECEIVED_PREVIEW;
-            mReceivedFlags |= FLAG_RECEIVED_PREVIEW_TS;
-            tryComplete();
-        }
-
-        // Comparison and equals based on frame number.
-        @Override
-        public int compareTo(CaptureHolder captureHolder) {
-            return (mRequest.getFrameNumber() > captureHolder.mRequest.getFrameNumber()) ? 1 :
-                    ((mRequest.getFrameNumber() == captureHolder.mRequest.getFrameNumber()) ? 0 :
-                            -1);
-        }
-
-        // Comparison and equals based on frame number.
-        @Override
-        public boolean equals(Object o) {
-            return o instanceof CaptureHolder && compareTo((CaptureHolder) o) == 0;
-        }
-    }
-
-    private final TreeSet<CaptureHolder> mActiveRequests;
-    private final ArrayDeque<CaptureHolder> mJpegCaptureQueue;
-    private final ArrayDeque<CaptureHolder> mJpegProduceQueue;
-    private final ArrayDeque<CaptureHolder> mPreviewCaptureQueue;
-    private final ArrayDeque<CaptureHolder> mPreviewProduceQueue;
-    private final ArrayList<CaptureHolder> mCompletedRequests = new ArrayList<>();
-
-    private final ReentrantLock mLock = new ReentrantLock();
-    private final Condition mIsEmpty;
-    private final Condition mPreviewsEmpty;
-    private final Condition mNotFull;
-    private final CameraDeviceState mDeviceState;
-    private int mInFlight = 0;
-    private int mInFlightPreviews = 0;
-    private final int mMaxInFlight;
-
-    /**
-     * Create a new {@link CaptureCollector} that can modify the given {@link CameraDeviceState}.
-     *
-     * @param maxInFlight max allowed in-flight requests.
-     * @param deviceState the {@link CameraDeviceState} to update as requests are processed.
-     */
-    public CaptureCollector(int maxInFlight, CameraDeviceState deviceState) {
-        mMaxInFlight = maxInFlight;
-        mJpegCaptureQueue = new ArrayDeque<>(MAX_JPEGS_IN_FLIGHT);
-        mJpegProduceQueue = new ArrayDeque<>(MAX_JPEGS_IN_FLIGHT);
-        mPreviewCaptureQueue = new ArrayDeque<>(mMaxInFlight);
-        mPreviewProduceQueue = new ArrayDeque<>(mMaxInFlight);
-        mActiveRequests = new TreeSet<>();
-        mIsEmpty = mLock.newCondition();
-        mNotFull = mLock.newCondition();
-        mPreviewsEmpty = mLock.newCondition();
-        mDeviceState = deviceState;
-    }
-
-    /**
-     * Queue a new request.
-     *
-     * <p>
-     * For requests that use the Camera1 API preview output stream, this will block if there are
-     * already {@code maxInFlight} requests in progress (until at least one prior request has
-     * completed). For requests that use the Camera1 API jpeg callbacks, this will block until
-     * all prior requests have been completed to avoid stopping preview for
-     * {@link android.hardware.Camera#takePicture} before prior preview requests have been
-     * completed.
-     * </p>
-     * @param holder the {@link RequestHolder} for this request.
-     * @param legacy the {@link LegacyRequest} for this request; this will not be mutated.
-     * @param timeout a timeout to use for this call.
-     * @param unit the units to use for the timeout.
-     * @return {@code false} if this method timed out.
-     * @throws InterruptedException if this thread is interrupted.
-     */
-    public boolean queueRequest(RequestHolder holder, LegacyRequest legacy, long timeout,
-                                TimeUnit unit)
-            throws InterruptedException {
-        CaptureHolder h = new CaptureHolder(holder, legacy);
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            if (DEBUG) {
-                Log.d(TAG, "queueRequest  for request " + holder.getRequestId() +
-                        " - " + mInFlight + " requests remain in flight.");
-            }
-
-            if (!(h.needsJpeg || h.needsPreview)) {
-                throw new IllegalStateException("Request must target at least one output surface!");
-            }
-
-            if (h.needsJpeg) {
-                // Wait for all current requests to finish before queueing jpeg.
-                while (mInFlight > 0) {
-                    if (nanos <= 0) {
-                        return false;
-                    }
-                    nanos = mIsEmpty.awaitNanos(nanos);
-                }
-                mJpegCaptureQueue.add(h);
-                mJpegProduceQueue.add(h);
-            }
-            if (h.needsPreview) {
-                while (mInFlight >= mMaxInFlight) {
-                    if (nanos <= 0) {
-                        return false;
-                    }
-                    nanos = mNotFull.awaitNanos(nanos);
-                }
-                mPreviewCaptureQueue.add(h);
-                mPreviewProduceQueue.add(h);
-                mInFlightPreviews++;
-            }
-            mActiveRequests.add(h);
-
-            mInFlight++;
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Wait all queued requests to complete.
-     *
-     * @param timeout a timeout to use for this call.
-     * @param unit the units to use for the timeout.
-     * @return {@code false} if this method timed out.
-     * @throws InterruptedException if this thread is interrupted.
-     */
-    public boolean waitForEmpty(long timeout, TimeUnit unit) throws InterruptedException {
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            while (mInFlight > 0) {
-                if (nanos <= 0) {
-                    return false;
-                }
-                nanos = mIsEmpty.awaitNanos(nanos);
-            }
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Wait all queued requests that use the Camera1 API preview output to complete.
-     *
-     * @param timeout a timeout to use for this call.
-     * @param unit the units to use for the timeout.
-     * @return {@code false} if this method timed out.
-     * @throws InterruptedException if this thread is interrupted.
-     */
-    public boolean waitForPreviewsEmpty(long timeout, TimeUnit unit) throws InterruptedException {
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            while (mInFlightPreviews > 0) {
-                if (nanos <= 0) {
-                    return false;
-                }
-                nanos = mPreviewsEmpty.awaitNanos(nanos);
-            }
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Wait for the specified request to be completed (all buffers available).
-     *
-     * <p>May not wait for the same request more than once, since a successful wait
-     * will erase the history of that request.</p>
-     *
-     * @param holder the {@link RequestHolder} for this request.
-     * @param timeout a timeout to use for this call.
-     * @param unit the units to use for the timeout.
-     * @param timestamp the timestamp of the request will be written out to here, in ns
-     *
-     * @return {@code false} if this method timed out.
-     *
-     * @throws InterruptedException if this thread is interrupted.
-     */
-    public boolean waitForRequestCompleted(RequestHolder holder, long timeout, TimeUnit unit,
-            MutableLong timestamp)
-            throws InterruptedException {
-        long nanos = unit.toNanos(timeout);
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            while (!removeRequestIfCompleted(holder, /*out*/timestamp)) {
-                if (nanos <= 0) {
-                    return false;
-                }
-                nanos = mNotFull.awaitNanos(nanos);
-            }
-            return true;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    private boolean removeRequestIfCompleted(RequestHolder holder, MutableLong timestamp) {
-        int i = 0;
-        for (CaptureHolder h : mCompletedRequests) {
-            if (h.mRequest.equals(holder)) {
-                timestamp.value = h.mTimestamp;
-                mCompletedRequests.remove(i);
-                return true;
-            }
-            i++;
-        }
-
-        return false;
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the jpeg capture has begun.
-     *
-     * @param timestamp the time of the jpeg capture.
-     * @return the {@link RequestHolder} for the request associated with this capture.
-     */
-    public RequestHolder jpegCaptured(long timestamp) {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h = mJpegCaptureQueue.poll();
-            if (h == null) {
-                Log.w(TAG, "jpegCaptured called with no jpeg request on queue!");
-                return null;
-            }
-            h.setJpegTimestamp(timestamp);
-            return h.mRequest;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the jpeg capture has completed.
-     *
-     * @return a pair containing the {@link RequestHolder} and the timestamp of the capture.
-     */
-    public Pair<RequestHolder, Long> jpegProduced() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h = mJpegProduceQueue.poll();
-            if (h == null) {
-                Log.w(TAG, "jpegProduced called with no jpeg request on queue!");
-                return null;
-            }
-            h.setJpegProduced();
-            return new Pair<>(h.mRequest, h.mTimestamp);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Check if there are any pending capture requests that use the Camera1 API preview output.
-     *
-     * @return {@code true} if there are pending preview requests.
-     */
-    public boolean hasPendingPreviewCaptures() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            return !mPreviewCaptureQueue.isEmpty();
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the preview capture has begun.
-     *
-     * @param timestamp the time of the preview capture.
-     * @return a pair containing the {@link RequestHolder} and the timestamp of the capture.
-     */
-    public Pair<RequestHolder, Long> previewCaptured(long timestamp) {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h = mPreviewCaptureQueue.poll();
-            if (h == null) {
-                if (DEBUG) {
-                    Log.d(TAG, "previewCaptured called with no preview request on queue!");
-                }
-                return null;
-            }
-            h.setPreviewTimestamp(timestamp);
-            return new Pair<>(h.mRequest, h.mTimestamp);
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the preview capture has completed.
-     *
-     * @return the {@link RequestHolder} for the request associated with this capture.
-     */
-    public RequestHolder previewProduced() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h = mPreviewProduceQueue.poll();
-            if (h == null) {
-                Log.w(TAG, "previewProduced called with no preview request on queue!");
-                return null;
-            }
-            h.setPreviewProduced();
-            return h.mRequest;
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the next pending preview capture has failed.
-     */
-    public void failNextPreview() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h1 = mPreviewCaptureQueue.peek();
-            CaptureHolder h2 = mPreviewProduceQueue.peek();
-
-            // Find the request with the lowest frame number.
-            CaptureHolder h = (h1 == null) ? h2 :
-                              ((h2 == null) ? h1 :
-                              ((h1.compareTo(h2) <= 0) ? h1 :
-                              h2));
-
-            if (h != null) {
-                mPreviewCaptureQueue.remove(h);
-                mPreviewProduceQueue.remove(h);
-                mActiveRequests.remove(h);
-                h.setPreviewFailed();
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} that the next pending jpeg capture has failed.
-     */
-    public void failNextJpeg() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h1 = mJpegCaptureQueue.peek();
-            CaptureHolder h2 = mJpegProduceQueue.peek();
-
-            // Find the request with the lowest frame number.
-            CaptureHolder h = (h1 == null) ? h2 :
-                              ((h2 == null) ? h1 :
-                              ((h1.compareTo(h2) <= 0) ? h1 :
-                              h2));
-
-            if (h != null) {
-                mJpegCaptureQueue.remove(h);
-                mJpegProduceQueue.remove(h);
-                mActiveRequests.remove(h);
-                h.setJpegFailed();
-            }
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Called to alert the {@link CaptureCollector} all pending captures have failed.
-     */
-    public void failAll() {
-        final ReentrantLock lock = this.mLock;
-        lock.lock();
-        try {
-            CaptureHolder h;
-            while ((h = mActiveRequests.pollFirst()) != null) {
-                h.setPreviewFailed();
-                h.setJpegFailed();
-            }
-            mPreviewCaptureQueue.clear();
-            mPreviewProduceQueue.clear();
-            mJpegCaptureQueue.clear();
-            mJpegProduceQueue.clear();
-        } finally {
-            lock.unlock();
-        }
-    }
-
-    private void onPreviewCompleted() {
-        mInFlightPreviews--;
-        if (mInFlightPreviews < 0) {
-            throw new IllegalStateException(
-                    "More preview captures completed than requests queued.");
-        }
-        if (mInFlightPreviews == 0) {
-            mPreviewsEmpty.signalAll();
-        }
-    }
-
-    private void onRequestCompleted(CaptureHolder capture) {
-        RequestHolder request = capture.mRequest;
-
-        mInFlight--;
-        if (DEBUG) {
-            Log.d(TAG, "Completed request " + request.getRequestId() +
-                    ", " + mInFlight + " requests remain in flight.");
-        }
-        if (mInFlight < 0) {
-            throw new IllegalStateException(
-                    "More captures completed than requests queued.");
-        }
-
-        mCompletedRequests.add(capture);
-        mActiveRequests.remove(capture);
-
-        mNotFull.signalAll();
-        if (mInFlight == 0) {
-            mIsEmpty.signalAll();
-        }
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/GLThreadManager.java b/core/java/android/hardware/camera2/legacy/GLThreadManager.java
deleted file mode 100644
index 152d82d..0000000
--- a/core/java/android/hardware/camera2/legacy/GLThreadManager.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-
-import java.util.Collection;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * GLThreadManager handles the thread used for rendering into the configured output surfaces.
- */
-public class GLThreadManager {
-    private final String TAG;
-    private static final boolean DEBUG = false;
-
-    private static final int MSG_NEW_CONFIGURATION = 1;
-    private static final int MSG_NEW_FRAME = 2;
-    private static final int MSG_CLEANUP = 3;
-    private static final int MSG_DROP_FRAMES = 4;
-    private static final int MSG_ALLOW_FRAMES = 5;
-
-    private CaptureCollector mCaptureCollector;
-
-    private final CameraDeviceState mDeviceState;
-
-    private final SurfaceTextureRenderer mTextureRenderer;
-
-    private final RequestHandlerThread mGLHandlerThread;
-
-    private final RequestThreadManager.FpsCounter mPrevCounter =
-            new RequestThreadManager.FpsCounter("GL Preview Producer");
-
-    /**
-     * Container object for Configure messages.
-     */
-    private static class ConfigureHolder {
-        public final ConditionVariable condition;
-        public final Collection<Pair<Surface, Size>> surfaces;
-        public final CaptureCollector collector;
-
-        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
-                Size>> surfaces, CaptureCollector collector) {
-            this.condition = condition;
-            this.surfaces = surfaces;
-            this.collector = collector;
-        }
-    }
-
-    private final Handler.Callback mGLHandlerCb = new Handler.Callback() {
-        private boolean mCleanup = false;
-        private boolean mConfigured = false;
-        private boolean mDroppingFrames = false;
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public boolean handleMessage(Message msg) {
-            if (mCleanup) {
-                return true;
-            }
-            try {
-                switch (msg.what) {
-                    case MSG_NEW_CONFIGURATION:
-                        ConfigureHolder configure = (ConfigureHolder) msg.obj;
-                        mTextureRenderer.cleanupEGLContext();
-                        mTextureRenderer.configureSurfaces(configure.surfaces);
-                        mCaptureCollector = checkNotNull(configure.collector);
-                        configure.condition.open();
-                        mConfigured = true;
-                        break;
-                    case MSG_NEW_FRAME:
-                        if (mDroppingFrames) {
-                            Log.w(TAG, "Ignoring frame.");
-                            break;
-                        }
-                        if (DEBUG) {
-                            mPrevCounter.countAndLog();
-                        }
-                        if (!mConfigured) {
-                            Log.e(TAG, "Dropping frame, EGL context not configured!");
-                        }
-                        mTextureRenderer.drawIntoSurfaces(mCaptureCollector);
-                        break;
-                    case MSG_CLEANUP:
-                        mTextureRenderer.cleanupEGLContext();
-                        mCleanup = true;
-                        mConfigured = false;
-                        break;
-                    case MSG_DROP_FRAMES:
-                        mDroppingFrames = true;
-                        break;
-                    case MSG_ALLOW_FRAMES:
-                        mDroppingFrames = false;
-                        break;
-                    case RequestHandlerThread.MSG_POKE_IDLE_HANDLER:
-                        // OK: Ignore message.
-                        break;
-                    default:
-                        Log.e(TAG, "Unhandled message " + msg.what + " on GLThread.");
-                        break;
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "Received exception on GL render thread: ", e);
-                mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-            }
-            return true;
-        }
-    };
-
-    /**
-     * Create a new GL thread and renderer.
-     *
-     * @param cameraId the camera id for this thread.
-     * @param facing direction the camera is facing.
-     * @param state {@link CameraDeviceState} to use for error handling.
-     */
-    public GLThreadManager(int cameraId, int facing, CameraDeviceState state) {
-        mTextureRenderer = new SurfaceTextureRenderer(facing);
-        TAG = String.format("CameraDeviceGLThread-%d", cameraId);
-        mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb);
-        mDeviceState = state;
-    }
-
-    /**
-     * Start the thread.
-     *
-     * <p>
-     * This must be called before queueing new frames.
-     * </p>
-     */
-    public void start() {
-        mGLHandlerThread.start();
-    }
-
-    /**
-     * Wait until the thread has started.
-     */
-    public void waitUntilStarted() {
-        mGLHandlerThread.waitUntilStarted();
-    }
-
-    /**
-     * Quit the thread.
-     *
-     * <p>
-     * No further methods can be called after this.
-     * </p>
-     */
-    public void quit() {
-        Handler handler = mGLHandlerThread.getHandler();
-        handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP));
-        mGLHandlerThread.quitSafely();
-        try {
-            mGLHandlerThread.join();
-        } catch (InterruptedException e) {
-            Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
-                    mGLHandlerThread.getName(), mGLHandlerThread.getId()));
-        }
-    }
-
-    /**
-     * Queue a new call to draw into the surfaces specified in the next available preview
-     * request from the {@link CaptureCollector} passed to
-     * {@link #setConfigurationAndWait(java.util.Collection, CaptureCollector)};
-     */
-    public void queueNewFrame() {
-        Handler handler = mGLHandlerThread.getHandler();
-
-        /**
-         * Avoid queuing more than one new frame.  If we are not consuming faster than frames
-         * are produced, drop frames rather than allowing the queue to back up.
-         */
-        if (!handler.hasMessages(MSG_NEW_FRAME)) {
-            handler.sendMessage(handler.obtainMessage(MSG_NEW_FRAME));
-        } else {
-            Log.e(TAG, "GLThread dropping frame.  Not consuming frames quickly enough!");
-        }
-    }
-
-    /**
-     * Configure the GL renderer for the given set of output surfaces, and block until
-     * this configuration has been applied.
-     *
-     * @param surfaces a collection of pairs of {@link android.view.Surface}s and their
-     *                 corresponding sizes to configure.
-     * @param collector a {@link CaptureCollector} to retrieve requests from.
-     */
-    public void setConfigurationAndWait(Collection<Pair<Surface, Size>> surfaces,
-                                        CaptureCollector collector) {
-        checkNotNull(collector, "collector must not be null");
-        Handler handler = mGLHandlerThread.getHandler();
-
-        final ConditionVariable condition = new ConditionVariable(/*closed*/false);
-        ConfigureHolder configure = new ConfigureHolder(condition, surfaces, collector);
-
-        Message m = handler.obtainMessage(MSG_NEW_CONFIGURATION, /*arg1*/0, /*arg2*/0, configure);
-        handler.sendMessage(m);
-
-        // Block until configuration applied.
-        condition.block();
-    }
-
-    /**
-     * Get the underlying surface to produce frames from.
-     *
-     * <p>
-     * This returns the surface that is drawn into the set of surfaces passed in for each frame.
-     * This method should only be called after a call to
-     * {@link #setConfigurationAndWait(java.util.Collection)}.  Calling this before the first call
-     * to {@link #setConfigurationAndWait(java.util.Collection)}, after {@link #quit()}, or
-     * concurrently to one of these calls may result in an invalid
-     * {@link android.graphics.SurfaceTexture} being returned.
-     * </p>
-     *
-     * @return an {@link android.graphics.SurfaceTexture} to draw to.
-     */
-    public SurfaceTexture getCurrentSurfaceTexture() {
-        return mTextureRenderer.getSurfaceTexture();
-    }
-
-    /**
-     * Ignore any subsequent calls to {@link #queueNewFrame(java.util.Collection)}.
-     */
-    public void ignoreNewFrames() {
-        mGLHandlerThread.getHandler().sendEmptyMessage(MSG_DROP_FRAMES);
-    }
-
-    /**
-     * Wait until no messages are queued.
-     */
-    public void waitUntilIdle() {
-        mGLHandlerThread.waitUntilIdle();
-    }
-
-    /**
-     * Re-enable drawing new frames after a call to {@link #ignoreNewFrames()}.
-     */
-    public void allowNewFrames() {
-        mGLHandlerThread.getHandler().sendEmptyMessage(MSG_ALLOW_FRAMES);
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
deleted file mode 100644
index fdd578c..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.ImageFormat;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.hardware.camera2.impl.CaptureResultExtras;
-import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
-import android.hardware.camera2.ICameraDeviceCallbacks;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.utils.ArrayUtils;
-import android.hardware.camera2.utils.SubmitInfo;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.RemoteException;
-import android.os.ServiceSpecificException;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.util.SparseArray;
-import android.view.Surface;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-import static android.hardware.camera2.legacy.LegacyExceptionUtils.*;
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * This class emulates the functionality of a Camera2 device using a the old Camera class.
- *
- * <p>
- * There are two main components that are used to implement this:
- * - A state machine containing valid Camera2 device states ({@link CameraDeviceState}).
- * - A message-queue based pipeline that manages an old Camera class, and executes capture and
- *   configuration requests.
- * </p>
- */
-public class LegacyCameraDevice implements AutoCloseable {
-    private final String TAG;
-
-    private static final boolean DEBUG = false;
-    private final int mCameraId;
-    private final CameraCharacteristics mStaticCharacteristics;
-    private final ICameraDeviceCallbacks mDeviceCallbacks;
-    private final CameraDeviceState mDeviceState = new CameraDeviceState();
-    private SparseArray<Surface> mConfiguredSurfaces;
-    private boolean mClosed = false;
-
-    private final ConditionVariable mIdle = new ConditionVariable(/*open*/true);
-
-    private final HandlerThread mResultThread = new HandlerThread("ResultThread");
-    private final HandlerThread mCallbackHandlerThread = new HandlerThread("CallbackThread");
-    private final Handler mCallbackHandler;
-    private final Handler mResultHandler;
-    private static final int ILLEGAL_VALUE = -1;
-
-    // Keep up to date with values in hardware/libhardware/include/hardware/gralloc.h
-    private static final int GRALLOC_USAGE_RENDERSCRIPT = 0x00100000;
-    private static final int GRALLOC_USAGE_SW_READ_OFTEN = 0x00000003;
-    private static final int GRALLOC_USAGE_HW_TEXTURE = 0x00000100;
-    private static final int GRALLOC_USAGE_HW_COMPOSER = 0x00000800;
-    private static final int GRALLOC_USAGE_HW_RENDER = 0x00000200;
-    private static final int GRALLOC_USAGE_HW_VIDEO_ENCODER = 0x00010000;
-
-    public static final int MAX_DIMEN_FOR_ROUNDING = 1920; // maximum allowed width for rounding
-
-    // Keep up to date with values in system/core/include/system/window.h
-    public static final int NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1;
-
-    private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) {
-        return getExtrasFromRequest(holder,
-                /*errorCode*/CameraDeviceState.NO_CAPTURE_ERROR, /*errorArg*/null);
-    }
-
-    private CaptureResultExtras getExtrasFromRequest(RequestHolder holder,
-            int errorCode, Object errorArg) {
-        int errorStreamId = -1;
-        if (errorCode == CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER) {
-            Surface errorTarget = (Surface) errorArg;
-            int indexOfTarget = mConfiguredSurfaces.indexOfValue(errorTarget);
-            if (indexOfTarget < 0) {
-                Log.e(TAG, "Buffer drop error reported for unknown Surface");
-            } else {
-                errorStreamId = mConfiguredSurfaces.keyAt(indexOfTarget);
-            }
-        }
-        if (holder == null) {
-            return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE,
-                    ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, null,
-                    ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE);
-        }
-        return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(),
-                /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(),
-                /*partialResultCount*/1, errorStreamId, null, holder.getFrameNumber(), -1, -1);
-    }
-
-    /**
-     * Listener for the camera device state machine.  Calls the appropriate
-     * {@link ICameraDeviceCallbacks} for each state transition.
-     */
-    private final CameraDeviceState.CameraDeviceStateListener mStateListener =
-            new CameraDeviceState.CameraDeviceStateListener() {
-        @Override
-        public void onError(final int errorCode, final Object errorArg, final RequestHolder holder) {
-            if (DEBUG) {
-                Log.d(TAG, "onError called, errorCode = " + errorCode + ", errorArg = " + errorArg);
-            }
-            switch (errorCode) {
-                /*
-                 * Only be considered idle if we hit a fatal error
-                 * and no further requests can be processed.
-                 */
-                case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DISCONNECTED:
-                case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_SERVICE:
-                case CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE: {
-                    mIdle.open();
-
-                    if (DEBUG) {
-                        Log.d(TAG, "onError - opening idle");
-                    }
-                }
-            }
-
-            final CaptureResultExtras extras = getExtrasFromRequest(holder, errorCode, errorArg);
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onError callback for request " + holder.getRequestId() +
-                                ", with error code " + errorCode);
-                    }
-                    try {
-                        mDeviceCallbacks.onDeviceError(errorCode, extras);
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onCameraError callback: ", e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onConfiguring() {
-            // Do nothing
-            if (DEBUG) {
-                Log.d(TAG, "doing onConfiguring callback.");
-            }
-        }
-
-        @Override
-        public void onIdle() {
-            if (DEBUG) {
-                Log.d(TAG, "onIdle called");
-            }
-
-            mIdle.open();
-
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onIdle callback.");
-                    }
-                    try {
-                        mDeviceCallbacks.onDeviceIdle();
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onCameraIdle callback: ", e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onBusy() {
-            mIdle.close();
-
-            if (DEBUG) {
-                Log.d(TAG, "onBusy called");
-            }
-        }
-
-        @Override
-        public void onCaptureStarted(final RequestHolder holder, final long timestamp) {
-            final CaptureResultExtras extras = getExtrasFromRequest(holder);
-
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onCaptureStarted callback for request " +
-                                holder.getRequestId());
-                    }
-                    try {
-                        mDeviceCallbacks.onCaptureStarted(extras, timestamp);
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onCameraError callback: ", e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRequestQueueEmpty() {
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onRequestQueueEmpty callback");
-                    }
-                    try {
-                        mDeviceCallbacks.onRequestQueueEmpty();
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onRequestQueueEmpty callback: ",
-                                e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onCaptureResult(final CameraMetadataNative result, final RequestHolder holder) {
-            final CaptureResultExtras extras = getExtrasFromRequest(holder);
-
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onCaptureResult callback for request " +
-                                holder.getRequestId());
-                    }
-                    try {
-                        mDeviceCallbacks.onResultReceived(result, extras,
-                                new PhysicalCaptureResultInfo[0]);
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onCameraError callback: ", e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRepeatingRequestError(final long lastFrameNumber,
-                final int repeatingRequestId) {
-            mResultHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    if (DEBUG) {
-                        Log.d(TAG, "doing onRepeatingRequestError callback.");
-                    }
-                    try {
-                        mDeviceCallbacks.onRepeatingRequestError(lastFrameNumber,
-                                repeatingRequestId);
-                    } catch (RemoteException e) {
-                        throw new IllegalStateException(
-                                "Received remote exception during onRepeatingRequestError " +
-                                "callback: ", e);
-                    }
-                }
-            });
-        }
-    };
-
-    private final RequestThreadManager mRequestThreadManager;
-
-    /**
-     * Check if a given surface uses {@link ImageFormat#YUV_420_888} or format that can be readily
-     * converted to this; YV12 and NV21 are the two currently supported formats.
-     *
-     * @param s the surface to check.
-     * @return {@code true} if the surfaces uses {@link ImageFormat#YUV_420_888} or a compatible
-     *          format.
-     */
-    static boolean needsConversion(Surface s) throws BufferQueueAbandonedException {
-        int nativeType = detectSurfaceType(s);
-        return nativeType == ImageFormat.YUV_420_888 || nativeType == ImageFormat.YV12 ||
-                nativeType == ImageFormat.NV21;
-    }
-
-    /**
-     * Create a new emulated camera device from a given Camera 1 API camera.
-     *
-     * <p>
-     * The {@link Camera} provided to this constructor must already have been successfully opened,
-     * and ownership of the provided camera is passed to this object.  No further calls to the
-     * camera methods should be made following this constructor.
-     * </p>
-     *
-     * @param cameraId the id of the camera.
-     * @param camera an open {@link Camera} device.
-     * @param characteristics the static camera characteristics for this camera device
-     * @param callbacks {@link ICameraDeviceCallbacks} callbacks to call for Camera2 API operations.
-     */
-    public LegacyCameraDevice(int cameraId, Camera camera, CameraCharacteristics characteristics,
-            ICameraDeviceCallbacks callbacks) {
-        mCameraId = cameraId;
-        mDeviceCallbacks = callbacks;
-        TAG = String.format("CameraDevice-%d-LE", mCameraId);
-
-        mResultThread.start();
-        mResultHandler = new Handler(mResultThread.getLooper());
-        mCallbackHandlerThread.start();
-        mCallbackHandler = new Handler(mCallbackHandlerThread.getLooper());
-        mDeviceState.setCameraDeviceCallbacks(mCallbackHandler, mStateListener);
-        mStaticCharacteristics = characteristics;
-        mRequestThreadManager =
-                new RequestThreadManager(cameraId, camera, characteristics, mDeviceState);
-        mRequestThreadManager.start();
-    }
-
-    /**
-     * Configure the device with a set of output surfaces.
-     *
-     * <p>Using empty or {@code null} {@code outputs} is the same as unconfiguring.</p>
-     *
-     * <p>Every surface in {@code outputs} must be non-{@code null}.</p>
-     *
-     * @param outputs a list of surfaces to set. LegacyCameraDevice will take ownership of this
-     *          list; it must not be modified by the caller once it's passed in.
-     * @return an error code for this binder operation, or {@link NO_ERROR}
-     *          on success.
-     */
-    public int configureOutputs(SparseArray<Surface> outputs) {
-        return configureOutputs(outputs, /*validateSurfacesOnly*/false);
-    }
-
-    /**
-     * Configure the device with a set of output surfaces.
-     *
-     * <p>Using empty or {@code null} {@code outputs} is the same as unconfiguring.</p>
-     *
-     * <p>Every surface in {@code outputs} must be non-{@code null}.</p>
-     *
-     * @param outputs a list of surfaces to set. LegacyCameraDevice will take ownership of this
-     *          list; it must not be modified by the caller once it's passed in.
-     * @param validateSurfacesOnly If set it will only check whether the outputs are supported
-     *                             and avoid any device configuration.
-     * @return an error code for this binder operation, or {@link NO_ERROR}
-     *          on success.
-     * @hide
-     */
-    public int configureOutputs(SparseArray<Surface> outputs, boolean validateSurfacesOnly) {
-        List<Pair<Surface, Size>> sizedSurfaces = new ArrayList<>();
-        if (outputs != null) {
-            int count = outputs.size();
-            for (int i = 0; i < count; i++)  {
-                Surface output = outputs.valueAt(i);
-                if (output == null) {
-                    Log.e(TAG, "configureOutputs - null outputs are not allowed");
-                    return BAD_VALUE;
-                }
-                if (!output.isValid()) {
-                    Log.e(TAG, "configureOutputs - invalid output surfaces are not allowed");
-                    return BAD_VALUE;
-                }
-                StreamConfigurationMap streamConfigurations = mStaticCharacteristics.
-                        get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-
-                // Validate surface size and format.
-                try {
-                    Size s = getSurfaceSize(output);
-                    int surfaceType = detectSurfaceType(output);
-
-                    boolean flexibleConsumer = isFlexibleConsumer(output);
-
-                    Size[] sizes = streamConfigurations.getOutputSizes(surfaceType);
-                    if (sizes == null) {
-                        if (surfaceType == ImageFormat.PRIVATE) {
-
-                            // YUV_420_888 is always present in LEGACY for all
-                            // IMPLEMENTATION_DEFINED output sizes, and is publicly visible in the
-                            // API (i.e. {@code #getOutputSizes} works here).
-                            sizes = streamConfigurations.getOutputSizes(ImageFormat.YUV_420_888);
-                        } else if (surfaceType == LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB) {
-                            sizes = streamConfigurations.getOutputSizes(ImageFormat.JPEG);
-                        }
-                    }
-
-                    if (!ArrayUtils.contains(sizes, s)) {
-                        if (flexibleConsumer && (s = findClosestSize(s, sizes)) != null) {
-                            sizedSurfaces.add(new Pair<>(output, s));
-                        } else {
-                            String reason = (sizes == null) ? "format is invalid." :
-                                    ("size not in valid set: " + Arrays.toString(sizes));
-                            Log.e(TAG, String.format("Surface with size (w=%d, h=%d) and format " +
-                                    "0x%x is not valid, %s", s.getWidth(), s.getHeight(),
-                                    surfaceType, reason));
-                            return BAD_VALUE;
-                        }
-                    } else {
-                        sizedSurfaces.add(new Pair<>(output, s));
-                    }
-                    // Lock down the size before configuration
-                    if (!validateSurfacesOnly) {
-                        setSurfaceDimens(output, s.getWidth(), s.getHeight());
-                    }
-                } catch (BufferQueueAbandonedException e) {
-                    Log.e(TAG, "Surface bufferqueue is abandoned, cannot configure as output: ", e);
-                    return BAD_VALUE;
-                }
-
-            }
-        }
-
-        if (validateSurfacesOnly) {
-            return LegacyExceptionUtils.NO_ERROR;
-        }
-
-        boolean success = false;
-        if (mDeviceState.setConfiguring()) {
-            mRequestThreadManager.configure(sizedSurfaces);
-            success = mDeviceState.setIdle();
-        }
-
-        if (success) {
-            mConfiguredSurfaces = outputs;
-        } else {
-            return LegacyExceptionUtils.INVALID_OPERATION;
-        }
-        return LegacyExceptionUtils.NO_ERROR;
-    }
-
-    /**
-     * Submit a burst of capture requests.
-     *
-     * @param requestList a list of capture requests to execute.
-     * @param repeating {@code true} if this burst is repeating.
-     * @return the submission info, including the new request id, and the last frame number, which
-     *   contains either the frame number of the last frame that will be returned for this request,
-     *   or the frame number of the last frame that will be returned for the current repeating
-     *   request if this burst is set to be repeating.
-     */
-    public SubmitInfo submitRequestList(CaptureRequest[] requestList, boolean repeating) {
-        if (requestList == null || requestList.length == 0) {
-            Log.e(TAG, "submitRequestList - Empty/null requests are not allowed");
-            throw new ServiceSpecificException(BAD_VALUE,
-                    "submitRequestList - Empty/null requests are not allowed");
-        }
-
-        List<Long> surfaceIds;
-
-        try {
-            surfaceIds = (mConfiguredSurfaces == null) ? new ArrayList<Long>() :
-                    getSurfaceIds(mConfiguredSurfaces);
-        } catch (BufferQueueAbandonedException e) {
-            throw new ServiceSpecificException(BAD_VALUE,
-                    "submitRequestList - configured surface is abandoned.");
-        }
-
-        // Make sure that there all requests have at least 1 surface; all surfaces are non-null
-        for (CaptureRequest request : requestList) {
-            if (request.getTargets().isEmpty()) {
-                Log.e(TAG, "submitRequestList - "
-                        + "Each request must have at least one Surface target");
-                throw new ServiceSpecificException(BAD_VALUE,
-                        "submitRequestList - "
-                        + "Each request must have at least one Surface target");
-            }
-
-            for (Surface surface : request.getTargets()) {
-                if (surface == null) {
-                    Log.e(TAG, "submitRequestList - Null Surface targets are not allowed");
-                    throw new ServiceSpecificException(BAD_VALUE,
-                            "submitRequestList - Null Surface targets are not allowed");
-                } else if (mConfiguredSurfaces == null) {
-                    Log.e(TAG, "submitRequestList - must configure " +
-                            " device with valid surfaces before submitting requests");
-                    throw new ServiceSpecificException(INVALID_OPERATION,
-                            "submitRequestList - must configure " +
-                            " device with valid surfaces before submitting requests");
-                } else if (!containsSurfaceId(surface, surfaceIds)) {
-                    Log.e(TAG, "submitRequestList - cannot use a surface that wasn't configured");
-                    throw new ServiceSpecificException(BAD_VALUE,
-                            "submitRequestList - cannot use a surface that wasn't configured");
-                }
-            }
-        }
-
-        // TODO: further validation of request here
-        mIdle.close();
-        return mRequestThreadManager.submitCaptureRequests(requestList, repeating);
-    }
-
-    /**
-     * Submit a single capture request.
-     *
-     * @param request the capture request to execute.
-     * @param repeating {@code true} if this request is repeating.
-     * @return the submission info, including the new request id, and the last frame number, which
-     *   contains either the frame number of the last frame that will be returned for this request,
-     *   or the frame number of the last frame that will be returned for the current repeating
-     *   request if this burst is set to be repeating.
-     */
-    public SubmitInfo submitRequest(CaptureRequest request, boolean repeating) {
-        CaptureRequest[] requestList = { request };
-        return submitRequestList(requestList, repeating);
-    }
-
-    /**
-     * Cancel the repeating request with the given request id.
-     *
-     * @param requestId the request id of the request to cancel.
-     * @return the last frame number to be returned from the HAL for the given repeating request, or
-     *          {@code INVALID_FRAME} if none exists.
-     */
-    public long cancelRequest(int requestId) {
-        return mRequestThreadManager.cancelRepeating(requestId);
-    }
-
-    /**
-     * Block until the {@link ICameraDeviceCallbacks#onCameraIdle()} callback is received.
-     */
-    public void waitUntilIdle()  {
-        mIdle.block();
-    }
-
-    /**
-     * Flush any pending requests.
-     *
-     * @return the last frame number.
-     */
-    public long flush() {
-        long lastFrame = mRequestThreadManager.flush();
-        waitUntilIdle();
-        return lastFrame;
-    }
-
-    public void setAudioRestriction(int mode) {
-        mRequestThreadManager.setAudioRestriction(mode);
-    }
-
-    public int getAudioRestriction() {
-        return mRequestThreadManager.getAudioRestriction();
-    }
-
-    /**
-     * Return {@code true} if the device has been closed.
-     */
-    public boolean isClosed() {
-        return mClosed;
-    }
-
-    @Override
-    public void close() {
-        mRequestThreadManager.quit();
-        mCallbackHandlerThread.quitSafely();
-        mResultThread.quitSafely();
-
-        try {
-            mCallbackHandlerThread.join();
-        } catch (InterruptedException e) {
-            Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
-                    mCallbackHandlerThread.getName(), mCallbackHandlerThread.getId()));
-        }
-
-        try {
-            mResultThread.join();
-        } catch (InterruptedException e) {
-            Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
-                    mResultThread.getName(), mResultThread.getId()));
-        }
-
-        mClosed = true;
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } catch (ServiceSpecificException e) {
-            Log.e(TAG, "Got error while trying to finalize, ignoring: " + e.getMessage());
-        } finally {
-            super.finalize();
-        }
-    }
-
-    static long findEuclidDistSquare(Size a, Size b) {
-        long d0 = a.getWidth() - b.getWidth();
-        long d1 = a.getHeight() - b.getHeight();
-        return d0 * d0 + d1 * d1;
-    }
-
-    // Keep up to date with rounding behavior in
-    // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
-    static Size findClosestSize(Size size, Size[] supportedSizes) {
-        if (size == null || supportedSizes == null) {
-            return null;
-        }
-        Size bestSize = null;
-        for (Size s : supportedSizes) {
-            if (s.equals(size)) {
-                return size;
-            } else if (s.getWidth() <= MAX_DIMEN_FOR_ROUNDING && (bestSize == null ||
-                    LegacyCameraDevice.findEuclidDistSquare(size, s) <
-                    LegacyCameraDevice.findEuclidDistSquare(bestSize, s))) {
-                bestSize = s;
-            }
-        }
-        return bestSize;
-    }
-
-    /**
-     * Query the surface for its currently configured default buffer size.
-     * @param surface a non-{@code null} {@code Surface}
-     * @return the width and height of the surface
-     *
-     * @throws NullPointerException if the {@code surface} was {@code null}
-     * @throws BufferQueueAbandonedException if the {@code surface} was invalid
-     */
-    public static Size getSurfaceSize(Surface surface) throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-
-        int[] dimens = new int[2];
-        LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDimens(surface, /*out*/dimens));
-
-        return new Size(dimens[0], dimens[1]);
-    }
-
-    public static boolean isFlexibleConsumer(Surface output) {
-        int usageFlags = detectSurfaceUsageFlags(output);
-
-        // Keep up to date with allowed consumer types in
-        // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
-        int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT;
-        int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN |
-            GRALLOC_USAGE_HW_COMPOSER;
-        boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0 &&
-                (usageFlags & allowedFlags) != 0);
-        return flexibleConsumer;
-    }
-
-    public static boolean isPreviewConsumer(Surface output) {
-        int usageFlags = detectSurfaceUsageFlags(output);
-        int disallowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_RENDERSCRIPT |
-                GRALLOC_USAGE_SW_READ_OFTEN;
-        int allowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER |
-                GRALLOC_USAGE_HW_RENDER;
-        boolean previewConsumer = ((usageFlags & disallowedFlags) == 0 &&
-                (usageFlags & allowedFlags) != 0);
-        int surfaceFormat = ImageFormat.UNKNOWN;
-        try {
-            surfaceFormat = detectSurfaceType(output);
-        } catch(BufferQueueAbandonedException e) {
-            throw new IllegalArgumentException("Surface was abandoned", e);
-        }
-
-        return previewConsumer;
-    }
-
-    public static boolean isVideoEncoderConsumer(Surface output) {
-        int usageFlags = detectSurfaceUsageFlags(output);
-        int disallowedFlags = GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER |
-                GRALLOC_USAGE_RENDERSCRIPT | GRALLOC_USAGE_SW_READ_OFTEN;
-        int allowedFlags = GRALLOC_USAGE_HW_VIDEO_ENCODER;
-        boolean videoEncoderConsumer = ((usageFlags & disallowedFlags) == 0 &&
-                (usageFlags & allowedFlags) != 0);
-
-        int surfaceFormat = ImageFormat.UNKNOWN;
-        try {
-            surfaceFormat = detectSurfaceType(output);
-        } catch(BufferQueueAbandonedException e) {
-            throw new IllegalArgumentException("Surface was abandoned", e);
-        }
-
-        return videoEncoderConsumer;
-    }
-
-    /**
-     * Query the surface for its currently configured usage flags
-     */
-    static int detectSurfaceUsageFlags(Surface surface) {
-        checkNotNull(surface);
-        return nativeDetectSurfaceUsageFlags(surface);
-    }
-
-    /**
-     * Query the surface for its currently configured format
-     */
-    public static int detectSurfaceType(Surface surface) throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        int surfaceType = nativeDetectSurfaceType(surface);
-
-        // TODO: remove this override since the default format should be
-        // ImageFormat.PRIVATE. b/9487482
-        if ((surfaceType >= LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888 &&
-                surfaceType <= LegacyMetadataMapper.HAL_PIXEL_FORMAT_BGRA_8888)) {
-            surfaceType = ImageFormat.PRIVATE;
-        }
-
-        return LegacyExceptionUtils.throwOnError(surfaceType);
-    }
-
-    /**
-     * Query the surface for its currently configured dataspace
-     */
-    public static int detectSurfaceDataspace(Surface surface) throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        return LegacyExceptionUtils.throwOnError(nativeDetectSurfaceDataspace(surface));
-    }
-
-    static void connectSurface(Surface surface) throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-
-        LegacyExceptionUtils.throwOnError(nativeConnectSurface(surface));
-    }
-
-    static void disconnectSurface(Surface surface) throws BufferQueueAbandonedException {
-        if (surface == null) return;
-
-        LegacyExceptionUtils.throwOnError(nativeDisconnectSurface(surface));
-    }
-
-    static void produceFrame(Surface surface, byte[] pixelBuffer, int width,
-                             int height, int pixelFormat)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        checkNotNull(pixelBuffer);
-        checkArgumentPositive(width, "width must be positive.");
-        checkArgumentPositive(height, "height must be positive.");
-
-        LegacyExceptionUtils.throwOnError(nativeProduceFrame(surface, pixelBuffer, width, height,
-                pixelFormat));
-    }
-
-    static void setSurfaceFormat(Surface surface, int pixelFormat)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-
-        LegacyExceptionUtils.throwOnError(nativeSetSurfaceFormat(surface, pixelFormat));
-    }
-
-    static void setSurfaceDimens(Surface surface, int width, int height)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        checkArgumentPositive(width, "width must be positive.");
-        checkArgumentPositive(height, "height must be positive.");
-
-        LegacyExceptionUtils.throwOnError(nativeSetSurfaceDimens(surface, width, height));
-    }
-
-    public static long getSurfaceId(Surface surface) throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        try {
-            return nativeGetSurfaceId(surface);
-        } catch (IllegalArgumentException e) {
-            throw new BufferQueueAbandonedException();
-        }
-    }
-
-    static List<Long> getSurfaceIds(SparseArray<Surface> surfaces)
-            throws BufferQueueAbandonedException {
-        if (surfaces == null) {
-            throw new NullPointerException("Null argument surfaces");
-        }
-        List<Long> surfaceIds = new ArrayList<>();
-        int count = surfaces.size();
-        for (int i = 0; i < count; i++) {
-            long id = getSurfaceId(surfaces.valueAt(i));
-            if (id == 0) {
-                throw new IllegalStateException(
-                        "Configured surface had null native GraphicBufferProducer pointer!");
-            }
-            surfaceIds.add(id);
-        }
-        return surfaceIds;
-    }
-
-    static List<Long> getSurfaceIds(Collection<Surface> surfaces)
-            throws BufferQueueAbandonedException {
-        if (surfaces == null) {
-            throw new NullPointerException("Null argument surfaces");
-        }
-        List<Long> surfaceIds = new ArrayList<>();
-        for (Surface s : surfaces) {
-            long id = getSurfaceId(s);
-            if (id == 0) {
-                throw new IllegalStateException(
-                        "Configured surface had null native GraphicBufferProducer pointer!");
-            }
-            surfaceIds.add(id);
-        }
-        return surfaceIds;
-    }
-
-    static boolean containsSurfaceId(Surface s, Collection<Long> ids) {
-        long id = 0;
-        try {
-            id = getSurfaceId(s);
-        } catch (BufferQueueAbandonedException e) {
-            // If surface is abandoned, return false.
-            return false;
-        }
-        return ids.contains(id);
-    }
-
-    static void setSurfaceOrientation(Surface surface, int facing, int sensorOrientation)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        LegacyExceptionUtils.throwOnError(nativeSetSurfaceOrientation(surface, facing,
-                sensorOrientation));
-    }
-
-    static Size getTextureSize(SurfaceTexture surfaceTexture)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surfaceTexture);
-
-        int[] dimens = new int[2];
-        LegacyExceptionUtils.throwOnError(nativeDetectTextureDimens(surfaceTexture,
-                /*out*/dimens));
-
-        return new Size(dimens[0], dimens[1]);
-    }
-
-    static void setNextTimestamp(Surface surface, long timestamp)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        LegacyExceptionUtils.throwOnError(nativeSetNextTimestamp(surface, timestamp));
-    }
-
-    static void setScalingMode(Surface surface, int mode)
-            throws BufferQueueAbandonedException {
-        checkNotNull(surface);
-        LegacyExceptionUtils.throwOnError(nativeSetScalingMode(surface, mode));
-    }
-
-
-    private static native int nativeDetectSurfaceType(Surface surface);
-
-    private static native int nativeDetectSurfaceDataspace(Surface surface);
-
-    private static native int nativeDetectSurfaceDimens(Surface surface,
-            /*out*/int[/*2*/] dimens);
-
-    private static native int nativeConnectSurface(Surface surface);
-
-    private static native int nativeProduceFrame(Surface surface, byte[] pixelBuffer, int width,
-                                                    int height, int pixelFormat);
-
-    private static native int nativeSetSurfaceFormat(Surface surface, int pixelFormat);
-
-    private static native int nativeSetSurfaceDimens(Surface surface, int width, int height);
-
-    private static native long nativeGetSurfaceId(Surface surface);
-
-    private static native int nativeSetSurfaceOrientation(Surface surface, int facing,
-                                                             int sensorOrientation);
-
-    private static native int nativeDetectTextureDimens(SurfaceTexture surfaceTexture,
-            /*out*/int[/*2*/] dimens);
-
-    private static native int nativeSetNextTimestamp(Surface surface, long timestamp);
-
-    private static native int nativeDetectSurfaceUsageFlags(Surface surface);
-
-    private static native int nativeSetScalingMode(Surface surface, int scalingMode);
-
-    private static native int nativeDisconnectSurface(Surface surface);
-
-    static native int nativeGetJpegFooterSize();
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java b/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
deleted file mode 100644
index 55130c8..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyExceptionUtils.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.ICameraService;
-import android.os.ServiceSpecificException;
-import android.util.AndroidException;
-
-import static android.system.OsConstants.*;
-
-/**
- * Utility class containing exception handling used solely by the compatibility mode shim.
- */
-public class LegacyExceptionUtils {
-    private static final String TAG = "LegacyExceptionUtils";
-
-    public static final int NO_ERROR = 0;
-    public static final int PERMISSION_DENIED = -EPERM;
-    public static final int ALREADY_EXISTS = -EEXIST;
-    public static final int BAD_VALUE = -EINVAL;
-    public static final int DEAD_OBJECT = -ENOSYS;
-    public static final int INVALID_OPERATION = -EPIPE;
-    public static final int TIMED_OUT = -ETIMEDOUT;
-
-    /**
-     * Checked exception thrown when a BufferQueue has been abandoned by its consumer.
-     */
-    public static class BufferQueueAbandonedException extends AndroidException {
-        public BufferQueueAbandonedException () {}
-
-        public BufferQueueAbandonedException(String name) {
-            super(name);
-        }
-
-        public BufferQueueAbandonedException(String name, Throwable cause) {
-            super(name, cause);
-        }
-
-        public BufferQueueAbandonedException(Exception cause) {
-            super(cause);
-        }
-    }
-
-    /**
-     * Throw error codes used by legacy device methods as exceptions.
-     *
-     * <p>Non-negative return values are passed through, negative return values are thrown as
-     * exceptions.</p>
-     *
-     * @param errorFlag error to throw as an exception.
-     * @throws {@link BufferQueueAbandonedException} for BAD_VALUE.
-     * @throws {@link UnsupportedOperationException} for an unknown negative error code.
-     * @return {@code errorFlag} if the value was non-negative, throws otherwise.
-     */
-    public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
-        if (errorFlag == NO_ERROR) {
-            return NO_ERROR;
-        } else if (errorFlag == BAD_VALUE) {
-            throw new BufferQueueAbandonedException();
-        }
-
-        if (errorFlag < 0) {
-            throw new UnsupportedOperationException("Unknown error " + errorFlag);
-        }
-        return errorFlag;
-    }
-
-    /**
-     * Throw error codes returned by the camera service as exceptions.
-     *
-     * @param errorFlag error to throw as an exception.
-     */
-    public static void throwOnServiceError(int errorFlag) {
-        int errorCode = ICameraService.ERROR_INVALID_OPERATION;
-        String errorMsg;
-
-        if (errorFlag >= NO_ERROR) {
-            return;
-        } else if (errorFlag == PERMISSION_DENIED) {
-            errorCode = ICameraService.ERROR_PERMISSION_DENIED;
-            errorMsg = "Lacking privileges to access camera service";
-        } else if (errorFlag == ALREADY_EXISTS) {
-            // This should be handled at the call site. Typically this isn't bad,
-            // just means we tried to do an operation that already completed.
-            return;
-        } else if (errorFlag == BAD_VALUE) {
-            errorCode = ICameraService.ERROR_ILLEGAL_ARGUMENT;
-            errorMsg = "Bad argument passed to camera service";
-        } else if (errorFlag == DEAD_OBJECT) {
-            errorCode = ICameraService.ERROR_DISCONNECTED;
-            errorMsg = "Camera service not available";
-        } else if (errorFlag == TIMED_OUT) {
-            errorCode = ICameraService.ERROR_INVALID_OPERATION;
-            errorMsg = "Operation timed out in camera service";
-        } else if (errorFlag == -EACCES) {
-            errorCode = ICameraService.ERROR_DISABLED;
-            errorMsg = "Camera disabled by policy";
-        } else if (errorFlag == -EBUSY) {
-            errorCode = ICameraService.ERROR_CAMERA_IN_USE;
-            errorMsg = "Camera already in use";
-        } else if (errorFlag == -EUSERS) {
-            errorCode = ICameraService.ERROR_MAX_CAMERAS_IN_USE;
-            errorMsg = "Maximum number of cameras in use";
-        } else if (errorFlag == -ENODEV) {
-            errorCode = ICameraService.ERROR_DISCONNECTED;
-            errorMsg = "Camera device not available";
-        } else if (errorFlag == -EOPNOTSUPP) {
-            errorCode = ICameraService.ERROR_DEPRECATED_HAL;
-            errorMsg = "Deprecated camera HAL does not support this";
-        } else if (errorFlag == INVALID_OPERATION) {
-            errorCode = ICameraService.ERROR_INVALID_OPERATION;
-            errorMsg = "Illegal state encountered in camera service.";
-        } else {
-            errorCode = ICameraService.ERROR_INVALID_OPERATION;
-            errorMsg = "Unknown camera device error " + errorFlag;
-        }
-
-        throw new ServiceSpecificException(errorCode, errorMsg);
-    }
-
-    private LegacyExceptionUtils() {
-        throw new AssertionError();
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java
deleted file mode 100644
index b3b4549..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyFaceDetectMapper.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.FaceDetectionListener;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.legacy.ParameterUtils.ZoomData;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.Face;
-import android.hardware.camera2.utils.ListUtils;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.util.Log;
-import android.util.Size;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.hardware.camera2.CaptureRequest.*;
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Map legacy face detect callbacks into face detection results.
- */
-@SuppressWarnings("deprecation")
-public class LegacyFaceDetectMapper {
-    private static String TAG = "LegacyFaceDetectMapper";
-    private static final boolean DEBUG = false;
-
-    private final Camera mCamera;
-    /** Is the camera capable of face detection? */
-    private final boolean mFaceDetectSupported;
-    /** Is the camera is running face detection? */
-    private boolean mFaceDetectEnabled = false;
-    /** Did the last request say to use SCENE_MODE = FACE_PRIORITY? */
-    private boolean mFaceDetectScenePriority = false;
-    /** Did the last request enable the face detect mode to ON? */
-    private boolean mFaceDetectReporting = false;
-
-    /** Synchronize access to all fields */
-    private final Object mLock = new Object();
-    private Camera.Face[] mFaces;
-    private Camera.Face[] mFacesPrev;
-    /**
-     * Instantiate a new face detect mapper.
-     *
-     * @param camera a non-{@code null} camera1 device
-     * @param characteristics a  non-{@code null} camera characteristics for that camera1
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     */
-    public LegacyFaceDetectMapper(Camera camera, CameraCharacteristics characteristics) {
-        mCamera = checkNotNull(camera, "camera must not be null");
-        checkNotNull(characteristics, "characteristics must not be null");
-
-        mFaceDetectSupported = ArrayUtils.contains(
-                characteristics.get(
-                        CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES),
-                STATISTICS_FACE_DETECT_MODE_SIMPLE);
-
-        if (!mFaceDetectSupported) {
-            return;
-        }
-
-       mCamera.setFaceDetectionListener(new FaceDetectionListener() {
-
-        @Override
-        public void onFaceDetection(Camera.Face[] faces, Camera camera) {
-            int lengthFaces = faces == null ? 0 : faces.length;
-            synchronized (mLock) {
-                if (mFaceDetectEnabled) {
-                    mFaces = faces;
-                } else if (lengthFaces > 0) {
-                    // stopFaceDetectMode could race against the requests, print a debug log
-                    Log.d(TAG,
-                            "onFaceDetection - Ignored some incoming faces since" +
-                            "face detection was disabled");
-                }
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "onFaceDetection - read " + lengthFaces + " faces");
-            }
-        }
-       });
-    }
-
-    /**
-     * Process the face detect mode from the capture request into an api1 face detect toggle.
-     *
-     * <p>This method should be called after the parameters are {@link LegacyRequestMapper mapped}
-     * with the request.</p>
-     *
-     * <p>Callbacks are processed in the background, and the next call to {@link #mapResultTriggers}
-     * will have the latest faces detected as reflected by the camera1 callbacks.</p>
-     *
-     * <p>None of the arguments will be mutated.</p>
-     *
-     * @param captureRequest a non-{@code null} request
-     * @param parameters a non-{@code null} parameters corresponding to this request (read-only)
-     */
-    public void processFaceDetectMode(CaptureRequest captureRequest,
-            Camera.Parameters parameters) {
-        checkNotNull(captureRequest, "captureRequest must not be null");
-
-        /*
-         * statistics.faceDetectMode
-         */
-        int fdMode = ParamsUtils.getOrDefault(captureRequest, STATISTICS_FACE_DETECT_MODE,
-                STATISTICS_FACE_DETECT_MODE_OFF);
-
-        if (fdMode != STATISTICS_FACE_DETECT_MODE_OFF && !mFaceDetectSupported) {
-            Log.w(TAG,
-                    "processFaceDetectMode - Ignoring statistics.faceDetectMode; " +
-                    "face detection is not available");
-            return;
-        }
-
-        /*
-         * control.sceneMode
-         */
-        int sceneMode = ParamsUtils.getOrDefault(captureRequest, CONTROL_SCENE_MODE,
-                CONTROL_SCENE_MODE_DISABLED);
-        if (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY && !mFaceDetectSupported) {
-            Log.w(TAG, "processFaceDetectMode - ignoring control.sceneMode == FACE_PRIORITY; " +
-                    "face detection is not available");
-            return;
-        }
-
-        // Print some warnings out in case the values were wrong
-        switch (fdMode) {
-            case STATISTICS_FACE_DETECT_MODE_OFF:
-            case STATISTICS_FACE_DETECT_MODE_SIMPLE:
-                break;
-            case STATISTICS_FACE_DETECT_MODE_FULL:
-                Log.w(TAG,
-                        "processFaceDetectMode - statistics.faceDetectMode == FULL unsupported, " +
-                        "downgrading to SIMPLE");
-                break;
-            default:
-                Log.w(TAG, "processFaceDetectMode - ignoring unknown statistics.faceDetectMode = "
-                        + fdMode);
-                return;
-        }
-
-        boolean enableFaceDetect = (fdMode != STATISTICS_FACE_DETECT_MODE_OFF)
-                || (sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY);
-        synchronized (mLock) {
-            // Enable/disable face detection if it's changed since last time
-            if (enableFaceDetect != mFaceDetectEnabled) {
-                if (enableFaceDetect) {
-                    mCamera.startFaceDetection();
-
-                    if (DEBUG) {
-                        Log.v(TAG, "processFaceDetectMode - start face detection");
-                    }
-                } else {
-                    mCamera.stopFaceDetection();
-
-                    if (DEBUG) {
-                        Log.v(TAG, "processFaceDetectMode - stop face detection");
-                    }
-
-                    mFaces = null;
-                }
-
-                mFaceDetectEnabled = enableFaceDetect;
-                mFaceDetectScenePriority = sceneMode == CONTROL_SCENE_MODE_FACE_PRIORITY;
-                mFaceDetectReporting = fdMode != STATISTICS_FACE_DETECT_MODE_OFF;
-            }
-        }
-    }
-
-    /**
-     * Update the {@code result} camera metadata map with the new value for the
-     * {@code statistics.faces} and {@code statistics.faceDetectMode}.
-     *
-     * <p>Face detect callbacks are processed in the background, and each call to
-     * {@link #mapResultFaces} will have the latest faces as reflected by the camera1 callbacks.</p>
-     *
-     * <p>If the scene mode was set to {@code FACE_PRIORITY} but face detection is disabled,
-     * the camera will still run face detection in the background, but no faces will be reported
-     * in the capture result.</p>
-     *
-     * @param result a non-{@code null} result
-     * @param legacyRequest a non-{@code null} request (read-only)
-     */
-    public void mapResultFaces(CameraMetadataNative result, LegacyRequest legacyRequest) {
-        checkNotNull(result, "result must not be null");
-        checkNotNull(legacyRequest, "legacyRequest must not be null");
-
-        Camera.Face[] faces, previousFaces;
-        int fdMode;
-        boolean fdScenePriority;
-        synchronized (mLock) {
-            fdMode = mFaceDetectReporting ?
-                            STATISTICS_FACE_DETECT_MODE_SIMPLE : STATISTICS_FACE_DETECT_MODE_OFF;
-
-            if (mFaceDetectReporting) {
-                faces = mFaces;
-            } else {
-                faces = null;
-            }
-
-            fdScenePriority = mFaceDetectScenePriority;
-
-            previousFaces = mFacesPrev;
-            mFacesPrev = faces;
-        }
-
-        CameraCharacteristics characteristics = legacyRequest.characteristics;
-        CaptureRequest request = legacyRequest.captureRequest;
-        Size previewSize = legacyRequest.previewSize;
-        Camera.Parameters params = legacyRequest.parameters;
-
-        Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-        ZoomData zoomData = ParameterUtils.convertToLegacyZoom(activeArray,
-                request.get(CaptureRequest.SCALER_CROP_REGION),
-                request.get(CaptureRequest.CONTROL_ZOOM_RATIO),
-                previewSize, params);
-
-        List<Face> convertedFaces = new ArrayList<>();
-        if (faces != null) {
-            for (Camera.Face face : faces) {
-                if (face != null) {
-                    convertedFaces.add(
-                            ParameterUtils.convertFaceFromLegacy(face, activeArray, zoomData));
-                } else {
-                    Log.w(TAG, "mapResultFaces - read NULL face from camera1 device");
-                }
-            }
-        }
-
-        if (DEBUG && previousFaces != faces) { // Log only in verbose and IF the faces changed
-            Log.v(TAG, "mapResultFaces - changed to " + ListUtils.listToString(convertedFaces));
-        }
-
-        result.set(CaptureResult.STATISTICS_FACES, convertedFaces.toArray(new Face[0]));
-        result.set(CaptureResult.STATISTICS_FACE_DETECT_MODE, fdMode);
-
-        // Override scene mode with FACE_PRIORITY if the request was using FACE_PRIORITY
-        if (fdScenePriority) {
-            result.set(CaptureResult.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_FACE_PRIORITY);
-        }
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java b/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java
deleted file mode 100644
index d33c09e..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyFocusStateMapper.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.util.Log;
-
-import java.util.Objects;
-
-import static android.hardware.camera2.CaptureRequest.*;
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Map capture request data into legacy focus state transitions.
- *
- * <p>This object will asynchronously process auto-focus changes, so no interaction
- * with it is necessary beyond reading the current state and updating with the latest trigger.</p>
- */
-@SuppressWarnings("deprecation")
-public class LegacyFocusStateMapper {
-    private static String TAG = "LegacyFocusStateMapper";
-    private static final boolean DEBUG = false;
-
-    private final Camera mCamera;
-
-    private int mAfStatePrevious = CONTROL_AF_STATE_INACTIVE;
-    private String mAfModePrevious = null;
-
-    /** Guard mAfRun and mAfState */
-    private final Object mLock = new Object();
-    /** Guard access with mLock */
-    private int mAfRun = 0;
-    /** Guard access with mLock */
-    private int mAfState = CONTROL_AF_STATE_INACTIVE;
-
-    /**
-     * Instantiate a new focus state mapper.
-     *
-     * @param camera a non-{@code null} camera1 device
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     */
-    public LegacyFocusStateMapper(Camera camera) {
-        mCamera = checkNotNull(camera, "camera must not be null");
-    }
-
-    /**
-     * Process the AF triggers from the request as a camera1 autofocus routine.
-     *
-     * <p>This method should be called after the parameters are {@link LegacyRequestMapper mapped}
-     * with the request.</p>
-     *
-     * <p>Callbacks are processed in the background, and the next call to {@link #mapResultTriggers}
-     * will have the latest AF state as reflected by the camera1 callbacks.</p>
-     *
-     * <p>None of the arguments will be mutated.</p>
-     *
-     * @param captureRequest a non-{@code null} request
-     * @param parameters a non-{@code null} parameters corresponding to this request (read-only)
-     */
-    public void processRequestTriggers(CaptureRequest captureRequest,
-            Camera.Parameters parameters) {
-        checkNotNull(captureRequest, "captureRequest must not be null");
-
-        /*
-         * control.afTrigger
-         */
-        int afTrigger = ParamsUtils.getOrDefault(captureRequest, CONTROL_AF_TRIGGER,
-                CONTROL_AF_TRIGGER_IDLE);
-
-        final String afMode = parameters.getFocusMode();
-
-        if (!Objects.equals(mAfModePrevious, afMode)) {
-            if (DEBUG) {
-                Log.v(TAG, "processRequestTriggers - AF mode switched from " + mAfModePrevious +
-                        " to " + afMode);
-            }
-
-            // Switching modes always goes back to INACTIVE; ignore callbacks from previous modes
-
-            synchronized (mLock) {
-                ++mAfRun;
-                mAfState = CONTROL_AF_STATE_INACTIVE;
-            }
-            mCamera.cancelAutoFocus();
-        }
-
-        mAfModePrevious = afMode;
-
-        // Passive AF Scanning
-        {
-            final int currentAfRun;
-
-            synchronized (mLock) {
-                currentAfRun = mAfRun;
-            }
-
-            Camera.AutoFocusMoveCallback afMoveCallback = new Camera.AutoFocusMoveCallback() {
-                @Override
-                public void onAutoFocusMoving(boolean start, Camera camera) {
-                    synchronized (mLock) {
-                        int latestAfRun = mAfRun;
-
-                        if (DEBUG) {
-                            Log.v(TAG,
-                                    "onAutoFocusMoving - start " + start + " latest AF run " +
-                                            latestAfRun + ", last AF run " + currentAfRun
-                            );
-                        }
-
-                        if (currentAfRun != latestAfRun) {
-                            Log.d(TAG,
-                                    "onAutoFocusMoving - ignoring move callbacks from old af run"
-                                            + currentAfRun
-                            );
-                            return;
-                        }
-
-                        int newAfState = start ?
-                                CONTROL_AF_STATE_PASSIVE_SCAN :
-                                CONTROL_AF_STATE_PASSIVE_FOCUSED;
-                        // We never send CONTROL_AF_STATE_PASSIVE_UNFOCUSED
-
-                        switch (afMode) {
-                            case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
-                            case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
-                                break;
-                            // This callback should never be sent in any other AF mode
-                            default:
-                                Log.w(TAG, "onAutoFocus - got unexpected onAutoFocus in mode "
-                                        + afMode);
-
-                        }
-
-                        mAfState = newAfState;
-                    }
-                }
-            };
-
-            // Only set move callback if we can call autofocus.
-            switch (afMode) {
-                case Parameters.FOCUS_MODE_AUTO:
-                case Parameters.FOCUS_MODE_MACRO:
-                case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
-                case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
-                    mCamera.setAutoFocusMoveCallback(afMoveCallback);
-            }
-        }
-
-
-        // AF Locking
-        switch (afTrigger) {
-            case CONTROL_AF_TRIGGER_START:
-
-                int afStateAfterStart;
-                switch (afMode) {
-                    case Parameters.FOCUS_MODE_AUTO:
-                    case Parameters.FOCUS_MODE_MACRO:
-                        afStateAfterStart = CONTROL_AF_STATE_ACTIVE_SCAN;
-                        break;
-                    case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
-                    case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
-                        afStateAfterStart = CONTROL_AF_STATE_PASSIVE_SCAN;
-                        break;
-                    default:
-                        // EDOF, INFINITY
-                        afStateAfterStart = CONTROL_AF_STATE_INACTIVE;
-                }
-
-                final int currentAfRun;
-                synchronized (mLock) {
-                    currentAfRun = ++mAfRun;
-                    mAfState = afStateAfterStart;
-                }
-
-                if (DEBUG) {
-                    Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_START, " +
-                            "new AF run is " + currentAfRun);
-                }
-
-                // Avoid calling autofocus unless we are in a state that supports calling this.
-                if (afStateAfterStart == CONTROL_AF_STATE_INACTIVE) {
-                    break;
-                }
-
-                mCamera.autoFocus(new Camera.AutoFocusCallback() {
-                    @Override
-                    public void onAutoFocus(boolean success, Camera camera) {
-                        synchronized (mLock) {
-                            int latestAfRun = mAfRun;
-
-                            if (DEBUG) {
-                                Log.v(TAG, "onAutoFocus - success " + success + " latest AF run " +
-                                        latestAfRun + ", last AF run " + currentAfRun);
-                            }
-
-                            // Ignore old auto-focus results, since another trigger was requested
-                            if (latestAfRun != currentAfRun) {
-                                Log.d(TAG, String.format("onAutoFocus - ignoring AF callback " +
-                                        "(old run %d, new run %d)", currentAfRun, latestAfRun));
-
-                                return;
-                            }
-
-                            int newAfState = success ?
-                                    CONTROL_AF_STATE_FOCUSED_LOCKED :
-                                    CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
-
-                            switch (afMode) {
-                                case Parameters.FOCUS_MODE_AUTO:
-                                case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
-                                case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
-                                case Parameters.FOCUS_MODE_MACRO:
-                                    break;
-                                // This callback should never be sent in any other AF mode
-                                default:
-                                    Log.w(TAG, "onAutoFocus - got unexpected onAutoFocus in mode "
-                                            + afMode);
-
-                            }
-
-                            mAfState = newAfState;
-                        }
-                    }
-                });
-
-                break;
-            case CONTROL_AF_TRIGGER_CANCEL:
-                synchronized (mLock) {
-                    int updatedAfRun;
-
-                    synchronized (mLock) {
-                        updatedAfRun = ++mAfRun;
-                        mAfState = CONTROL_AF_STATE_INACTIVE;
-                    }
-
-                    mCamera.cancelAutoFocus();
-
-                    if (DEBUG) {
-                        Log.v(TAG, "processRequestTriggers - got AF_TRIGGER_CANCEL, " +
-                                "new AF run is " + updatedAfRun);
-                    }
-                }
-
-                break;
-            case CONTROL_AF_TRIGGER_IDLE:
-                // No action necessary. The callbacks will handle transitions.
-                break;
-            default:
-                Log.w(TAG, "processRequestTriggers - ignoring unknown control.afTrigger = "
-                        + afTrigger);
-        }
-    }
-
-    /**
-     * Update the {@code result} camera metadata map with the new value for the
-     * {@code control.afState}.
-     *
-     * <p>AF callbacks are processed in the background, and each call to {@link #mapResultTriggers}
-     * will have the latest AF state as reflected by the camera1 callbacks.</p>
-     *
-     * @param result a non-{@code null} result
-     */
-    public void mapResultTriggers(CameraMetadataNative result) {
-        checkNotNull(result, "result must not be null");
-
-        int newAfState;
-        synchronized (mLock) {
-            newAfState = mAfState;
-        }
-
-        if (DEBUG && newAfState != mAfStatePrevious) {
-            Log.v(TAG, String.format("mapResultTriggers - afState changed from %s to %s",
-                    afStateToString(mAfStatePrevious), afStateToString(newAfState)));
-        }
-
-        result.set(CaptureResult.CONTROL_AF_STATE, newAfState);
-
-        mAfStatePrevious = newAfState;
-    }
-
-    private static String afStateToString(int afState) {
-        switch (afState) {
-            case CONTROL_AF_STATE_ACTIVE_SCAN:
-                return "ACTIVE_SCAN";
-            case CONTROL_AF_STATE_FOCUSED_LOCKED:
-                return "FOCUSED_LOCKED";
-            case CONTROL_AF_STATE_INACTIVE:
-                return "INACTIVE";
-            case CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
-                return "NOT_FOCUSED_LOCKED";
-            case CONTROL_AF_STATE_PASSIVE_FOCUSED:
-                return "PASSIVE_FOCUSED";
-            case CONTROL_AF_STATE_PASSIVE_SCAN:
-                return "PASSIVE_SCAN";
-            case CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
-                return "PASSIVE_UNFOCUSED";
-            default :
-                return "UNKNOWN(" + afState + ")";
-        }
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
deleted file mode 100644
index 362ddfa..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ /dev/null
@@ -1,1532 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.ImageFormat;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Parameters;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.params.StreamConfiguration;
-import android.hardware.camera2.params.StreamConfigurationDuration;
-import android.hardware.camera2.utils.ArrayUtils;
-import android.hardware.camera2.utils.ListUtils;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.util.Log;
-import android.util.Range;
-import android.util.Size;
-import android.util.SizeF;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static com.android.internal.util.Preconditions.*;
-import static android.hardware.camera2.CameraCharacteristics.*;
-import static android.hardware.camera2.legacy.ParameterUtils.*;
-
-/**
- * Provide legacy-specific implementations of camera2 metadata for legacy devices, such as the
- * camera characteristics.
- */
-@SuppressWarnings("deprecation")
-public class LegacyMetadataMapper {
-    private static final String TAG = "LegacyMetadataMapper";
-    private static final boolean DEBUG = false;
-
-    private static final long NS_PER_MS = 1000000;
-
-    // from graphics.h
-    public static final int HAL_PIXEL_FORMAT_RGBA_8888 = PixelFormat.RGBA_8888;
-    public static final int HAL_PIXEL_FORMAT_BGRA_8888 = 0x5;
-    public static final int HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED = 0x22;
-    public static final int HAL_PIXEL_FORMAT_BLOB = 0x21;
-
-    // for metadata
-    private static final float LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS = 0.0f;
-
-    private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_RAW = 0; // no raw support
-    private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC = 3; // preview, video, cb
-    private static final int REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC_STALL = 1; // 1 jpeg only
-    private static final int REQUEST_MAX_NUM_INPUT_STREAMS_COUNT = 0; // no reprocessing
-
-    /** Assume 3 HAL1 stages: Exposure, Read-out, Post-Processing */
-    private static final int REQUEST_PIPELINE_MAX_DEPTH_HAL1 = 3;
-    /** Assume 3 shim stages: Preview input, Split output, Format conversion for output */
-    private static final int REQUEST_PIPELINE_MAX_DEPTH_OURS = 3;
-    /* TODO: Update above maxDepth values once we do more performance measurements */
-
-    // For approximating JPEG stall durations
-    private static final long APPROXIMATE_CAPTURE_DELAY_MS = 200; // 200 milliseconds
-    private static final long APPROXIMATE_SENSOR_AREA_PX = (1 << 23); // 8 megapixels
-    private static final long APPROXIMATE_JPEG_ENCODE_TIME_MS = 600; // 600 milliseconds
-
-    static final int UNKNOWN_MODE = -1;
-
-    // Maximum difference between a preview size aspect ratio and a jpeg size aspect ratio
-    private static final float PREVIEW_ASPECT_RATIO_TOLERANCE = 0.01f;
-
-    /*
-     * Development hijinks: Lie about not supporting certain capabilities
-     *
-     * - Unblock some CTS tests from running whose main intent is not the metadata itself
-     *
-     * TODO: Remove these constants and strip out any code that previously relied on them
-     * being set to true.
-     */
-    static final boolean LIE_ABOUT_AE_STATE = false;
-    static final boolean LIE_ABOUT_AE_MAX_REGIONS = false;
-    static final boolean LIE_ABOUT_AF = false;
-    static final boolean LIE_ABOUT_AF_MAX_REGIONS = false;
-    static final boolean LIE_ABOUT_AWB_STATE = false;
-    static final boolean LIE_ABOUT_AWB = false;
-
-
-    /**
-     * Create characteristics for a legacy device by mapping the {@code parameters}
-     * and {@code info}
-     *
-     * @param parameters A non-{@code null} parameters set
-     * @param info Camera info with camera facing direction and angle of orientation
-     * @param cameraId Current camera Id
-     * @param displaySize Device display size
-     *
-     * @return static camera characteristics for a camera device
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     */
-    public static CameraCharacteristics createCharacteristics(Camera.Parameters parameters,
-            CameraInfo info, int cameraId, Size displaySize) {
-        checkNotNull(parameters, "parameters must not be null");
-        checkNotNull(info, "info must not be null");
-
-        String paramStr = parameters.flatten();
-        android.hardware.CameraInfo outerInfo = new android.hardware.CameraInfo();
-        outerInfo.info = info;
-
-        return createCharacteristics(paramStr, outerInfo, cameraId, displaySize);
-    }
-
-    /**
-     * Create characteristics for a legacy device by mapping the {@code parameters}
-     * and {@code info}
-     *
-     * @param parameters A string parseable by {@link Camera.Parameters#unflatten}
-     * @param info Camera info with camera facing direction and angle of orientation
-     * @param cameraId Current camera id
-     * @param displaySize Device display size
-     * @return static camera characteristics for a camera device
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     */
-    public static CameraCharacteristics createCharacteristics(String parameters,
-            android.hardware.CameraInfo info, int cameraId, Size displaySize) {
-        checkNotNull(parameters, "parameters must not be null");
-        checkNotNull(info, "info must not be null");
-        checkNotNull(info.info, "info.info must not be null");
-
-        CameraMetadataNative m = new CameraMetadataNative();
-
-        mapCharacteristicsFromInfo(m, info.info);
-
-        Camera.Parameters params = Camera.getEmptyParameters();
-        params.unflatten(parameters);
-        mapCharacteristicsFromParameters(m, params);
-
-        if (DEBUG) {
-            Log.v(TAG, "createCharacteristics metadata:");
-            Log.v(TAG, "--------------------------------------------------- (start)");
-            m.dumpToLog();
-            Log.v(TAG, "--------------------------------------------------- (end)");
-        }
-
-        m.setCameraId(cameraId);
-        m.setDisplaySize(displaySize);
-
-        return new CameraCharacteristics(m);
-    }
-
-    private static void mapCharacteristicsFromInfo(CameraMetadataNative m, CameraInfo i) {
-        m.set(LENS_FACING, i.facing == CameraInfo.CAMERA_FACING_BACK ?
-                LENS_FACING_BACK : LENS_FACING_FRONT);
-        m.set(SENSOR_ORIENTATION, i.orientation);
-    }
-
-    private static void mapCharacteristicsFromParameters(CameraMetadataNative m,
-            Camera.Parameters p) {
-
-        /*
-         * colorCorrection.*
-         */
-        m.set(COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
-                new int[] { COLOR_CORRECTION_ABERRATION_MODE_FAST,
-                            COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY });
-        /*
-         * control.ae*
-         */
-        mapControlAe(m, p);
-        /*
-         * control.af*
-         */
-        mapControlAf(m, p);
-        /*
-         * control.awb*
-         */
-        mapControlAwb(m, p);
-        /*
-         * control.*
-         * - Anything that doesn't have a set of related fields
-         */
-        mapControlOther(m, p);
-        /*
-         * lens.*
-         */
-        mapLens(m, p);
-        /*
-         * flash.*
-         */
-        mapFlash(m, p);
-        /*
-         * jpeg.*
-         */
-        mapJpeg(m, p);
-
-        /*
-         * noiseReduction.*
-         */
-        m.set(NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
-                new int[] { NOISE_REDUCTION_MODE_FAST,
-                            NOISE_REDUCTION_MODE_HIGH_QUALITY});
-
-        /*
-         * scaler.*
-         */
-        mapScaler(m, p);
-
-        /*
-         * sensor.*
-         */
-        mapSensor(m, p);
-
-        /*
-         * statistics.*
-         */
-        mapStatistics(m, p);
-
-        /*
-         * sync.*
-         */
-        mapSync(m, p);
-
-        /*
-         * info.supportedHardwareLevel
-         */
-        m.set(INFO_SUPPORTED_HARDWARE_LEVEL, INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY);
-
-        /*
-         * scaler.availableStream*, scaler.available*Durations, sensor.info.maxFrameDuration
-         */
-        mapScalerStreamConfigs(m, p);
-
-        // Order matters below: Put this last so that we can read the metadata set previously
-
-        /*
-         * request.*
-         */
-        mapRequest(m, p);
-
-    }
-
-    private static void mapScalerStreamConfigs(CameraMetadataNative m, Camera.Parameters p) {
-
-        ArrayList<StreamConfiguration> availableStreamConfigs = new ArrayList<>();
-        /*
-         * Implementation-defined (preview, recording, etc) -> use camera1 preview sizes
-         * YUV_420_888 cpu callbacks -> use camera1 preview sizes
-         * Other preview callbacks (CPU) -> use camera1 preview sizes
-         * JPEG still capture -> use camera1 still capture sizes
-         *
-         * Use platform-internal format constants here, since StreamConfigurationMap does the
-         * remapping to public format constants.
-         */
-        List<Camera.Size> previewSizes = p.getSupportedPreviewSizes();
-        List<Camera.Size> jpegSizes = p.getSupportedPictureSizes();
-        /*
-         * Work-around for b/17589233:
-         * - Some HALs's largest preview size aspect ratio does not match the largest JPEG size AR
-         * - This causes a large amount of problems with focus/metering because it's relative to
-         *   preview, making the difference between the JPEG and preview viewport inaccessible
-         * - This boils down to metering or focusing areas being "arbitrarily" cropped
-         *   in the capture result.
-         * - Work-around the HAL limitations by removing all of the largest preview sizes
-         *   until we get one with the same aspect ratio as the jpeg size.
-         */
-        {
-            SizeAreaComparator areaComparator = new SizeAreaComparator();
-
-            // Sort preview to min->max
-            Collections.sort(previewSizes, areaComparator);
-
-            Camera.Size maxJpegSize = SizeAreaComparator.findLargestByArea(jpegSizes);
-            float jpegAspectRatio = maxJpegSize.width * 1.0f / maxJpegSize.height;
-
-            if (DEBUG) {
-                Log.v(TAG, String.format("mapScalerStreamConfigs - largest JPEG area %dx%d, AR=%f",
-                        maxJpegSize.width, maxJpegSize.height, jpegAspectRatio));
-            }
-
-            // Now remove preview sizes from the end (largest->smallest) until aspect ratio matches
-            while (!previewSizes.isEmpty()) {
-                int index = previewSizes.size() - 1; // max is always at the end
-                Camera.Size size = previewSizes.get(index);
-
-                float previewAspectRatio = size.width * 1.0f / size.height;
-
-                if (Math.abs(jpegAspectRatio - previewAspectRatio) >=
-                        PREVIEW_ASPECT_RATIO_TOLERANCE) {
-                    previewSizes.remove(index); // Assume removing from end is O(1)
-
-                    if (DEBUG) {
-                        Log.v(TAG, String.format(
-                                "mapScalerStreamConfigs - removed preview size %dx%d, AR=%f "
-                                        + "was not the same",
-                                size.width, size.height, previewAspectRatio));
-                    }
-                } else {
-                    break;
-                }
-            }
-
-            if (previewSizes.isEmpty()) {
-                // Fall-back to the original faulty behavior, but at least work
-                Log.w(TAG, "mapScalerStreamConfigs - failed to find any preview size matching " +
-                        "JPEG aspect ratio " + jpegAspectRatio);
-                previewSizes = p.getSupportedPreviewSizes();
-            }
-
-            // Sort again, this time in descending order max->min
-            Collections.sort(previewSizes, Collections.reverseOrder(areaComparator));
-        }
-
-        appendStreamConfig(availableStreamConfigs,
-                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, previewSizes);
-        appendStreamConfig(availableStreamConfigs,
-                ImageFormat.YUV_420_888, previewSizes);
-        for (int format : p.getSupportedPreviewFormats()) {
-            if (ImageFormat.isPublicFormat(format) && format != ImageFormat.NV21) {
-                appendStreamConfig(availableStreamConfigs, format, previewSizes);
-            } else if (DEBUG) {
-                /*
-                 *  Do not add any formats unknown to us
-                 * (since it would fail runtime checks in StreamConfigurationMap)
-                 */
-                Log.v(TAG,
-                        String.format("mapStreamConfigs - Skipping format %x", format));
-            }
-        }
-
-        appendStreamConfig(availableStreamConfigs,
-                HAL_PIXEL_FORMAT_BLOB, p.getSupportedPictureSizes());
-        /*
-         * scaler.availableStreamConfigurations
-         */
-        m.set(SCALER_AVAILABLE_STREAM_CONFIGURATIONS,
-                availableStreamConfigs.toArray(new StreamConfiguration[0]));
-
-        /*
-         * scaler.availableMinFrameDurations
-         */
-        // No frame durations available
-        m.set(SCALER_AVAILABLE_MIN_FRAME_DURATIONS, new StreamConfigurationDuration[0]);
-
-        StreamConfigurationDuration[] jpegStalls =
-                new StreamConfigurationDuration[jpegSizes.size()];
-        int i = 0;
-        long longestStallDuration = -1;
-        for (Camera.Size s : jpegSizes) {
-            long stallDuration =  calculateJpegStallDuration(s);
-            jpegStalls[i++] = new StreamConfigurationDuration(HAL_PIXEL_FORMAT_BLOB, s.width,
-                    s.height, stallDuration);
-            if (longestStallDuration < stallDuration) {
-                longestStallDuration = stallDuration;
-            }
-        }
-        /*
-         * scaler.availableStallDurations
-         */
-        // Set stall durations for jpeg, other formats use default stall duration
-        m.set(SCALER_AVAILABLE_STALL_DURATIONS, jpegStalls);
-
-        /*
-         * sensor.info.maxFrameDuration
-         */
-        m.set(SENSOR_INFO_MAX_FRAME_DURATION, longestStallDuration);
-    }
-
-    @SuppressWarnings({"unchecked"})
-    private static void mapControlAe(CameraMetadataNative m, Camera.Parameters p) {
-        /*
-         * control.aeAvailableAntiBandingModes
-         */
-        List<String> antiBandingModes = p.getSupportedAntibanding();
-        if (antiBandingModes != null && antiBandingModes.size() > 0) { // antibanding is optional
-            int[] modes = new int[antiBandingModes.size()];
-            int j = 0;
-            for (String mode : antiBandingModes) {
-                int convertedMode = convertAntiBandingMode(mode);
-                if (DEBUG && convertedMode == -1) {
-                    Log.v(TAG, "Antibanding mode " + ((mode == null) ? "NULL" : mode) +
-                            " not supported, skipping...");
-                } else {
-                    modes[j++] = convertedMode;
-                }
-            }
-            m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, Arrays.copyOf(modes, j));
-        } else {
-            m.set(CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, new int[0]);
-        }
-
-        /*
-         * control.aeAvailableTargetFpsRanges
-         */
-        {
-            List<int[]> fpsRanges = p.getSupportedPreviewFpsRange();
-            if (fpsRanges == null) {
-                throw new AssertionError("Supported FPS ranges cannot be null.");
-            }
-            int rangesSize = fpsRanges.size();
-            if (rangesSize <= 0) {
-                throw new AssertionError("At least one FPS range must be supported.");
-            }
-            Range<Integer>[] ranges = new Range[rangesSize];
-            int i = 0;
-            for (int[] r : fpsRanges) {
-                ranges[i++] = Range.create(
-                        (int) Math.floor(r[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.0),
-                        (int) Math.ceil(r[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.0));
-            }
-            m.set(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, ranges);
-        }
-
-        /*
-         * control.aeAvailableModes
-         */
-        {
-            List<String> flashModes = p.getSupportedFlashModes();
-
-            String[] flashModeStrings = new String[] {
-                    Camera.Parameters.FLASH_MODE_OFF,
-                    Camera.Parameters.FLASH_MODE_AUTO,
-                    Camera.Parameters.FLASH_MODE_ON,
-                    Camera.Parameters.FLASH_MODE_RED_EYE,
-                    // Map these manually
-                    Camera.Parameters.FLASH_MODE_TORCH,
-            };
-            int[] flashModeInts = new int[] {
-                    CONTROL_AE_MODE_ON,
-                    CONTROL_AE_MODE_ON_AUTO_FLASH,
-                    CONTROL_AE_MODE_ON_ALWAYS_FLASH,
-                    CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE
-            };
-            int[] aeAvail = ArrayUtils.convertStringListToIntArray(
-                    flashModes, flashModeStrings, flashModeInts);
-
-            // No flash control -> AE is always on
-            if (aeAvail == null || aeAvail.length == 0) {
-                aeAvail = new int[] {
-                        CONTROL_AE_MODE_ON
-                };
-            }
-
-            // Note that AE_MODE_OFF is never available.
-            m.set(CONTROL_AE_AVAILABLE_MODES, aeAvail);
-        }
-
-        /*
-         * control.aeCompensationRanges
-         */
-        {
-            int min = p.getMinExposureCompensation();
-            int max = p.getMaxExposureCompensation();
-
-            m.set(CONTROL_AE_COMPENSATION_RANGE, Range.create(min, max));
-        }
-
-        /*
-         * control.aeCompensationStep
-         */
-        {
-            float step = p.getExposureCompensationStep();
-
-            m.set(CONTROL_AE_COMPENSATION_STEP, ParamsUtils.createRational(step));
-        }
-
-        /*
-         * control.aeLockAvailable
-         */
-        {
-            boolean aeLockAvailable = p.isAutoExposureLockSupported();
-
-            m.set(CONTROL_AE_LOCK_AVAILABLE, aeLockAvailable);
-        }
-    }
-
-
-    @SuppressWarnings({"unchecked"})
-    private static void mapControlAf(CameraMetadataNative m, Camera.Parameters p) {
-        /*
-         * control.afAvailableModes
-         */
-        {
-            List<String> focusModes = p.getSupportedFocusModes();
-
-            String[] focusModeStrings = new String[] {
-                    Camera.Parameters.FOCUS_MODE_AUTO,
-                    Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
-                    Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO,
-                    Camera.Parameters.FOCUS_MODE_EDOF,
-                    Camera.Parameters.FOCUS_MODE_INFINITY,
-                    Camera.Parameters.FOCUS_MODE_MACRO,
-                    Camera.Parameters.FOCUS_MODE_FIXED,
-            };
-
-            int[] focusModeInts = new int[] {
-                    CONTROL_AF_MODE_AUTO,
-                    CONTROL_AF_MODE_CONTINUOUS_PICTURE,
-                    CONTROL_AF_MODE_CONTINUOUS_VIDEO,
-                    CONTROL_AF_MODE_EDOF,
-                    CONTROL_AF_MODE_OFF,
-                    CONTROL_AF_MODE_MACRO,
-                    CONTROL_AF_MODE_OFF
-            };
-
-            List<Integer> afAvail = ArrayUtils.convertStringListToIntList(
-                    focusModes, focusModeStrings, focusModeInts);
-
-            // No AF modes supported? That's unpossible!
-            if (afAvail == null || afAvail.size() == 0) {
-                Log.w(TAG, "No AF modes supported (HAL bug); defaulting to AF_MODE_OFF only");
-                afAvail = new ArrayList<Integer>(/*capacity*/1);
-                afAvail.add(CONTROL_AF_MODE_OFF);
-            }
-
-            m.set(CONTROL_AF_AVAILABLE_MODES, ArrayUtils.toIntArray(afAvail));
-
-            if (DEBUG) {
-                Log.v(TAG, "mapControlAf - control.afAvailableModes set to " +
-                        ListUtils.listToString(afAvail));
-            }
-        }
-    }
-
-    private static void mapControlAwb(CameraMetadataNative m, Camera.Parameters p) {
-        /*
-         * control.awbAvailableModes
-         */
-
-        {
-            List<String> wbModes = p.getSupportedWhiteBalance();
-
-            String[] wbModeStrings = new String[] {
-                    Camera.Parameters.WHITE_BALANCE_AUTO                    ,
-                    Camera.Parameters.WHITE_BALANCE_INCANDESCENT            ,
-                    Camera.Parameters.WHITE_BALANCE_FLUORESCENT             ,
-                    Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT        ,
-                    Camera.Parameters.WHITE_BALANCE_DAYLIGHT                ,
-                    Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT         ,
-                    Camera.Parameters.WHITE_BALANCE_TWILIGHT                ,
-                    Camera.Parameters.WHITE_BALANCE_SHADE                   ,
-            };
-
-            int[] wbModeInts = new int[] {
-                    CONTROL_AWB_MODE_AUTO,
-                    CONTROL_AWB_MODE_INCANDESCENT            ,
-                    CONTROL_AWB_MODE_FLUORESCENT             ,
-                    CONTROL_AWB_MODE_WARM_FLUORESCENT        ,
-                    CONTROL_AWB_MODE_DAYLIGHT                ,
-                    CONTROL_AWB_MODE_CLOUDY_DAYLIGHT         ,
-                    CONTROL_AWB_MODE_TWILIGHT                ,
-                    CONTROL_AWB_MODE_SHADE                   ,
-                    // Note that CONTROL_AWB_MODE_OFF is unsupported
-            };
-
-            List<Integer> awbAvail = ArrayUtils.convertStringListToIntList(
-                        wbModes, wbModeStrings, wbModeInts);
-
-            // No AWB modes supported? That's unpossible!
-            if (awbAvail == null || awbAvail.size() == 0) {
-                Log.w(TAG, "No AWB modes supported (HAL bug); defaulting to AWB_MODE_AUTO only");
-                awbAvail = new ArrayList<Integer>(/*capacity*/1);
-                awbAvail.add(CONTROL_AWB_MODE_AUTO);
-            }
-
-            m.set(CONTROL_AWB_AVAILABLE_MODES, ArrayUtils.toIntArray(awbAvail));
-
-            if (DEBUG) {
-                Log.v(TAG, "mapControlAwb - control.awbAvailableModes set to " +
-                        ListUtils.listToString(awbAvail));
-            }
-
-
-            /*
-             * control.awbLockAvailable
-             */
-            {
-                boolean awbLockAvailable = p.isAutoWhiteBalanceLockSupported();
-
-                m.set(CONTROL_AWB_LOCK_AVAILABLE, awbLockAvailable);
-            }
-        }
-    }
-
-    private static void mapControlOther(CameraMetadataNative m, Camera.Parameters p) {
-        /*
-         * android.control.availableVideoStabilizationModes
-         */
-        {
-            int stabModes[] = p.isVideoStabilizationSupported() ?
-                    new int[] { CONTROL_VIDEO_STABILIZATION_MODE_OFF,
-                                CONTROL_VIDEO_STABILIZATION_MODE_ON } :
-                    new int[] { CONTROL_VIDEO_STABILIZATION_MODE_OFF };
-
-            m.set(CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, stabModes);
-        }
-
-        /*
-         * android.control.maxRegions
-         */
-        final int AE = 0, AWB = 1, AF = 2;
-
-        int[] maxRegions = new int[3];
-        maxRegions[AE] = p.getMaxNumMeteringAreas();
-        maxRegions[AWB] = 0; // AWB regions not supported in API1
-        maxRegions[AF] = p.getMaxNumFocusAreas();
-
-        if (LIE_ABOUT_AE_MAX_REGIONS) {
-            maxRegions[AE] = 0;
-        }
-        if (LIE_ABOUT_AF_MAX_REGIONS) {
-            maxRegions[AF] = 0;
-        }
-
-        m.set(CONTROL_MAX_REGIONS, maxRegions);
-
-        /*
-         * android.control.availableEffects
-         */
-        List<String> effectModes = p.getSupportedColorEffects();
-        int[] supportedEffectModes = (effectModes == null) ? new int[0] :
-                ArrayUtils.convertStringListToIntArray(effectModes, sLegacyEffectMode,
-                        sEffectModes);
-        m.set(CONTROL_AVAILABLE_EFFECTS, supportedEffectModes);
-
-        /*
-         * android.control.availableSceneModes
-         */
-        int maxNumDetectedFaces = p.getMaxNumDetectedFaces();
-        List<String> sceneModes = p.getSupportedSceneModes();
-        List<Integer> supportedSceneModes =
-                ArrayUtils.convertStringListToIntList(sceneModes, sLegacySceneModes, sSceneModes);
-
-        // Special case where the only scene mode listed is AUTO => no scene mode
-        if (sceneModes != null && sceneModes.size() == 1 &&
-                sceneModes.get(0).equals(Parameters.SCENE_MODE_AUTO)) {
-            supportedSceneModes = null;
-        }
-
-        boolean sceneModeSupported = true;
-        if (supportedSceneModes == null && maxNumDetectedFaces == 0) {
-            sceneModeSupported = false;
-        }
-
-        if (sceneModeSupported) {
-            if (supportedSceneModes == null) {
-                supportedSceneModes = new ArrayList<Integer>();
-            }
-            if (maxNumDetectedFaces > 0) { // always supports FACE_PRIORITY when face detecting
-                supportedSceneModes.add(CONTROL_SCENE_MODE_FACE_PRIORITY);
-            }
-            // Remove all DISABLED occurrences
-            if (supportedSceneModes.contains(CONTROL_SCENE_MODE_DISABLED)) {
-                while(supportedSceneModes.remove(new Integer(CONTROL_SCENE_MODE_DISABLED))) {}
-            }
-            m.set(CONTROL_AVAILABLE_SCENE_MODES, ArrayUtils.toIntArray(supportedSceneModes));
-        } else {
-            m.set(CONTROL_AVAILABLE_SCENE_MODES, new int[] {CONTROL_SCENE_MODE_DISABLED});
-        }
-
-        /*
-         * android.control.availableModes
-         */
-        m.set(CONTROL_AVAILABLE_MODES, sceneModeSupported ?
-                new int[] { CONTROL_MODE_AUTO, CONTROL_MODE_USE_SCENE_MODE } :
-                new int[] { CONTROL_MODE_AUTO });
-    }
-
-    private static void mapLens(CameraMetadataNative m, Camera.Parameters p) {
-        /*
-         *  We can tell if the lens is fixed focus;
-         *  but if it's not, we can't tell the minimum focus distance, so leave it null then.
-         */
-        if (DEBUG) {
-            Log.v(TAG, "mapLens - focus-mode='" + p.getFocusMode() + "'");
-        }
-
-        if (Camera.Parameters.FOCUS_MODE_FIXED.equals(p.getFocusMode())) {
-            /*
-             * lens.info.minimumFocusDistance
-             */
-            m.set(LENS_INFO_MINIMUM_FOCUS_DISTANCE, LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS);
-
-            if (DEBUG) {
-                Log.v(TAG, "mapLens - lens.info.minimumFocusDistance = 0");
-            }
-        } else {
-            if (DEBUG) {
-                Log.v(TAG, "mapLens - lens.info.minimumFocusDistance is unknown");
-            }
-        }
-
-        float[] focalLengths = new float[] { p.getFocalLength() };
-        m.set(LENS_INFO_AVAILABLE_FOCAL_LENGTHS, focalLengths);
-    }
-
-    private static void mapFlash(CameraMetadataNative m, Camera.Parameters p) {
-        boolean flashAvailable = false;
-        List<String> supportedFlashModes = p.getSupportedFlashModes();
-
-        if (supportedFlashModes != null) {
-            // If only 'OFF' is available, we don't really have flash support
-            flashAvailable = !ListUtils.listElementsEqualTo(
-                    supportedFlashModes, Camera.Parameters.FLASH_MODE_OFF);
-        }
-
-        /*
-         * flash.info.available
-         */
-        m.set(FLASH_INFO_AVAILABLE, flashAvailable);
-    }
-
-    private static void mapJpeg(CameraMetadataNative m, Camera.Parameters p) {
-        List<Camera.Size> thumbnailSizes = p.getSupportedJpegThumbnailSizes();
-
-        if (thumbnailSizes != null) {
-            Size[] sizes = convertSizeListToArray(thumbnailSizes);
-            Arrays.sort(sizes, new android.hardware.camera2.utils.SizeAreaComparator());
-            m.set(JPEG_AVAILABLE_THUMBNAIL_SIZES, sizes);
-        }
-    }
-
-    private static void mapRequest(CameraMetadataNative m, Parameters p) {
-        /*
-         * request.availableCapabilities
-         */
-        int[] capabilities = { REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE };
-        m.set(REQUEST_AVAILABLE_CAPABILITIES, capabilities);
-
-        /*
-         * request.availableCharacteristicsKeys
-         */
-        {
-            // TODO: check if the underlying key is supported before listing a key as available
-
-            // Note: We only list public keys. Native HALs should list ALL keys regardless of visibility.
-
-            Key<?> availableKeys[] = new Key<?>[] {
-                    CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES     ,
-                    CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES          ,
-                    CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES                      ,
-                    CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES          ,
-                    CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE                   ,
-                    CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP                    ,
-                    CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE                       ,
-                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES                      ,
-                    CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS                       ,
-                    CameraCharacteristics.CONTROL_AVAILABLE_MODES                         ,
-                    CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES                   ,
-                    CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES     ,
-                    CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES                     ,
-                    CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE                      ,
-                    CameraCharacteristics.CONTROL_MAX_REGIONS                             ,
-                    CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE                        ,
-                    CameraCharacteristics.FLASH_INFO_AVAILABLE                            ,
-                    CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL                   ,
-                    CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES                  ,
-                    CameraCharacteristics.LENS_FACING                                     ,
-                    CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS               ,
-                    CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES ,
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES                  ,
-                    CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS                  ,
-                    CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT                    ,
-                    CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH                      ,
-                    CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM               ,
-//                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP                 ,
-                    CameraCharacteristics.SCALER_CROPPING_TYPE                            ,
-                    CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES             ,
-                    CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE                   ,
-                    CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE                       ,
-                    CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE                    ,
-                    CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE    ,
-                    CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE                    ,
-                    CameraCharacteristics.SENSOR_ORIENTATION                              ,
-                    CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES     ,
-                    CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT                  ,
-                    CameraCharacteristics.SYNC_MAX_LATENCY                                ,
-            };
-            List<Key<?>> characteristicsKeys = new ArrayList<>(Arrays.asList(availableKeys));
-
-            /*
-             * Add the conditional keys
-             */
-            if (m.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE) != null) {
-                characteristicsKeys.add(LENS_INFO_MINIMUM_FOCUS_DISTANCE);
-            }
-
-            m.set(REQUEST_AVAILABLE_CHARACTERISTICS_KEYS,
-                    getTagsForKeys(characteristicsKeys.toArray(new Key<?>[0])));
-        }
-
-        /*
-         * request.availableRequestKeys
-         */
-        {
-            CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] {
-                    CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
-                    CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
-                    CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
-                    CaptureRequest.CONTROL_AE_LOCK,
-                    CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
-                    CaptureRequest.CONTROL_AF_MODE,
-                    CaptureRequest.CONTROL_AF_TRIGGER,
-                    CaptureRequest.CONTROL_AWB_LOCK,
-                    CaptureRequest.CONTROL_AWB_MODE,
-                    CaptureRequest.CONTROL_CAPTURE_INTENT,
-                    CaptureRequest.CONTROL_EFFECT_MODE,
-                    CaptureRequest.CONTROL_MODE,
-                    CaptureRequest.CONTROL_SCENE_MODE,
-                    CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE,
-                    CaptureRequest.CONTROL_ZOOM_RATIO,
-                    CaptureRequest.FLASH_MODE,
-                    CaptureRequest.JPEG_GPS_COORDINATES,
-                    CaptureRequest.JPEG_GPS_PROCESSING_METHOD,
-                    CaptureRequest.JPEG_GPS_TIMESTAMP,
-                    CaptureRequest.JPEG_ORIENTATION,
-                    CaptureRequest.JPEG_QUALITY,
-                    CaptureRequest.JPEG_THUMBNAIL_QUALITY,
-                    CaptureRequest.JPEG_THUMBNAIL_SIZE,
-                    CaptureRequest.LENS_FOCAL_LENGTH,
-                    CaptureRequest.NOISE_REDUCTION_MODE,
-                    CaptureRequest.SCALER_CROP_REGION,
-                    CaptureRequest.STATISTICS_FACE_DETECT_MODE,
-            };
-            ArrayList<CaptureRequest.Key<?>> availableKeys =
-                    new ArrayList<CaptureRequest.Key<?>>(Arrays.asList(defaultAvailableKeys));
-
-            if (p.getMaxNumMeteringAreas() > 0) {
-                availableKeys.add(CaptureRequest.CONTROL_AE_REGIONS);
-            }
-            if (p.getMaxNumFocusAreas() > 0) {
-                availableKeys.add(CaptureRequest.CONTROL_AF_REGIONS);
-            }
-
-            CaptureRequest.Key<?> availableRequestKeys[] =
-                    new CaptureRequest.Key<?>[availableKeys.size()];
-            availableKeys.toArray(availableRequestKeys);
-            m.set(REQUEST_AVAILABLE_REQUEST_KEYS, getTagsForKeys(availableRequestKeys));
-        }
-
-        /*
-         * request.availableResultKeys
-         */
-        {
-            CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] {
-                    CaptureResult.COLOR_CORRECTION_ABERRATION_MODE                 ,
-                    CaptureResult.CONTROL_AE_ANTIBANDING_MODE                      ,
-                    CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION                 ,
-                    CaptureResult.CONTROL_AE_LOCK                                  ,
-                    CaptureResult.CONTROL_AE_MODE                                  ,
-                    CaptureResult.CONTROL_AF_MODE                                  ,
-                    CaptureResult.CONTROL_AF_STATE                                 ,
-                    CaptureResult.CONTROL_AWB_MODE                                 ,
-                    CaptureResult.CONTROL_AWB_LOCK                                 ,
-                    CaptureResult.CONTROL_MODE                                     ,
-                    CaptureResult.CONTROL_ZOOM_RATIO                               ,
-                    CaptureResult.FLASH_MODE                                       ,
-                    CaptureResult.JPEG_GPS_COORDINATES                             ,
-                    CaptureResult.JPEG_GPS_PROCESSING_METHOD                       ,
-                    CaptureResult.JPEG_GPS_TIMESTAMP                               ,
-                    CaptureResult.JPEG_ORIENTATION                                 ,
-                    CaptureResult.JPEG_QUALITY                                     ,
-                    CaptureResult.JPEG_THUMBNAIL_QUALITY                           ,
-                    CaptureResult.LENS_FOCAL_LENGTH                                ,
-                    CaptureResult.NOISE_REDUCTION_MODE                             ,
-                    CaptureResult.REQUEST_PIPELINE_DEPTH                           ,
-                    CaptureResult.SCALER_CROP_REGION                               ,
-                    CaptureResult.SENSOR_TIMESTAMP                                 ,
-                    CaptureResult.STATISTICS_FACE_DETECT_MODE                      ,
-//                    CaptureResult.STATISTICS_FACES                                 ,
-            };
-            List<CaptureResult.Key<?>> availableKeys =
-                    new ArrayList<CaptureResult.Key<?>>(Arrays.asList(defaultAvailableKeys));
-
-            if (p.getMaxNumMeteringAreas() > 0) {
-                availableKeys.add(CaptureResult.CONTROL_AE_REGIONS);
-            }
-            if (p.getMaxNumFocusAreas() > 0) {
-                availableKeys.add(CaptureResult.CONTROL_AF_REGIONS);
-            }
-
-            CaptureResult.Key<?> availableResultKeys[] =
-                    new CaptureResult.Key<?>[availableKeys.size()];
-            availableKeys.toArray(availableResultKeys);
-            m.set(REQUEST_AVAILABLE_RESULT_KEYS, getTagsForKeys(availableResultKeys));
-        }
-
-        /*
-         * request.maxNumOutputStreams
-         */
-        int[] outputStreams = {
-                /* RAW */
-                REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_RAW,
-                /* Processed & Not-Stalling */
-                REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC,
-                /* Processed & Stalling */
-                REQUEST_MAX_NUM_OUTPUT_STREAMS_COUNT_PROC_STALL,
-        };
-        m.set(REQUEST_MAX_NUM_OUTPUT_STREAMS, outputStreams);
-
-        /*
-         * request.maxNumInputStreams
-         */
-        m.set(REQUEST_MAX_NUM_INPUT_STREAMS, REQUEST_MAX_NUM_INPUT_STREAMS_COUNT);
-
-        /*
-         * request.partialResultCount
-         */
-        m.set(REQUEST_PARTIAL_RESULT_COUNT, 1); // No partial results supported
-
-        /*
-         * request.pipelineMaxDepth
-         */
-        m.set(REQUEST_PIPELINE_MAX_DEPTH,
-                (byte)(REQUEST_PIPELINE_MAX_DEPTH_HAL1 + REQUEST_PIPELINE_MAX_DEPTH_OURS));
-    }
-
-    private static void mapScaler(CameraMetadataNative m, Parameters p) {
-        /*
-         * control.zoomRatioRange
-         */
-        Range<Float> zoomRatioRange = new Range<Float>(1.0f, ParameterUtils.getMaxZoomRatio(p));
-        m.set(CONTROL_ZOOM_RATIO_RANGE, zoomRatioRange);
-
-        /*
-         * scaler.availableMaxDigitalZoom
-         */
-        m.set(SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, ParameterUtils.getMaxZoomRatio(p));
-
-        /*
-         * scaler.croppingType = CENTER_ONLY
-         */
-        m.set(SCALER_CROPPING_TYPE, SCALER_CROPPING_TYPE_CENTER_ONLY);
-    }
-
-    private static void mapSensor(CameraMetadataNative m, Parameters p) {
-        // Use the largest jpeg size (by area) for both active array and pixel array
-        Size largestJpegSize = getLargestSupportedJpegSizeByArea(p);
-        /*
-         * sensor.info.activeArraySize, and preCorrectionActiveArraySize
-         */
-        {
-            Rect activeArrayRect = ParamsUtils.createRect(largestJpegSize);
-            m.set(SENSOR_INFO_ACTIVE_ARRAY_SIZE, activeArrayRect);
-            m.set(SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE, activeArrayRect);
-        }
-
-        /*
-         * sensor.availableTestPatternModes
-         */
-        {
-            // Only "OFF" test pattern mode is available
-            m.set(SENSOR_AVAILABLE_TEST_PATTERN_MODES, new int[] { SENSOR_TEST_PATTERN_MODE_OFF });
-        }
-
-        /*
-         * sensor.info.pixelArraySize
-         */
-        m.set(SENSOR_INFO_PIXEL_ARRAY_SIZE, largestJpegSize);
-
-        /*
-         * sensor.info.physicalSize
-         */
-        {
-            /*
-             * Assume focal length is at infinity focus and that the lens is rectilinear.
-             */
-            float focalLength = p.getFocalLength(); // in mm
-            double angleHor = p.getHorizontalViewAngle() * Math.PI / 180; // to radians
-            double angleVer = p.getVerticalViewAngle() * Math.PI / 180; // to radians
-
-            float height = (float)Math.abs(2 * focalLength * Math.tan(angleVer / 2));
-            float width = (float)Math.abs(2 * focalLength * Math.tan(angleHor / 2));
-
-            m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm
-        }
-
-        /*
-         * sensor.info.timestampSource
-         */
-        {
-            m.set(SENSOR_INFO_TIMESTAMP_SOURCE, SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN);
-        }
-    }
-
-    private static void mapStatistics(CameraMetadataNative m, Parameters p) {
-        /*
-         * statistics.info.availableFaceDetectModes
-         */
-        int[] fdModes;
-
-        if (p.getMaxNumDetectedFaces() > 0) {
-            fdModes = new int[] {
-                STATISTICS_FACE_DETECT_MODE_OFF,
-                STATISTICS_FACE_DETECT_MODE_SIMPLE
-                // FULL is never-listed, since we have no way to query it statically
-            };
-        } else {
-            fdModes = new int[] {
-                STATISTICS_FACE_DETECT_MODE_OFF
-            };
-        }
-        m.set(STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, fdModes);
-
-        /*
-         * statistics.info.maxFaceCount
-         */
-        m.set(STATISTICS_INFO_MAX_FACE_COUNT, p.getMaxNumDetectedFaces());
-    }
-
-    private static void mapSync(CameraMetadataNative m, Parameters p) {
-        /*
-         * sync.maxLatency
-         */
-        m.set(SYNC_MAX_LATENCY, SYNC_MAX_LATENCY_UNKNOWN);
-    }
-
-    private static void appendStreamConfig(
-            ArrayList<StreamConfiguration> configs, int format, List<Camera.Size> sizes) {
-        for (Camera.Size size : sizes) {
-            StreamConfiguration config =
-                    new StreamConfiguration(format, size.width, size.height, /*input*/false);
-            configs.add(config);
-        }
-    }
-
-    private final static String[] sLegacySceneModes = {
-        Parameters.SCENE_MODE_AUTO,
-        Parameters.SCENE_MODE_ACTION,
-        Parameters.SCENE_MODE_PORTRAIT,
-        Parameters.SCENE_MODE_LANDSCAPE,
-        Parameters.SCENE_MODE_NIGHT,
-        Parameters.SCENE_MODE_NIGHT_PORTRAIT,
-        Parameters.SCENE_MODE_THEATRE,
-        Parameters.SCENE_MODE_BEACH,
-        Parameters.SCENE_MODE_SNOW,
-        Parameters.SCENE_MODE_SUNSET,
-        Parameters.SCENE_MODE_STEADYPHOTO,
-        Parameters.SCENE_MODE_FIREWORKS,
-        Parameters.SCENE_MODE_SPORTS,
-        Parameters.SCENE_MODE_PARTY,
-        Parameters.SCENE_MODE_CANDLELIGHT,
-        Parameters.SCENE_MODE_BARCODE,
-        Parameters.SCENE_MODE_HDR,
-    };
-
-    private final static int[] sSceneModes = {
-        CameraCharacteristics.CONTROL_SCENE_MODE_DISABLED,
-        CameraCharacteristics.CONTROL_SCENE_MODE_ACTION,
-        CameraCharacteristics.CONTROL_SCENE_MODE_PORTRAIT,
-        CameraCharacteristics.CONTROL_SCENE_MODE_LANDSCAPE,
-        CameraCharacteristics.CONTROL_SCENE_MODE_NIGHT,
-        CameraCharacteristics.CONTROL_SCENE_MODE_NIGHT_PORTRAIT,
-        CameraCharacteristics.CONTROL_SCENE_MODE_THEATRE,
-        CameraCharacteristics.CONTROL_SCENE_MODE_BEACH,
-        CameraCharacteristics.CONTROL_SCENE_MODE_SNOW,
-        CameraCharacteristics.CONTROL_SCENE_MODE_SUNSET,
-        CameraCharacteristics.CONTROL_SCENE_MODE_STEADYPHOTO,
-        CameraCharacteristics.CONTROL_SCENE_MODE_FIREWORKS,
-        CameraCharacteristics.CONTROL_SCENE_MODE_SPORTS,
-        CameraCharacteristics.CONTROL_SCENE_MODE_PARTY,
-        CameraCharacteristics.CONTROL_SCENE_MODE_CANDLELIGHT,
-        CameraCharacteristics.CONTROL_SCENE_MODE_BARCODE,
-        CameraCharacteristics.CONTROL_SCENE_MODE_HDR,
-    };
-
-    static int convertSceneModeFromLegacy(String mode) {
-        if (mode == null) {
-            return CameraCharacteristics.CONTROL_SCENE_MODE_DISABLED;
-        }
-        int index = ArrayUtils.getArrayIndex(sLegacySceneModes, mode);
-        if (index < 0) {
-            return UNKNOWN_MODE;
-        }
-        return sSceneModes[index];
-    }
-
-    static String convertSceneModeToLegacy(int mode) {
-        if (mode == CONTROL_SCENE_MODE_FACE_PRIORITY) {
-            // OK: Let LegacyFaceDetectMapper handle turning face detection on/off
-            return Parameters.SCENE_MODE_AUTO;
-        }
-
-        int index = ArrayUtils.getArrayIndex(sSceneModes, mode);
-        if (index < 0) {
-            return null;
-        }
-        return sLegacySceneModes[index];
-    }
-
-    private final static String[] sLegacyEffectMode = {
-        Parameters.EFFECT_NONE,
-        Parameters.EFFECT_MONO,
-        Parameters.EFFECT_NEGATIVE,
-        Parameters.EFFECT_SOLARIZE,
-        Parameters.EFFECT_SEPIA,
-        Parameters.EFFECT_POSTERIZE,
-        Parameters.EFFECT_WHITEBOARD,
-        Parameters.EFFECT_BLACKBOARD,
-        Parameters.EFFECT_AQUA,
-    };
-
-    private final static int[] sEffectModes = {
-        CameraCharacteristics.CONTROL_EFFECT_MODE_OFF,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_MONO,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_NEGATIVE,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_SOLARIZE,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_SEPIA,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_POSTERIZE,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_WHITEBOARD,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_BLACKBOARD,
-        CameraCharacteristics.CONTROL_EFFECT_MODE_AQUA,
-    };
-
-    static int convertEffectModeFromLegacy(String mode) {
-        if (mode == null) {
-            return CameraCharacteristics.CONTROL_EFFECT_MODE_OFF;
-        }
-        int index = ArrayUtils.getArrayIndex(sLegacyEffectMode, mode);
-        if (index < 0) {
-            return UNKNOWN_MODE;
-        }
-        return sEffectModes[index];
-    }
-
-    static String convertEffectModeToLegacy(int mode) {
-        int index = ArrayUtils.getArrayIndex(sEffectModes, mode);
-        if (index < 0) {
-            return null;
-        }
-        return sLegacyEffectMode[index];
-    }
-
-    /**
-     * Convert the ae antibanding mode from api1 into api2.
-     *
-     * @param mode the api1 mode, {@code null} is allowed and will return {@code -1}.
-     *
-     * @return The api2 value, or {@code -1} by default if conversion failed
-     */
-    private static int convertAntiBandingMode(String mode) {
-        if (mode == null) {
-            return -1;
-        }
-
-        switch (mode) {
-            case Camera.Parameters.ANTIBANDING_OFF: {
-                return CONTROL_AE_ANTIBANDING_MODE_OFF;
-            }
-            case Camera.Parameters.ANTIBANDING_50HZ: {
-                return CONTROL_AE_ANTIBANDING_MODE_50HZ;
-            }
-            case Camera.Parameters.ANTIBANDING_60HZ: {
-                return CONTROL_AE_ANTIBANDING_MODE_60HZ;
-            }
-            case Camera.Parameters.ANTIBANDING_AUTO: {
-                return CONTROL_AE_ANTIBANDING_MODE_AUTO;
-            }
-            default: {
-                Log.w(TAG, "convertAntiBandingMode - Unknown antibanding mode " + mode);
-                return -1;
-            }
-        }
-    }
-
-    /**
-     * Convert the ae antibanding mode from api1 into api2.
-     *
-     * @param mode the api1 mode, {@code null} is allowed and will return {@code MODE_OFF}.
-     *
-     * @return The api2 value, or {@code MODE_OFF} by default if conversion failed
-     */
-    static int convertAntiBandingModeOrDefault(String mode) {
-        int antiBandingMode = convertAntiBandingMode(mode);
-        if (antiBandingMode == -1) {
-            return CONTROL_AE_ANTIBANDING_MODE_OFF;
-        }
-
-        return antiBandingMode;
-    }
-
-    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
-        int[] legacyFps = new int[2];
-        legacyFps[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower();
-        legacyFps[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper();
-        return legacyFps;
-    }
-
-    /**
-     * Return the stall duration for a given output jpeg size in nanoseconds.
-     *
-     * <p>An 8mp image is chosen to have a stall duration of 0.8 seconds.</p>
-     */
-    private static long calculateJpegStallDuration(Camera.Size size) {
-        long baseDuration = APPROXIMATE_CAPTURE_DELAY_MS * NS_PER_MS; // 200ms for capture
-        long area = size.width * (long) size.height;
-        long stallPerArea = APPROXIMATE_JPEG_ENCODE_TIME_MS * NS_PER_MS /
-                APPROXIMATE_SENSOR_AREA_PX; // 600ms stall for 8mp
-        return baseDuration + area * stallPerArea;
-    }
-
-    /**
-     * Set the legacy parameters using the {@link LegacyRequest legacy request}.
-     *
-     * <p>The legacy request's parameters are changed as a side effect of calling this
-     * method.</p>
-     *
-     * @param request a non-{@code null} legacy request
-     */
-    public static void convertRequestMetadata(LegacyRequest request) {
-        LegacyRequestMapper.convertRequestMetadata(request);
-    }
-
-    private static final int[] sAllowedTemplates = {
-            CameraDevice.TEMPLATE_PREVIEW,
-            CameraDevice.TEMPLATE_STILL_CAPTURE,
-            CameraDevice.TEMPLATE_RECORD,
-            // Disallowed templates in legacy mode:
-            // CameraDevice.TEMPLATE_VIDEO_SNAPSHOT,
-            // CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG,
-            // CameraDevice.TEMPLATE_MANUAL
-    };
-
-    /**
-     * Create a request template
-     *
-     * @param c a non-{@code null} camera characteristics for this camera
-     * @param templateId a non-negative template ID
-     *
-     * @return a non-{@code null} request template
-     *
-     * @throws IllegalArgumentException if {@code templateId} was invalid
-     *
-     * @see android.hardware.camera2.CameraDevice#TEMPLATE_MANUAL
-     */
-    public static CameraMetadataNative createRequestTemplate(
-            CameraCharacteristics c, int templateId) {
-        if (!ArrayUtils.contains(sAllowedTemplates, templateId)) {
-            throw new IllegalArgumentException("templateId out of range");
-        }
-
-        CameraMetadataNative m = new CameraMetadataNative();
-
-        /*
-         * NOTE: If adding new code here and it needs to query the static info,
-         * query the camera characteristics, so we can reuse this for api2 code later
-         * to create our own templates in the framework
-         */
-
-        /*
-         * control.*
-         */
-
-        // control.awbMode
-        m.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO);
-        // AWB is always unconditionally available in API1 devices
-
-        // control.aeAntibandingMode
-        m.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, CONTROL_AE_ANTIBANDING_MODE_AUTO);
-
-        // control.aeExposureCompensation
-        m.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
-
-        // control.aeLock
-        m.set(CaptureRequest.CONTROL_AE_LOCK, false);
-
-        // control.aePrecaptureTrigger
-        m.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
-
-        // control.afTrigger
-        m.set(CaptureRequest.CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_IDLE);
-
-        // control.awbMode
-        m.set(CaptureRequest.CONTROL_AWB_MODE, CONTROL_AWB_MODE_AUTO);
-
-        // control.awbLock
-        m.set(CaptureRequest.CONTROL_AWB_LOCK, false);
-
-        // control.aeRegions, control.awbRegions, control.afRegions
-        {
-            Rect activeArray = c.get(SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-            MeteringRectangle[] activeRegions =  new MeteringRectangle[] {
-                    new MeteringRectangle(/*x*/0, /*y*/0, /*width*/activeArray.width() - 1,
-                    /*height*/activeArray.height() - 1,/*weight*/0)};
-            m.set(CaptureRequest.CONTROL_AE_REGIONS, activeRegions);
-            m.set(CaptureRequest.CONTROL_AWB_REGIONS, activeRegions);
-            m.set(CaptureRequest.CONTROL_AF_REGIONS, activeRegions);
-        }
-
-        // control.captureIntent
-        {
-            int captureIntent;
-            switch (templateId) {
-                case CameraDevice.TEMPLATE_PREVIEW:
-                    captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
-                    break;
-                case CameraDevice.TEMPLATE_STILL_CAPTURE:
-                    captureIntent = CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
-                    break;
-                case CameraDevice.TEMPLATE_RECORD:
-                    captureIntent = CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
-                    break;
-                default:
-                    // Can't get anything else since it's guarded by the IAE check
-                    throw new AssertionError("Impossible; keep in sync with sAllowedTemplates");
-            }
-            m.set(CaptureRequest.CONTROL_CAPTURE_INTENT, captureIntent);
-        }
-
-        // control.aeMode
-        m.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_ON);
-        // AE is always unconditionally available in API1 devices
-
-        // control.mode
-        m.set(CaptureRequest.CONTROL_MODE, CONTROL_MODE_AUTO);
-
-        // control.afMode
-        {
-            Float minimumFocusDistance = c.get(LENS_INFO_MINIMUM_FOCUS_DISTANCE);
-
-            int afMode;
-            if (minimumFocusDistance != null &&
-                    minimumFocusDistance == LENS_INFO_MINIMUM_FOCUS_DISTANCE_FIXED_FOCUS) {
-                // Cannot control auto-focus with fixed-focus cameras
-                afMode = CameraMetadata.CONTROL_AF_MODE_OFF;
-            } else {
-                // If a minimum focus distance is reported; the camera must have AF
-                afMode = CameraMetadata.CONTROL_AF_MODE_AUTO;
-
-                if (templateId == CameraDevice.TEMPLATE_RECORD ||
-                        templateId == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
-                    if (ArrayUtils.contains(c.get(CONTROL_AF_AVAILABLE_MODES),
-                            CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
-                        afMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-                    }
-                } else if (templateId == CameraDevice.TEMPLATE_PREVIEW ||
-                        templateId == CameraDevice.TEMPLATE_STILL_CAPTURE) {
-                    if (ArrayUtils.contains(c.get(CONTROL_AF_AVAILABLE_MODES),
-                            CONTROL_AF_MODE_CONTINUOUS_PICTURE)) {
-                        afMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-                    }
-                }
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "createRequestTemplate (templateId=" + templateId + ")," +
-                        " afMode=" + afMode + ", minimumFocusDistance=" + minimumFocusDistance);
-            }
-
-            m.set(CaptureRequest.CONTROL_AF_MODE, afMode);
-        }
-
-        {
-            // control.aeTargetFpsRange
-            Range<Integer>[] availableFpsRange = c.
-                    get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
-
-            // Pick FPS range with highest max value, tiebreak on higher min value
-            Range<Integer> bestRange = availableFpsRange[0];
-            for (Range<Integer> r : availableFpsRange) {
-                if (bestRange.getUpper() < r.getUpper()) {
-                    bestRange = r;
-                } else if (bestRange.getUpper() == r.getUpper() &&
-                        bestRange.getLower() < r.getLower()) {
-                    bestRange = r;
-                }
-            }
-            m.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, bestRange);
-        }
-
-        // control.sceneMode -- DISABLED is always available
-        m.set(CaptureRequest.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED);
-
-        // control.zoomRatio -- 1.0
-        m.set(CaptureRequest.CONTROL_ZOOM_RATIO, 1.0f);
-
-        /*
-         * statistics.*
-         */
-
-        // statistics.faceDetectMode
-        m.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, STATISTICS_FACE_DETECT_MODE_OFF);
-
-        /*
-         * flash.*
-         */
-
-        // flash.mode
-        m.set(CaptureRequest.FLASH_MODE, FLASH_MODE_OFF);
-
-        /*
-         * noiseReduction.*
-         */
-        if (templateId == CameraDevice.TEMPLATE_STILL_CAPTURE) {
-            m.set(CaptureRequest.NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODE_HIGH_QUALITY);
-        } else {
-            m.set(CaptureRequest.NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODE_FAST);
-        }
-
-        /*
-        * colorCorrection.*
-        */
-        if (templateId == CameraDevice.TEMPLATE_STILL_CAPTURE) {
-            m.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
-                    COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
-        } else {
-            m.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
-                    COLOR_CORRECTION_ABERRATION_MODE_FAST);
-        }
-
-        /*
-         * lens.*
-         */
-
-        // lens.focalLength
-        m.set(CaptureRequest.LENS_FOCAL_LENGTH,
-                c.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)[0]);
-
-        /*
-         * jpeg.*
-         */
-
-        // jpeg.thumbnailSize - set smallest non-zero size if possible
-        Size[] sizes = c.get(CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES);
-        m.set(CaptureRequest.JPEG_THUMBNAIL_SIZE, (sizes.length > 1) ? sizes[1] : sizes[0]);
-
-        // TODO: map other request template values
-        return m;
-    }
-
-    private static int[] getTagsForKeys(Key<?>[] keys) {
-        int[] tags = new int[keys.length];
-
-        for (int i = 0; i < keys.length; ++i) {
-            tags[i] = keys[i].getNativeKey().getTag();
-        }
-
-        return tags;
-    }
-
-    private static int[] getTagsForKeys(CaptureRequest.Key<?>[] keys) {
-        int[] tags = new int[keys.length];
-
-        for (int i = 0; i < keys.length; ++i) {
-            tags[i] = keys[i].getNativeKey().getTag();
-        }
-
-        return tags;
-    }
-
-    private static int[] getTagsForKeys(CaptureResult.Key<?>[] keys) {
-        int[] tags = new int[keys.length];
-
-        for (int i = 0; i < keys.length; ++i) {
-            tags[i] = keys[i].getNativeKey().getTag();
-        }
-
-        return tags;
-    }
-
-    /**
-     * Convert the requested AF mode into its equivalent supported parameter.
-     *
-     * @param mode {@code CONTROL_AF_MODE}
-     * @param supportedFocusModes list of camera1's supported focus modes
-     * @return the stringified af mode, or {@code null} if its not supported
-     */
-    static String convertAfModeToLegacy(int mode, List<String> supportedFocusModes) {
-        if (supportedFocusModes == null || supportedFocusModes.isEmpty()) {
-            Log.w(TAG, "No focus modes supported; API1 bug");
-            return null;
-        }
-
-        String param = null;
-        switch (mode) {
-            case CONTROL_AF_MODE_AUTO:
-                param = Parameters.FOCUS_MODE_AUTO;
-                break;
-            case CONTROL_AF_MODE_CONTINUOUS_PICTURE:
-                param = Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
-                break;
-            case CONTROL_AF_MODE_CONTINUOUS_VIDEO:
-                param = Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
-                break;
-            case CONTROL_AF_MODE_EDOF:
-                param = Parameters.FOCUS_MODE_EDOF;
-                break;
-            case CONTROL_AF_MODE_MACRO:
-                param = Parameters.FOCUS_MODE_MACRO;
-                break;
-            case CONTROL_AF_MODE_OFF:
-                if (supportedFocusModes.contains(Parameters.FOCUS_MODE_FIXED)) {
-                    param = Parameters.FOCUS_MODE_FIXED;
-                } else {
-                    param = Parameters.FOCUS_MODE_INFINITY;
-                }
-        }
-
-        if (!supportedFocusModes.contains(param)) {
-            // Weed out bad user input by setting to the first arbitrary focus mode
-            String defaultMode = supportedFocusModes.get(0);
-            Log.w(TAG,
-                    String.format(
-                            "convertAfModeToLegacy - ignoring unsupported mode %d, " +
-                            "defaulting to %s", mode, defaultMode));
-            param = defaultMode;
-        }
-
-        return param;
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequest.java b/core/java/android/hardware/camera2/legacy/LegacyRequest.java
deleted file mode 100644
index f13ac5c..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyRequest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.Camera;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.util.Size;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Hold important data necessary to build the camera1 parameters up from a capture request.
- */
-public class LegacyRequest {
-    /** Immutable characteristics for the camera corresponding to this request */
-    public final CameraCharacteristics characteristics;
-    /** Immutable capture request, as requested by the user */
-    public final CaptureRequest captureRequest;
-    /** Immutable api1 preview buffer size at the time of the request */
-    public final Size previewSize;
-    /** <em>Mutable</em> camera parameters */
-    public final Camera.Parameters parameters;
-
-    /**
-     * Create a new legacy request; the parameters are copied.
-     *
-     * @param characteristics immutable static camera characteristics for this camera
-     * @param captureRequest immutable user-defined capture request
-     * @param previewSize immutable internal preview size used for {@link Camera#setPreviewSurface}
-     * @param parameters the initial camera1 parameter state; (copied) can be mutated
-     */
-    public LegacyRequest(CameraCharacteristics characteristics, CaptureRequest captureRequest,
-            Size previewSize, Camera.Parameters parameters) {
-        this.characteristics = checkNotNull(characteristics, "characteristics must not be null");
-        this.captureRequest = checkNotNull(captureRequest, "captureRequest must not be null");
-        this.previewSize = checkNotNull(previewSize, "previewSize must not be null");
-        checkNotNull(parameters, "parameters must not be null");
-
-        this.parameters = Camera.getParametersCopy(parameters);
-    }
-
-    /**
-     * Update the current parameters in-place to be a copy of the new parameters.
-     *
-     * @param parameters non-{@code null} parameters for api1 camera
-     */
-    public void setParameters(Camera.Parameters parameters) {
-        checkNotNull(parameters, "parameters must not be null");
-
-        this.parameters.copyFrom(parameters);
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
deleted file mode 100644
index 3a46379..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ /dev/null
@@ -1,688 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.utils.ListUtils;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.location.Location;
-import android.util.Log;
-import android.util.Range;
-import android.util.Size;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-import static android.hardware.camera2.CaptureRequest.*;
-
-/**
- * Provide legacy-specific implementations of camera2 CaptureRequest for legacy devices.
- */
-@SuppressWarnings("deprecation")
-public class LegacyRequestMapper {
-    private static final String TAG = "LegacyRequestMapper";
-    private static final boolean DEBUG = false;
-
-    /** Default quality for android.jpeg.quality, android.jpeg.thumbnailQuality */
-    private static final byte DEFAULT_JPEG_QUALITY = 85;
-
-    /**
-     * Set the legacy parameters using the {@link LegacyRequest legacy request}.
-     *
-     * <p>The legacy request's parameters are changed as a side effect of calling this
-     * method.</p>
-     *
-     * @param legacyRequest a non-{@code null} legacy request
-     */
-    public static void convertRequestMetadata(LegacyRequest legacyRequest) {
-        CameraCharacteristics characteristics = legacyRequest.characteristics;
-        CaptureRequest request = legacyRequest.captureRequest;
-        Size previewSize = legacyRequest.previewSize;
-        Camera.Parameters params = legacyRequest.parameters;
-
-        Rect activeArray = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-
-        /*
-         * scaler.cropRegion
-         */
-        ParameterUtils.ZoomData zoomData;
-        {
-            zoomData = ParameterUtils.convertToLegacyZoom(activeArray,
-                    request.get(SCALER_CROP_REGION),
-                    request.get(CONTROL_ZOOM_RATIO),
-                    previewSize,
-                    params);
-
-            if (params.isZoomSupported()) {
-                params.setZoom(zoomData.zoomIndex);
-            } else if (DEBUG) {
-                Log.v(TAG, "convertRequestToMetadata - zoom is not supported");
-            }
-        }
-
-        /*
-         * colorCorrection.*
-         */
-        // colorCorrection.aberrationMode
-        {
-            int aberrationMode = ParamsUtils.getOrDefault(request,
-                    COLOR_CORRECTION_ABERRATION_MODE,
-                    /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST);
-
-            if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST &&
-                    aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY) {
-                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
-                        "colorCorrection.aberrationMode = " + aberrationMode);
-            }
-        }
-
-        /*
-         * control.ae*
-         */
-        // control.aeAntibandingMode
-        {
-        String legacyMode;
-            Integer antiBandingMode = request.get(CONTROL_AE_ANTIBANDING_MODE);
-            if (antiBandingMode != null) {
-                legacyMode = convertAeAntiBandingModeToLegacy(antiBandingMode);
-            } else {
-                legacyMode = ListUtils.listSelectFirstFrom(params.getSupportedAntibanding(),
-                        new String[] {
-                            Parameters.ANTIBANDING_AUTO,
-                            Parameters.ANTIBANDING_OFF,
-                            Parameters.ANTIBANDING_50HZ,
-                            Parameters.ANTIBANDING_60HZ,
-                        });
-            }
-
-            if (legacyMode != null) {
-                params.setAntibanding(legacyMode);
-            }
-        }
-
-        /*
-         * control.aeRegions, afRegions
-         */
-        {
-            // aeRegions
-            {
-                // Use aeRegions if available, fall back to using awbRegions if present
-                MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS);
-                if (request.get(CONTROL_AWB_REGIONS) != null) {
-                    Log.w(TAG, "convertRequestMetadata - control.awbRegions setting is not " +
-                            "supported, ignoring value");
-                }
-                int maxNumMeteringAreas = params.getMaxNumMeteringAreas();
-                List<Camera.Area> meteringAreaList = convertMeteringRegionsToLegacy(
-                        activeArray, zoomData, aeRegions, maxNumMeteringAreas,
-                        /*regionName*/"AE");
-
-                // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null).
-                if (maxNumMeteringAreas > 0) {
-                    params.setMeteringAreas(meteringAreaList);
-                }
-            }
-
-            // afRegions
-            {
-                MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS);
-                int maxNumFocusAreas = params.getMaxNumFocusAreas();
-                List<Camera.Area> focusAreaList = convertMeteringRegionsToLegacy(
-                        activeArray, zoomData, afRegions, maxNumFocusAreas,
-                        /*regionName*/"AF");
-
-                // WAR: for b/17252693, some devices can't handle params.setFocusAreas(null).
-                if (maxNumFocusAreas > 0) {
-                    params.setFocusAreas(focusAreaList);
-                }
-            }
-        }
-
-        // control.aeTargetFpsRange
-        Range<Integer> aeFpsRange = request.get(CONTROL_AE_TARGET_FPS_RANGE);
-        if (aeFpsRange != null) {
-            int[] legacyFps = convertAeFpsRangeToLegacy(aeFpsRange);
-
-            int[] rangeToApply = null;
-            for(int[] range : params.getSupportedPreviewFpsRange()) {
-                // Round range up/down to integer FPS value
-                int intRangeLow = (int) Math.floor(range[0] / 1000.0) * 1000;
-                int intRangeHigh = (int) Math.ceil(range[1] / 1000.0) * 1000;
-                if (legacyFps[0] == intRangeLow && legacyFps[1] == intRangeHigh) {
-                    rangeToApply = range;
-                    break;
-                }
-            }
-            if (rangeToApply != null) {
-                params.setPreviewFpsRange(rangeToApply[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
-                        rangeToApply[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
-            } else {
-                Log.w(TAG, "Unsupported FPS range set [" + legacyFps[0] + "," + legacyFps[1] + "]");
-            }
-        }
-
-        /*
-         * control
-         */
-
-        // control.aeExposureCompensation
-        {
-            Range<Integer> compensationRange =
-                    characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
-            int compensation = ParamsUtils.getOrDefault(request,
-                    CONTROL_AE_EXPOSURE_COMPENSATION,
-                    /*defaultValue*/0);
-
-            if (!compensationRange.contains(compensation)) {
-                Log.w(TAG,
-                        "convertRequestMetadata - control.aeExposureCompensation " +
-                        "is out of range, ignoring value");
-                compensation = 0;
-            }
-
-            params.setExposureCompensation(compensation);
-        }
-
-        // control.aeLock
-        {
-            Boolean aeLock = getIfSupported(request, CONTROL_AE_LOCK, /*defaultValue*/false,
-                    params.isAutoExposureLockSupported(),
-                    /*allowedValue*/false);
-
-            if (aeLock != null) {
-                params.setAutoExposureLock(aeLock);
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "convertRequestToMetadata - control.aeLock set to " + aeLock);
-            }
-
-            // TODO: Don't add control.aeLock to availableRequestKeys if it's not supported
-        }
-
-        // control.aeMode, flash.mode
-        mapAeAndFlashMode(request, /*out*/params);
-
-        // control.afMode
-        {
-            int afMode = ParamsUtils.getOrDefault(request, CONTROL_AF_MODE,
-                    /*defaultValue*/CONTROL_AF_MODE_OFF);
-            String focusMode = LegacyMetadataMapper.convertAfModeToLegacy(afMode,
-                    params.getSupportedFocusModes());
-
-            if (focusMode != null) {
-                params.setFocusMode(focusMode);
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "convertRequestToMetadata - control.afMode "
-                        + afMode + " mapped to " + focusMode);
-            }
-        }
-
-        // control.awbMode
-        {
-            Integer awbMode = getIfSupported(request, CONTROL_AWB_MODE,
-                    /*defaultValue*/CONTROL_AWB_MODE_AUTO,
-                    params.getSupportedWhiteBalance() != null,
-                    /*allowedValue*/CONTROL_AWB_MODE_AUTO);
-
-            String whiteBalanceMode = null;
-            if (awbMode != null) { // null iff AWB is not supported by camera1 api
-                whiteBalanceMode = convertAwbModeToLegacy(awbMode);
-                params.setWhiteBalance(whiteBalanceMode);
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, "convertRequestToMetadata - control.awbMode "
-                        + awbMode + " mapped to " + whiteBalanceMode);
-            }
-        }
-
-        // control.awbLock
-        {
-            Boolean awbLock = getIfSupported(request, CONTROL_AWB_LOCK, /*defaultValue*/false,
-                    params.isAutoWhiteBalanceLockSupported(),
-                    /*allowedValue*/false);
-
-            if (awbLock != null) {
-                params.setAutoWhiteBalanceLock(awbLock);
-            }
-
-         // TODO: Don't add control.awbLock to availableRequestKeys if it's not supported
-        }
-
-        // control.captureIntent
-        {
-            int captureIntent = ParamsUtils.getOrDefault(request,
-                    CONTROL_CAPTURE_INTENT,
-                    /*defaultValue*/CONTROL_CAPTURE_INTENT_PREVIEW);
-
-            captureIntent = filterSupportedCaptureIntent(captureIntent);
-
-            params.setRecordingHint(
-                    captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_RECORD ||
-                    captureIntent == CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
-        }
-
-        // control.videoStabilizationMode
-        {
-            Integer stabMode = getIfSupported(request, CONTROL_VIDEO_STABILIZATION_MODE,
-                    /*defaultValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF,
-                    params.isVideoStabilizationSupported(),
-                    /*allowedValue*/CONTROL_VIDEO_STABILIZATION_MODE_OFF);
-
-            if (stabMode != null) {
-                params.setVideoStabilization(stabMode == CONTROL_VIDEO_STABILIZATION_MODE_ON);
-            }
-        }
-
-        // lens.focusDistance
-        {
-            boolean infinityFocusSupported =
-                    ListUtils.listContains(params.getSupportedFocusModes(),
-                            Parameters.FOCUS_MODE_INFINITY);
-            Float focusDistance = getIfSupported(request, LENS_FOCUS_DISTANCE,
-                    /*defaultValue*/0f, infinityFocusSupported, /*allowedValue*/0f);
-
-            if (focusDistance == null || focusDistance != 0f) {
-                Log.w(TAG,
-                        "convertRequestToMetadata - Ignoring android.lens.focusDistance "
-                                + infinityFocusSupported + ", only 0.0f is supported");
-            }
-        }
-
-        // control.sceneMode, control.mode
-        {
-            // TODO: Map FACE_PRIORITY scene mode to face detection.
-
-            if (params.getSupportedSceneModes() != null) {
-                int controlMode = ParamsUtils.getOrDefault(request, CONTROL_MODE,
-                    /*defaultValue*/CONTROL_MODE_AUTO);
-                String modeToSet;
-                switch (controlMode) {
-                    case CONTROL_MODE_USE_SCENE_MODE: {
-                        int sceneMode = ParamsUtils.getOrDefault(request, CONTROL_SCENE_MODE,
-                                /*defaultValue*/CONTROL_SCENE_MODE_DISABLED);
-                        String legacySceneMode = LegacyMetadataMapper.
-                                convertSceneModeToLegacy(sceneMode);
-                        if (legacySceneMode != null) {
-                            modeToSet = legacySceneMode;
-                        } else {
-                            modeToSet = Parameters.SCENE_MODE_AUTO;
-                            Log.w(TAG, "Skipping unknown requested scene mode: " + sceneMode);
-                        }
-                        break;
-                    }
-                    case CONTROL_MODE_AUTO: {
-                        modeToSet = Parameters.SCENE_MODE_AUTO;
-                        break;
-                    }
-                    default: {
-                        Log.w(TAG, "Control mode " + controlMode +
-                                " is unsupported, defaulting to AUTO");
-                        modeToSet = Parameters.SCENE_MODE_AUTO;
-                    }
-                }
-                params.setSceneMode(modeToSet);
-            }
-        }
-
-        // control.effectMode
-        {
-            if (params.getSupportedColorEffects() != null) {
-                int effectMode = ParamsUtils.getOrDefault(request, CONTROL_EFFECT_MODE,
-                    /*defaultValue*/CONTROL_EFFECT_MODE_OFF);
-                String legacyEffectMode = LegacyMetadataMapper.convertEffectModeToLegacy(effectMode);
-                if (legacyEffectMode != null) {
-                    params.setColorEffect(legacyEffectMode);
-                } else {
-                    params.setColorEffect(Parameters.EFFECT_NONE);
-                    Log.w(TAG, "Skipping unknown requested effect mode: " + effectMode);
-                }
-            }
-        }
-
-        /*
-         * sensor
-         */
-
-        // sensor.testPattern
-        {
-            int testPatternMode = ParamsUtils.getOrDefault(request, SENSOR_TEST_PATTERN_MODE,
-                    /*defaultValue*/SENSOR_TEST_PATTERN_MODE_OFF);
-            if (testPatternMode != SENSOR_TEST_PATTERN_MODE_OFF) {
-                Log.w(TAG, "convertRequestToMetadata - ignoring sensor.testPatternMode "
-                        + testPatternMode + "; only OFF is supported");
-            }
-        }
-
-        /*
-         * jpeg.*
-         */
-
-        // jpeg.gpsLocation
-        {
-            Location location = request.get(JPEG_GPS_LOCATION);
-            if (location != null) {
-                if (checkForCompleteGpsData(location)) {
-                    params.setGpsAltitude(location.getAltitude());
-                    params.setGpsLatitude(location.getLatitude());
-                    params.setGpsLongitude(location.getLongitude());
-                    params.setGpsProcessingMethod(location.getProvider().toUpperCase());
-                    params.setGpsTimestamp(location.getTime());
-                } else {
-                    Log.w(TAG, "Incomplete GPS parameters provided in location " + location);
-                }
-            } else {
-                params.removeGpsData();
-            }
-        }
-
-        // jpeg.orientation
-        {
-            Integer orientation = request.get(CaptureRequest.JPEG_ORIENTATION);
-            params.setRotation(ParamsUtils.getOrDefault(request, JPEG_ORIENTATION,
-                    (orientation == null) ? 0 : orientation));
-        }
-
-        // jpeg.quality
-        {
-            params.setJpegQuality(0xFF & ParamsUtils.getOrDefault(request, JPEG_QUALITY,
-                    DEFAULT_JPEG_QUALITY));
-        }
-
-        // jpeg.thumbnailQuality
-        {
-            params.setJpegThumbnailQuality(0xFF & ParamsUtils.getOrDefault(request,
-                    JPEG_THUMBNAIL_QUALITY, DEFAULT_JPEG_QUALITY));
-        }
-
-        // jpeg.thumbnailSize
-        {
-            List<Camera.Size> sizes = params.getSupportedJpegThumbnailSizes();
-
-            if (sizes != null && sizes.size() > 0) {
-                Size s = request.get(JPEG_THUMBNAIL_SIZE);
-                boolean invalidSize = (s == null) ? false : !ParameterUtils.containsSize(sizes,
-                        s.getWidth(), s.getHeight());
-                if (invalidSize) {
-                    Log.w(TAG, "Invalid JPEG thumbnail size set " + s + ", skipping thumbnail...");
-                }
-                if (s == null || invalidSize) {
-                    // (0,0) = "no thumbnail" in Camera API 1
-                    params.setJpegThumbnailSize(/*width*/0, /*height*/0);
-                } else {
-                    params.setJpegThumbnailSize(s.getWidth(), s.getHeight());
-                }
-            }
-        }
-
-        /*
-         * noiseReduction.*
-         */
-        // noiseReduction.mode
-        {
-            int mode = ParamsUtils.getOrDefault(request,
-                    NOISE_REDUCTION_MODE,
-                    /*defaultValue*/NOISE_REDUCTION_MODE_FAST);
-
-            if (mode != NOISE_REDUCTION_MODE_FAST &&
-                    mode != NOISE_REDUCTION_MODE_HIGH_QUALITY) {
-                Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
-                        "noiseReduction.mode = " + mode);
-            }
-        }
-    }
-
-    private static boolean checkForCompleteGpsData(Location location) {
-        return location != null && location.getProvider() != null && location.getTime() != 0;
-    }
-
-    static int filterSupportedCaptureIntent(int captureIntent) {
-        switch (captureIntent) {
-            case CONTROL_CAPTURE_INTENT_CUSTOM:
-            case CONTROL_CAPTURE_INTENT_PREVIEW:
-            case CONTROL_CAPTURE_INTENT_STILL_CAPTURE:
-            case CONTROL_CAPTURE_INTENT_VIDEO_RECORD:
-            case CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT:
-                break;
-            case CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG:
-            case CONTROL_CAPTURE_INTENT_MANUAL:
-                captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
-                Log.w(TAG, "Unsupported control.captureIntent value " + captureIntent
-                        + "; default to PREVIEW");
-            default:
-                captureIntent = CONTROL_CAPTURE_INTENT_PREVIEW;
-                Log.w(TAG, "Unknown control.captureIntent value " + captureIntent
-                        + "; default to PREVIEW");
-        }
-
-        return captureIntent;
-    }
-
-    private static List<Camera.Area> convertMeteringRegionsToLegacy(
-            Rect activeArray, ParameterUtils.ZoomData zoomData,
-            MeteringRectangle[] meteringRegions, int maxNumMeteringAreas, String regionName) {
-        if (meteringRegions == null || maxNumMeteringAreas <= 0) {
-            if (maxNumMeteringAreas > 0) {
-                return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT);
-            } else {
-                return null;
-            }
-        }
-
-        // Add all non-zero weight regions to the list
-        List<MeteringRectangle> meteringRectangleList = new ArrayList<>();
-        for (MeteringRectangle rect : meteringRegions) {
-            if (rect.getMeteringWeight() != MeteringRectangle.METERING_WEIGHT_DONT_CARE) {
-                meteringRectangleList.add(rect);
-            }
-        }
-
-        if (meteringRectangleList.size() == 0) {
-            Log.w(TAG, "Only received metering rectangles with weight 0.");
-            return Arrays.asList(ParameterUtils.CAMERA_AREA_DEFAULT);
-        }
-
-        // Ignore any regions beyond our maximum supported count
-        int countMeteringAreas =
-                Math.min(maxNumMeteringAreas, meteringRectangleList.size());
-        List<Camera.Area> meteringAreaList = new ArrayList<>(countMeteringAreas);
-
-        for (int i = 0; i < countMeteringAreas; ++i) {
-            MeteringRectangle rect = meteringRectangleList.get(i);
-
-            ParameterUtils.MeteringData meteringData =
-                    ParameterUtils.convertMeteringRectangleToLegacy(activeArray, rect, zoomData);
-            meteringAreaList.add(meteringData.meteringArea);
-        }
-
-        if (maxNumMeteringAreas < meteringRectangleList.size()) {
-            Log.w(TAG,
-                    "convertMeteringRegionsToLegacy - Too many requested " + regionName +
-                            " regions, ignoring all beyond the first " + maxNumMeteringAreas);
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "convertMeteringRegionsToLegacy - " + regionName + " areas = "
-                    + ParameterUtils.stringFromAreaList(meteringAreaList));
-        }
-
-        return meteringAreaList;
-    }
-
-    private static void mapAeAndFlashMode(CaptureRequest r, /*out*/Parameters p) {
-        int flashMode = ParamsUtils.getOrDefault(r, FLASH_MODE, FLASH_MODE_OFF);
-        int aeMode = ParamsUtils.getOrDefault(r, CONTROL_AE_MODE, CONTROL_AE_MODE_ON);
-
-        List<String> supportedFlashModes = p.getSupportedFlashModes();
-
-        String flashModeSetting = null;
-
-        // Flash is OFF by default, on cameras that support flash
-        if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_OFF)) {
-            flashModeSetting = Parameters.FLASH_MODE_OFF;
-        }
-
-        /*
-         * Map all of the control.aeMode* enums, but ignore AE_MODE_OFF since we never support it
-         */
-
-        // Ignore flash.mode controls unless aeMode == ON
-        if (aeMode == CONTROL_AE_MODE_ON) {
-            if (flashMode == FLASH_MODE_TORCH) {
-                    if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_TORCH)) {
-                        flashModeSetting = Parameters.FLASH_MODE_TORCH;
-                    } else {
-                        Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == TORCH;" +
-                                "camera does not support it");
-                    }
-            } else if (flashMode == FLASH_MODE_SINGLE) {
-                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
-                    flashModeSetting = Parameters.FLASH_MODE_ON;
-                } else {
-                    Log.w(TAG, "mapAeAndFlashMode - Ignore flash.mode == SINGLE;" +
-                            "camera does not support it");
-                }
-            } else {
-                // Use the default FLASH_MODE_OFF
-            }
-        } else if (aeMode == CONTROL_AE_MODE_ON_ALWAYS_FLASH) {
-                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_ON)) {
-                    flashModeSetting = Parameters.FLASH_MODE_ON;
-                } else {
-                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_ALWAYS_FLASH;" +
-                            "camera does not support it");
-                }
-        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH) {
-            if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_AUTO)) {
-                flashModeSetting = Parameters.FLASH_MODE_AUTO;
-            } else {
-                Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH;" +
-                        "camera does not support it");
-            }
-        } else if (aeMode == CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
-                if (ListUtils.listContains(supportedFlashModes, Parameters.FLASH_MODE_RED_EYE)) {
-                    flashModeSetting = Parameters.FLASH_MODE_RED_EYE;
-                } else {
-                    Log.w(TAG, "mapAeAndFlashMode - Ignore control.aeMode == ON_AUTO_FLASH_REDEYE;"
-                            + "camera does not support it");
-                }
-        } else {
-            // Default to aeMode == ON, flash = OFF
-        }
-
-        if (flashModeSetting != null) {
-            p.setFlashMode(flashModeSetting);
-        }
-
-        if (DEBUG) {
-                Log.v(TAG,
-                        "mapAeAndFlashMode - set flash.mode (api1) to " + flashModeSetting
-                        + ", requested (api2) " + flashMode
-                        + ", supported (api1) " + ListUtils.listToString(supportedFlashModes));
-        }
-    }
-
-    /**
-     * Returns null if the anti-banding mode enum is not supported.
-     */
-    private static String convertAeAntiBandingModeToLegacy(int mode) {
-        switch (mode) {
-            case CONTROL_AE_ANTIBANDING_MODE_OFF: {
-                return Parameters.ANTIBANDING_OFF;
-            }
-            case CONTROL_AE_ANTIBANDING_MODE_50HZ: {
-                return Parameters.ANTIBANDING_50HZ;
-            }
-            case CONTROL_AE_ANTIBANDING_MODE_60HZ: {
-                return Parameters.ANTIBANDING_60HZ;
-            }
-            case CONTROL_AE_ANTIBANDING_MODE_AUTO: {
-                return Parameters.ANTIBANDING_AUTO;
-            }
-            default: {
-                return null;
-            }
-        }
-    }
-
-    private static int[] convertAeFpsRangeToLegacy(Range<Integer> fpsRange) {
-        int[] legacyFps = new int[2];
-        legacyFps[Parameters.PREVIEW_FPS_MIN_INDEX] = fpsRange.getLower() * 1000;
-        legacyFps[Parameters.PREVIEW_FPS_MAX_INDEX] = fpsRange.getUpper() * 1000;
-        return legacyFps;
-    }
-
-    private static String convertAwbModeToLegacy(int mode) {
-        switch (mode) {
-            case CONTROL_AWB_MODE_AUTO:
-                return Camera.Parameters.WHITE_BALANCE_AUTO;
-            case CONTROL_AWB_MODE_INCANDESCENT:
-                return Camera.Parameters.WHITE_BALANCE_INCANDESCENT;
-            case CONTROL_AWB_MODE_FLUORESCENT:
-                return Camera.Parameters.WHITE_BALANCE_FLUORESCENT;
-            case CONTROL_AWB_MODE_WARM_FLUORESCENT:
-                return Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT;
-            case CONTROL_AWB_MODE_DAYLIGHT:
-                return Camera.Parameters.WHITE_BALANCE_DAYLIGHT;
-            case CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
-                return Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT;
-            case CONTROL_AWB_MODE_TWILIGHT:
-                return Camera.Parameters.WHITE_BALANCE_TWILIGHT;
-            case CONTROL_AWB_MODE_SHADE:
-                return Parameters.WHITE_BALANCE_SHADE;
-            default:
-                Log.w(TAG, "convertAwbModeToLegacy - unrecognized control.awbMode" + mode);
-                return Camera.Parameters.WHITE_BALANCE_AUTO;
-        }
-    }
-
-
-    /**
-     * Return {@code null} if the value is not supported, otherwise return the retrieved key's
-     * value from the request (or the default value if it wasn't set).
-     *
-     * <p>If the fetched value in the request is equivalent to {@code allowedValue},
-     * then omit the warning (e.g. turning off AF lock on a camera
-     * that always has the AF lock turned off is a silent no-op), but still return {@code null}.</p>
-     *
-     * <p>Logs a warning to logcat if the key is not supported by api1 camera device.</p.
-     */
-    private static <T> T getIfSupported(
-            CaptureRequest r, CaptureRequest.Key<T> key, T defaultValue, boolean isSupported,
-            T allowedValue) {
-        T val = ParamsUtils.getOrDefault(r, key, defaultValue);
-
-        if (!isSupported) {
-            if (!Objects.equals(val, allowedValue)) {
-                Log.w(TAG, key.getName() + " is not supported; ignoring requested value " + val);
-            }
-            return null;
-        }
-
-        return val;
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
deleted file mode 100644
index 09edf74..0000000
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.legacy.ParameterUtils.WeightedRectangle;
-import android.hardware.camera2.legacy.ParameterUtils.ZoomData;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.utils.ListUtils;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.util.Log;
-import android.util.Size;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.hardware.camera2.CaptureResult.*;
-
-/**
- * Provide legacy-specific implementations of camera2 CaptureResult for legacy devices.
- */
-@SuppressWarnings("deprecation")
-public class LegacyResultMapper {
-    private static final String TAG = "LegacyResultMapper";
-    private static final boolean DEBUG = false;
-
-    private LegacyRequest mCachedRequest = null;
-    private CameraMetadataNative mCachedResult = null;
-
-    /**
-     * Generate capture result metadata from the legacy camera request.
-     *
-     * <p>This method caches and reuses the result from the previous call to this method if
-     * the {@code parameters} of the subsequent {@link LegacyRequest} passed to this method
-     * have not changed.</p>
-     *
-     * @param legacyRequest a non-{@code null} legacy request containing the latest parameters
-     * @param timestamp the timestamp to use for this result in nanoseconds.
-     *
-     * @return {@link CameraMetadataNative} object containing result metadata.
-     */
-    public CameraMetadataNative cachedConvertResultMetadata(
-            LegacyRequest legacyRequest, long timestamp) {
-        CameraMetadataNative result;
-        boolean cached;
-
-        /*
-         * Attempt to look up the result from the cache if the parameters haven't changed
-         */
-        if (mCachedRequest != null &&
-                legacyRequest.parameters.same(mCachedRequest.parameters) &&
-                legacyRequest.captureRequest.equals(mCachedRequest.captureRequest)) {
-            result = new CameraMetadataNative(mCachedResult);
-            cached = true;
-        } else {
-            result = convertResultMetadata(legacyRequest);
-            cached = false;
-
-            // Always cache a *copy* of the metadata result,
-            // since api2's client side takes ownership of it after it receives a result
-            mCachedRequest = legacyRequest;
-            mCachedResult = new CameraMetadataNative(result);
-        }
-
-        /*
-         * Unconditionally set fields that change in every single frame
-         */
-        {
-            // sensor.timestamp
-            result.set(SENSOR_TIMESTAMP, timestamp);
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "cachedConvertResultMetadata - cached? " + cached +
-                    " timestamp = " + timestamp);
-
-            Log.v(TAG, "----- beginning of result dump ------");
-            result.dumpToLog();
-            Log.v(TAG, "----- end of result dump ------");
-        }
-
-        return result;
-    }
-
-    /**
-     * Generate capture result metadata from the legacy camera request.
-     *
-     * @param legacyRequest a non-{@code null} legacy request containing the latest parameters
-     * @return a {@link CameraMetadataNative} object containing result metadata.
-     */
-    private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest) {
-        CameraCharacteristics characteristics = legacyRequest.characteristics;
-        CaptureRequest request = legacyRequest.captureRequest;
-        Size previewSize = legacyRequest.previewSize;
-        Camera.Parameters params = legacyRequest.parameters;
-
-        CameraMetadataNative result = new CameraMetadataNative();
-
-        Rect activeArraySize = characteristics.get(
-                CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-        ZoomData zoomData = ParameterUtils.convertToLegacyZoom(activeArraySize,
-                request.get(CaptureRequest.SCALER_CROP_REGION),
-                request.get(CaptureRequest.CONTROL_ZOOM_RATIO),
-                previewSize, params);
-
-        /*
-         * colorCorrection
-         */
-        // colorCorrection.aberrationMode
-        {
-            result.set(COLOR_CORRECTION_ABERRATION_MODE,
-                    request.get(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE));
-        }
-
-        /*
-         * control
-         */
-
-        /*
-         * control.ae*
-         */
-        mapAe(result, characteristics, request, activeArraySize, zoomData, /*out*/params);
-
-        /*
-         * control.af*
-         */
-        mapAf(result, activeArraySize, zoomData, /*out*/params);
-
-        /*
-         * control.awb*
-         */
-        mapAwb(result, /*out*/params);
-
-        /*
-         * control.captureIntent
-         */
-        {
-            int captureIntent = ParamsUtils.getOrDefault(request,
-                    CaptureRequest.CONTROL_CAPTURE_INTENT,
-                    /*defaultValue*/CaptureRequest.CONTROL_CAPTURE_INTENT_PREVIEW);
-
-            captureIntent = LegacyRequestMapper.filterSupportedCaptureIntent(captureIntent);
-
-            result.set(CONTROL_CAPTURE_INTENT, captureIntent);
-        }
-
-        /*
-         * control.mode
-         */
-        {
-            int controlMode = ParamsUtils.getOrDefault(request, CaptureRequest.CONTROL_MODE,
-                    CONTROL_MODE_AUTO);
-            if (controlMode == CaptureResult.CONTROL_MODE_USE_SCENE_MODE) {
-                result.set(CONTROL_MODE, CONTROL_MODE_USE_SCENE_MODE);
-            } else {
-                result.set(CONTROL_MODE, CONTROL_MODE_AUTO);
-            }
-        }
-
-        /*
-         * control.sceneMode
-         */
-        {
-            String legacySceneMode = params.getSceneMode();
-            int mode = LegacyMetadataMapper.convertSceneModeFromLegacy(legacySceneMode);
-            if (mode != LegacyMetadataMapper.UNKNOWN_MODE) {
-                result.set(CaptureResult.CONTROL_SCENE_MODE, mode);
-                // In case of SCENE_MODE == FACE_PRIORITY, LegacyFaceDetectMapper will override
-                // the result to say SCENE_MODE == FACE_PRIORITY.
-            }  else {
-                Log.w(TAG, "Unknown scene mode " + legacySceneMode +
-                        " returned by camera HAL, setting to disabled.");
-                result.set(CaptureResult.CONTROL_SCENE_MODE, CONTROL_SCENE_MODE_DISABLED);
-            }
-        }
-
-        /*
-         * control.effectMode
-         */
-        {
-            String legacyEffectMode = params.getColorEffect();
-            int mode = LegacyMetadataMapper.convertEffectModeFromLegacy(legacyEffectMode);
-            if (mode != LegacyMetadataMapper.UNKNOWN_MODE) {
-                result.set(CaptureResult.CONTROL_EFFECT_MODE, mode);
-            } else {
-                Log.w(TAG, "Unknown effect mode " + legacyEffectMode +
-                        " returned by camera HAL, setting to off.");
-                result.set(CaptureResult.CONTROL_EFFECT_MODE, CONTROL_EFFECT_MODE_OFF);
-            }
-        }
-
-        // control.videoStabilizationMode
-        {
-            int stabMode =
-                    (params.isVideoStabilizationSupported() && params.getVideoStabilization()) ?
-                        CONTROL_VIDEO_STABILIZATION_MODE_ON :
-                        CONTROL_VIDEO_STABILIZATION_MODE_OFF;
-            result.set(CONTROL_VIDEO_STABILIZATION_MODE, stabMode);
-        }
-
-        /*
-         * flash
-         */
-        {
-            // flash.mode, flash.state mapped in mapAeAndFlashMode
-        }
-
-        /*
-         * lens
-         */
-        // lens.focusDistance
-        {
-            if (Parameters.FOCUS_MODE_INFINITY.equals(params.getFocusMode())) {
-                result.set(CaptureResult.LENS_FOCUS_DISTANCE, 0.0f);
-            }
-        }
-
-        // lens.focalLength
-        result.set(CaptureResult.LENS_FOCAL_LENGTH, params.getFocalLength());
-
-        /*
-         * request
-         */
-        // request.pipelineDepth
-        result.set(REQUEST_PIPELINE_DEPTH,
-                characteristics.get(CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH));
-
-        /*
-         * scaler
-         */
-        mapScaler(result, zoomData, /*out*/params);
-
-        /*
-         * sensor
-         */
-        // sensor.timestamp varies every frame; mapping is done in #cachedConvertResultMetadata
-        {
-            // Unconditionally no test patterns
-            result.set(SENSOR_TEST_PATTERN_MODE, SENSOR_TEST_PATTERN_MODE_OFF);
-        }
-
-        /*
-         * jpeg
-         */
-        // jpeg.gpsLocation
-        result.set(JPEG_GPS_LOCATION, request.get(CaptureRequest.JPEG_GPS_LOCATION));
-
-        // jpeg.orientation
-        result.set(JPEG_ORIENTATION, request.get(CaptureRequest.JPEG_ORIENTATION));
-
-        // jpeg.quality
-        result.set(JPEG_QUALITY, (byte) params.getJpegQuality());
-
-        // jpeg.thumbnailQuality
-        result.set(JPEG_THUMBNAIL_QUALITY, (byte) params.getJpegThumbnailQuality());
-
-        // jpeg.thumbnailSize
-        Camera.Size s = params.getJpegThumbnailSize();
-        if (s != null) {
-            result.set(JPEG_THUMBNAIL_SIZE, ParameterUtils.convertSize(s));
-        } else {
-            Log.w(TAG, "Null thumbnail size received from parameters.");
-        }
-
-        /*
-         * noiseReduction.*
-         */
-        // noiseReduction.mode
-        result.set(NOISE_REDUCTION_MODE, request.get(CaptureRequest.NOISE_REDUCTION_MODE));
-
-        return result;
-    }
-
-    private static void mapAe(CameraMetadataNative m,
-            CameraCharacteristics characteristics,
-            CaptureRequest request, Rect activeArray, ZoomData zoomData, /*out*/Parameters p) {
-        // control.aeAntiBandingMode
-        {
-            int antiBandingMode = LegacyMetadataMapper.convertAntiBandingModeOrDefault(
-                    p.getAntibanding());
-            m.set(CONTROL_AE_ANTIBANDING_MODE, antiBandingMode);
-        }
-
-        // control.aeExposureCompensation
-        {
-            m.set(CONTROL_AE_EXPOSURE_COMPENSATION, p.getExposureCompensation());
-        }
-
-        // control.aeLock
-        {
-            boolean lock = p.isAutoExposureLockSupported() ? p.getAutoExposureLock() : false;
-            m.set(CONTROL_AE_LOCK, lock);
-            if (DEBUG) {
-                Log.v(TAG,
-                        "mapAe - android.control.aeLock = " + lock +
-                        ", supported = " + p.isAutoExposureLockSupported());
-            }
-
-            Boolean requestLock = request.get(CaptureRequest.CONTROL_AE_LOCK);
-            if (requestLock != null && requestLock != lock) {
-                Log.w(TAG,
-                        "mapAe - android.control.aeLock was requested to " + requestLock +
-                        " but resulted in " + lock);
-            }
-        }
-
-        // control.aeMode, flash.mode, flash.state
-        mapAeAndFlashMode(m, characteristics, p);
-
-        // control.aeState
-        if (LegacyMetadataMapper.LIE_ABOUT_AE_STATE) {
-            // Lie to pass CTS temporarily.
-            // TODO: Implement precapture trigger, after which we can report CONVERGED ourselves
-            m.set(CONTROL_AE_STATE, CONTROL_AE_STATE_CONVERGED);
-        }
-
-        // control.aeRegions
-        if (p.getMaxNumMeteringAreas() > 0) {
-            if (DEBUG) {
-                String meteringAreas = p.get("metering-areas");
-                Log.v(TAG, "mapAe - parameter dump; metering-areas: " + meteringAreas);
-            }
-
-            MeteringRectangle[] meteringRectArray = getMeteringRectangles(activeArray,
-                    zoomData, p.getMeteringAreas(), "AE");
-
-            m.set(CONTROL_AE_REGIONS, meteringRectArray);
-        }
-
-    }
-
-    private static void mapAf(CameraMetadataNative m,
-            Rect activeArray, ZoomData zoomData, Camera.Parameters p) {
-        // control.afMode
-        m.set(CaptureResult.CONTROL_AF_MODE, convertLegacyAfMode(p.getFocusMode()));
-
-        // control.afRegions
-        if (p.getMaxNumFocusAreas() > 0) {
-            if (DEBUG) {
-                String focusAreas = p.get("focus-areas");
-                Log.v(TAG, "mapAe - parameter dump; focus-areas: " + focusAreas);
-            }
-
-            MeteringRectangle[] meteringRectArray = getMeteringRectangles(activeArray,
-                    zoomData, p.getFocusAreas(), "AF");
-
-            m.set(CONTROL_AF_REGIONS, meteringRectArray);
-        }
-    }
-
-    private static void mapAwb(CameraMetadataNative m, Camera.Parameters p) {
-        // control.awbLock
-        {
-            boolean lock = p.isAutoWhiteBalanceLockSupported() ?
-                    p.getAutoWhiteBalanceLock() : false;
-            m.set(CONTROL_AWB_LOCK, lock);
-        }
-
-        // control.awbMode
-        {
-            int awbMode = convertLegacyAwbMode(p.getWhiteBalance());
-            m.set(CONTROL_AWB_MODE, awbMode);
-        }
-    }
-
-    private static MeteringRectangle[] getMeteringRectangles(Rect activeArray, ZoomData zoomData,
-            List<Camera.Area> meteringAreaList, String regionName) {
-        List<MeteringRectangle> meteringRectList = new ArrayList<>();
-        if (meteringAreaList != null) {
-            for (Camera.Area area : meteringAreaList) {
-                WeightedRectangle rect =
-                        ParameterUtils.convertCameraAreaToActiveArrayRectangle(
-                                activeArray, zoomData, area);
-
-                meteringRectList.add(rect.toMetering());
-            }
-        }
-
-        if (DEBUG) {
-            Log.v(TAG,
-                    "Metering rectangles for " + regionName + ": "
-                     + ListUtils.listToString(meteringRectList));
-        }
-
-        return meteringRectList.toArray(new MeteringRectangle[0]);
-    }
-
-    /** Map results for control.aeMode, flash.mode, flash.state */
-    private static void mapAeAndFlashMode(CameraMetadataNative m,
-            CameraCharacteristics characteristics, Parameters p) {
-        // Default: AE mode on but flash never fires
-        int flashMode = FLASH_MODE_OFF;
-        // If there is no flash on this camera, the state is always unavailable
-        // , otherwise it's only known for TORCH/SINGLE modes
-        Integer flashState = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)
-                ? null : FLASH_STATE_UNAVAILABLE;
-        int aeMode = CONTROL_AE_MODE_ON;
-
-        String flashModeSetting = p.getFlashMode();
-
-        if (flashModeSetting != null) {
-            switch (flashModeSetting) {
-                case Parameters.FLASH_MODE_OFF:
-                    break; // ok, using default
-                case Parameters.FLASH_MODE_AUTO:
-                    aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH;
-                    break;
-                case Parameters.FLASH_MODE_ON:
-                    // flashMode = SINGLE + aeMode = ON is indistinguishable from ON_ALWAYS_FLASH
-                    flashMode = FLASH_MODE_SINGLE;
-                    aeMode = CONTROL_AE_MODE_ON_ALWAYS_FLASH;
-                    flashState = FLASH_STATE_FIRED;
-                    break;
-                case Parameters.FLASH_MODE_RED_EYE:
-                    aeMode = CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE;
-                    break;
-                case Parameters.FLASH_MODE_TORCH:
-                    flashMode = FLASH_MODE_TORCH;
-                    flashState = FLASH_STATE_FIRED;
-                    break;
-                default:
-                    Log.w(TAG,
-                            "mapAeAndFlashMode - Ignoring unknown flash mode " + p.getFlashMode());
-            }
-        }
-
-        // flash.state
-        m.set(FLASH_STATE, flashState);
-        // flash.mode
-        m.set(FLASH_MODE, flashMode);
-        // control.aeMode
-        m.set(CONTROL_AE_MODE, aeMode);
-    }
-
-    private static int convertLegacyAfMode(String mode) {
-        if (mode == null) {
-            Log.w(TAG, "convertLegacyAfMode - no AF mode, default to OFF");
-            return CONTROL_AF_MODE_OFF;
-        }
-
-        switch (mode) {
-            case Parameters.FOCUS_MODE_AUTO:
-                return CONTROL_AF_MODE_AUTO;
-            case Parameters.FOCUS_MODE_CONTINUOUS_PICTURE:
-                return CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-            case Parameters.FOCUS_MODE_CONTINUOUS_VIDEO:
-                return CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-            case Parameters.FOCUS_MODE_EDOF:
-                return CONTROL_AF_MODE_EDOF;
-            case Parameters.FOCUS_MODE_MACRO:
-                return CONTROL_AF_MODE_MACRO;
-            case Parameters.FOCUS_MODE_FIXED:
-                return CONTROL_AF_MODE_OFF;
-            case Parameters.FOCUS_MODE_INFINITY:
-                return CONTROL_AF_MODE_OFF;
-            default:
-                Log.w(TAG, "convertLegacyAfMode - unknown mode " + mode + " , ignoring");
-                return CONTROL_AF_MODE_OFF;
-        }
-    }
-
-    private static int convertLegacyAwbMode(String mode) {
-        if (mode == null) {
-            // OK: camera1 api may not support changing WB modes; assume AUTO
-            return CONTROL_AWB_MODE_AUTO;
-        }
-
-        switch (mode) {
-            case Camera.Parameters.WHITE_BALANCE_AUTO:
-                return CONTROL_AWB_MODE_AUTO;
-            case Camera.Parameters.WHITE_BALANCE_INCANDESCENT:
-                return CONTROL_AWB_MODE_INCANDESCENT;
-            case Camera.Parameters.WHITE_BALANCE_FLUORESCENT:
-                return CONTROL_AWB_MODE_FLUORESCENT;
-            case Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT:
-                return CONTROL_AWB_MODE_WARM_FLUORESCENT;
-            case Camera.Parameters.WHITE_BALANCE_DAYLIGHT:
-                return CONTROL_AWB_MODE_DAYLIGHT;
-            case Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT:
-                return CONTROL_AWB_MODE_CLOUDY_DAYLIGHT;
-            case Camera.Parameters.WHITE_BALANCE_TWILIGHT:
-                return CONTROL_AWB_MODE_TWILIGHT;
-            case Camera.Parameters.WHITE_BALANCE_SHADE:
-                return CONTROL_AWB_MODE_SHADE;
-            default:
-                Log.w(TAG, "convertAwbMode - unrecognized WB mode " + mode);
-                return CONTROL_AWB_MODE_AUTO;
-        }
-    }
-
-    /** Map results for scaler.* */
-    private static void mapScaler(CameraMetadataNative m,
-            ZoomData zoomData,
-            /*out*/Parameters p) {
-        /*
-         * scaler.cropRegion
-         */
-        {
-            m.set(SCALER_CROP_REGION, zoomData.reportedCrop);
-        }
-
-        /*
-         * control.zoomRatio
-         */
-        {
-            m.set(CONTROL_ZOOM_RATIO, zoomData.reportedZoomRatio);
-        }
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/ParameterUtils.java b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
deleted file mode 100644
index eb43598..0000000
--- a/core/java/android/hardware/camera2/legacy/ParameterUtils.java
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.Matrix;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.Camera;
-import android.hardware.Camera.Area;
-import android.hardware.camera2.params.Face;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.utils.ListUtils;
-import android.hardware.camera2.utils.ParamsUtils;
-import android.hardware.camera2.utils.SizeAreaComparator;
-import android.util.Size;
-import android.util.SizeF;
-
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Various utilities for dealing with camera API1 parameters.
- */
-@SuppressWarnings("deprecation")
-public class ParameterUtils {
-    /** Upper/left minimal point of a normalized rectangle */
-    public static final int NORMALIZED_RECTANGLE_MIN = -1000;
-    /** Lower/right maximal point of a normalized rectangle */
-    public static final int NORMALIZED_RECTANGLE_MAX = 1000;
-    /** The default normalized rectangle spans the entire size of the preview viewport */
-    public static final Rect NORMALIZED_RECTANGLE_DEFAULT = new Rect(
-            NORMALIZED_RECTANGLE_MIN,
-            NORMALIZED_RECTANGLE_MIN,
-            NORMALIZED_RECTANGLE_MAX,
-            NORMALIZED_RECTANGLE_MAX);
-    /** The default normalized area uses the default normalized rectangle with a weight=1 */
-    public static final Camera.Area CAMERA_AREA_DEFAULT =
-            new Camera.Area(new Rect(NORMALIZED_RECTANGLE_DEFAULT),
-                            /*weight*/1);
-    /** Empty rectangle {@code 0x0+0,0} */
-    public static final Rect RECTANGLE_EMPTY =
-            new Rect(/*left*/0, /*top*/0, /*right*/0, /*bottom*/0);
-
-    private static final double ASPECT_RATIO_TOLERANCE = 0.05f;
-
-    /**
-     * Calculate effective/reported zoom data from a user-specified crop region.
-     */
-    public static class ZoomData {
-        /** Zoom index used by {@link Camera.Parameters#setZoom} */
-        public final int zoomIndex;
-        /** Effective crop-region given the zoom index, coordinates relative to active-array */
-        public final Rect previewCrop;
-        /** Reported crop-region given the zoom index, coordinates relative to active-array */
-        public final Rect reportedCrop;
-        /** Reported zoom ratio given the zoom index */
-        public final float reportedZoomRatio;
-
-        public ZoomData(int zoomIndex, Rect previewCrop, Rect reportedCrop,
-                float reportedZoomRatio) {
-            this.zoomIndex = zoomIndex;
-            this.previewCrop = previewCrop;
-            this.reportedCrop = reportedCrop;
-            this.reportedZoomRatio = reportedZoomRatio;
-        }
-    }
-
-    /**
-     * Calculate effective/reported metering data from a user-specified metering region.
-     */
-    public static class MeteringData {
-        /**
-         * The metering area scaled to the range of [-1000, 1000].
-         * <p>Values outside of this range are clipped to be within the range.</p>
-         */
-        public final Camera.Area meteringArea;
-        /**
-         * Effective preview metering region, coordinates relative to active-array.
-         *
-         * <p>Clipped to fit inside of the (effective) preview crop region.</p>
-         */
-        public final Rect previewMetering;
-        /**
-         * Reported metering region, coordinates relative to active-array.
-         *
-         * <p>Clipped to fit inside of the (reported) resulting crop region.</p>
-         */
-        public final Rect reportedMetering;
-
-        public MeteringData(Area meteringArea, Rect previewMetering, Rect reportedMetering) {
-            this.meteringArea = meteringArea;
-            this.previewMetering = previewMetering;
-            this.reportedMetering = reportedMetering;
-        }
-    }
-
-    /**
-     * A weighted rectangle is an arbitrary rectangle (the coordinate system is unknown) with an
-     * arbitrary weight.
-     *
-     * <p>The user of this class must know what the coordinate system ahead of time; it's
-     * then possible to convert to a more concrete type such as a metering rectangle or a face.
-     * </p>
-     *
-     * <p>When converting to a more concrete type, out-of-range values are clipped; this prevents
-     * possible illegal argument exceptions being thrown at runtime.</p>
-     */
-    public static class WeightedRectangle {
-        /** Arbitrary rectangle (the range is user-defined); never {@code null}. */
-        public final Rect rect;
-        /** Arbitrary weight (the range is user-defined). */
-        public final int weight;
-
-        /**
-         * Create a new weighted-rectangle from a non-{@code null} rectangle; the {@code weight}
-         * can be unbounded.
-         */
-        public WeightedRectangle(Rect rect, int weight) {
-            this.rect = checkNotNull(rect, "rect must not be null");
-            this.weight = weight;
-        }
-
-        /**
-         * Convert to a metering rectangle, clipping any of the values to stay within range.
-         *
-         * <p>If values are clipped, a warning is printed to logcat.</p>
-         *
-         * @return a new metering rectangle
-         */
-        public MeteringRectangle toMetering() {
-            int weight = clip(this.weight,
-                    MeteringRectangle.METERING_WEIGHT_MIN,
-                    MeteringRectangle.METERING_WEIGHT_MAX,
-                    rect,
-                    "weight");
-
-            int x = clipLower(rect.left, /*lo*/0, rect, "left");
-            int y = clipLower(rect.top, /*lo*/0, rect, "top");
-            int w = clipLower(rect.width(), /*lo*/0, rect, "width");
-            int h = clipLower(rect.height(), /*lo*/0, rect, "height");
-
-            return new MeteringRectangle(x, y, w, h, weight);
-        }
-
-        /**
-         * Convert to a face; the rect is considered to be the bounds, and the weight
-         * is considered to be the score.
-         *
-         * <p>If the score is out of range of {@value Face#SCORE_MIN}, {@value Face#SCORE_MAX},
-         * the score is clipped first and a warning is printed to logcat.</p>
-         *
-         * <p>If the id is negative, the id is changed to 0 and a warning is printed to
-         * logcat.</p>
-         *
-         * <p>All other parameters are passed-through as-is.</p>
-         *
-         * @return a new face with the optional features set
-         */
-        public Face toFace(
-                int id, Point leftEyePosition, Point rightEyePosition, Point mouthPosition) {
-            int idSafe = clipLower(id, /*lo*/0, rect, "id");
-            int score = clip(weight,
-                    Face.SCORE_MIN,
-                    Face.SCORE_MAX,
-                    rect,
-                    "score");
-
-            return new Face(rect, score, idSafe, leftEyePosition, rightEyePosition, mouthPosition);
-        }
-
-        /**
-         * Convert to a face; the rect is considered to be the bounds, and the weight
-         * is considered to be the score.
-         *
-         * <p>If the score is out of range of {@value Face#SCORE_MIN}, {@value Face#SCORE_MAX},
-         * the score is clipped first and a warning is printed to logcat.</p>
-         *
-         * <p>All other parameters are passed-through as-is.</p>
-         *
-         * @return a new face without the optional features
-         */
-        public Face toFace() {
-            int score = clip(weight,
-                    Face.SCORE_MIN,
-                    Face.SCORE_MAX,
-                    rect,
-                    "score");
-
-            return new Face(rect, score);
-        }
-
-        private static int clipLower(int value, int lo, Rect rect, String name) {
-            return clip(value, lo, /*hi*/Integer.MAX_VALUE, rect, name);
-        }
-
-        private static int clip(int value, int lo, int hi, Rect rect, String name) {
-            if (value < lo) {
-                Log.w(TAG, "toMetering - Rectangle " + rect + " "
-                        + name + " too small, clip to " + lo);
-                value = lo;
-            } else if (value > hi) {
-                Log.w(TAG, "toMetering - Rectangle " + rect + " "
-                        + name + " too small, clip to " + hi);
-                value = hi;
-            }
-
-            return value;
-        }
-    }
-
-    private static final String TAG = "ParameterUtils";
-    private static final boolean DEBUG = false;
-
-    /** getZoomRatios stores zoom ratios in 1/100 increments, e.x. a zoom of 3.2 is 320 */
-    private static final int ZOOM_RATIO_MULTIPLIER = 100;
-
-    /**
-     * Convert a camera API1 size into a util size
-     */
-    public static Size convertSize(Camera.Size size) {
-        checkNotNull(size, "size must not be null");
-
-        return new Size(size.width, size.height);
-    }
-
-    /**
-     * Convert a camera API1 list of sizes into a util list of sizes
-     */
-    public static List<Size> convertSizeList(List<Camera.Size> sizeList) {
-        checkNotNull(sizeList, "sizeList must not be null");
-
-        List<Size> sizes = new ArrayList<>(sizeList.size());
-        for (Camera.Size s : sizeList) {
-            sizes.add(new Size(s.width, s.height));
-        }
-        return sizes;
-    }
-
-    /**
-     * Convert a camera API1 list of sizes into an array of sizes
-     */
-    public static Size[] convertSizeListToArray(List<Camera.Size> sizeList) {
-        checkNotNull(sizeList, "sizeList must not be null");
-
-        Size[] array = new Size[sizeList.size()];
-        int ctr = 0;
-        for (Camera.Size s : sizeList) {
-            array[ctr++] = new Size(s.width, s.height);
-        }
-        return array;
-    }
-
-    /**
-     * Check if the camera API1 list of sizes contains a size with the given dimens.
-     */
-    public static boolean containsSize(List<Camera.Size> sizeList, int width, int height) {
-        checkNotNull(sizeList, "sizeList must not be null");
-        for (Camera.Size s : sizeList) {
-            if (s.height == height && s.width == width) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the largest supported picture size, as compared by its area.
-     */
-    public static Size getLargestSupportedJpegSizeByArea(Camera.Parameters params) {
-        checkNotNull(params, "params must not be null");
-
-        List<Size> supportedJpegSizes = convertSizeList(params.getSupportedPictureSizes());
-        return SizeAreaComparator.findLargestByArea(supportedJpegSizes);
-    }
-
-    /**
-     * Convert a camera area into a human-readable string.
-     */
-    public static String stringFromArea(Camera.Area area) {
-        if (area == null) {
-            return null;
-        } else {
-            StringBuilder sb = new StringBuilder();
-            Rect r = area.rect;
-
-            sb.setLength(0);
-            sb.append("(["); sb.append(r.left); sb.append(',');
-            sb.append(r.top); sb.append("]["); sb.append(r.right);
-            sb.append(','); sb.append(r.bottom); sb.append(']');
-
-            sb.append(',');
-            sb.append(area.weight);
-            sb.append(')');
-
-            return sb.toString();
-        }
-    }
-
-    /**
-     * Convert a camera area list into a human-readable string
-     * @param areaList a list of areas (null is ok)
-     */
-    public static String stringFromAreaList(List<Camera.Area> areaList) {
-        StringBuilder sb = new StringBuilder();
-
-        if (areaList == null) {
-            return null;
-        }
-
-        int i = 0;
-        for (Camera.Area area : areaList) {
-            if (area == null) {
-                sb.append("null");
-            } else {
-                sb.append(stringFromArea(area));
-            }
-
-            if (i != areaList.size() - 1) {
-                sb.append(", ");
-            }
-
-            i++;
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Calculate the closest zoom index for the user-requested crop region by rounding
-     * up to the closest (largest or equal) possible zoom crop.
-     *
-     * <p>If the requested crop region exceeds the size of the active array, it is
-     * shrunk to fit inside of the active array first.</p>
-     *
-     * <p>Since all api1 camera devices only support a discrete set of zooms, we have
-     * to translate the per-pixel-granularity requested crop region into a per-zoom-index
-     * granularity.</p>
-     *
-     * <p>Furthermore, since the zoom index and zoom levels also depends on the field-of-view
-     * of the preview, the current preview {@code streamSize} is also used.</p>
-     *
-     * <p>The calculated crop regions are then written to in-place to {@code reportedCropRegion}
-     * and {@code previewCropRegion}, in coordinates relative to the active array.</p>
-     *
-     * @param params non-{@code null} camera api1 parameters
-     * @param activeArray active array dimensions, in sensor space
-     * @param streamSize stream size dimensions, in pixels
-     * @param cropRegion user-specified crop region, in active array coordinates
-     * @param reportedCropRegion (out parameter) what the result for {@code cropRegion} looks like
-     * @param previewCropRegion (out parameter) what the visual preview crop is
-     * @return
-     *          the zoom index inclusively between 0 and {@code Parameters#getMaxZoom},
-     *          where 0 means the camera is not zoomed
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     */
-    public static int getClosestAvailableZoomCrop(
-            Camera.Parameters params, Rect activeArray,
-            Size streamSize, Rect cropRegion,
-            /*out*/
-            Rect reportedCropRegion,
-            Rect previewCropRegion) {
-        checkNotNull(params, "params must not be null");
-        checkNotNull(activeArray, "activeArray must not be null");
-        checkNotNull(streamSize, "streamSize must not be null");
-        checkNotNull(reportedCropRegion, "reportedCropRegion must not be null");
-        checkNotNull(previewCropRegion, "previewCropRegion must not be null");
-
-        Rect actualCrop = new Rect(cropRegion);
-
-        /*
-         * Shrink requested crop region to fit inside of the active array size
-         */
-        if (!actualCrop.intersect(activeArray)) {
-            Log.w(TAG, "getClosestAvailableZoomCrop - Crop region out of range; " +
-                    "setting to active array size");
-            actualCrop.set(activeArray);
-        }
-
-        Rect previewCrop = getPreviewCropRectangleUnzoomed(activeArray, streamSize);
-
-        // Make the user-requested crop region the same aspect ratio as the preview stream size
-        Rect cropRegionAsPreview =
-                shrinkToSameAspectRatioCentered(previewCrop, actualCrop);
-
-        if (DEBUG) {
-            Log.v(TAG, "getClosestAvailableZoomCrop - actualCrop = " + actualCrop);
-            Log.v(TAG,
-                    "getClosestAvailableZoomCrop - previewCrop = " + previewCrop);
-            Log.v(TAG,
-                    "getClosestAvailableZoomCrop - cropRegionAsPreview = " + cropRegionAsPreview);
-        }
-
-        /*
-         * Iterate all available zoom rectangles and find the closest zoom index
-         */
-        Rect bestReportedCropRegion = null;
-        Rect bestPreviewCropRegion = null;
-        int bestZoomIndex = -1;
-
-        List<Rect> availableReportedCropRegions =
-                getAvailableZoomCropRectangles(params, activeArray);
-        List<Rect> availablePreviewCropRegions =
-                getAvailablePreviewZoomCropRectangles(params, activeArray, streamSize);
-
-        if (DEBUG) {
-            Log.v(TAG,
-                    "getClosestAvailableZoomCrop - availableReportedCropRegions = " +
-                            ListUtils.listToString(availableReportedCropRegions));
-            Log.v(TAG,
-                    "getClosestAvailableZoomCrop - availablePreviewCropRegions = " +
-                            ListUtils.listToString(availablePreviewCropRegions));
-        }
-
-        if (availableReportedCropRegions.size() != availablePreviewCropRegions.size()) {
-            throw new AssertionError("available reported/preview crop region size mismatch");
-        }
-
-        for (int i = 0; i < availableReportedCropRegions.size(); ++i) {
-            Rect currentPreviewCropRegion = availablePreviewCropRegions.get(i);
-            Rect currentReportedCropRegion = availableReportedCropRegions.get(i);
-
-            boolean isBest;
-            if (bestZoomIndex == -1) {
-                isBest = true;
-            } else if (currentPreviewCropRegion.width() >= cropRegionAsPreview.width() &&
-                    currentPreviewCropRegion.height() >= cropRegionAsPreview.height()) {
-                isBest = true;
-            } else {
-                isBest = false;
-            }
-
-            // Sizes are sorted largest-to-smallest, so once the available crop is too small,
-            // we the rest are too small. Furthermore, this is the final best crop,
-            // since its the largest crop that still fits the requested crop
-            if (isBest) {
-                bestPreviewCropRegion = currentPreviewCropRegion;
-                bestReportedCropRegion = currentReportedCropRegion;
-                bestZoomIndex = i;
-            } else {
-                break;
-            }
-        }
-
-        if (bestZoomIndex == -1) {
-            // Even in the worst case, we should always at least return 0 here
-            throw new AssertionError("Should've found at least one valid zoom index");
-        }
-
-        // Write the rectangles in-place
-        reportedCropRegion.set(bestReportedCropRegion);
-        previewCropRegion.set(bestPreviewCropRegion);
-
-        return bestZoomIndex;
-    }
-
-    /**
-     * Calculate the effective crop rectangle for this preview viewport;
-     * assumes the preview is centered to the sensor and scaled to fit across one of the dimensions
-     * without skewing.
-     *
-     * <p>The preview size must be a subset of the active array size; the resulting
-     * rectangle will also be a subset of the active array rectangle.</p>
-     *
-     * <p>The unzoomed crop rectangle is calculated only.</p>
-     *
-     * @param activeArray active array dimensions, in sensor space
-     * @param previewSize size of the preview buffer render target, in pixels (not in sensor space)
-     * @return a rectangle which serves as the preview stream's effective crop region (unzoomed),
-     *         in sensor space
-     *
-     * @throws NullPointerException
-     *          if any of the args were {@code null}
-     * @throws IllegalArgumentException
-     *          if {@code previewSize} is wider or taller than {@code activeArray}
-     */
-    private static Rect getPreviewCropRectangleUnzoomed(Rect activeArray, Size previewSize) {
-        if (previewSize.getWidth() > activeArray.width()) {
-            throw new IllegalArgumentException("previewSize must not be wider than activeArray");
-        } else if (previewSize.getHeight() > activeArray.height()) {
-            throw new IllegalArgumentException("previewSize must not be taller than activeArray");
-        }
-
-        float aspectRatioArray = activeArray.width() * 1.0f / activeArray.height();
-        float aspectRatioPreview = previewSize.getWidth() * 1.0f / previewSize.getHeight();
-
-        float cropH, cropW;
-        if (Math.abs(aspectRatioPreview - aspectRatioArray) < ASPECT_RATIO_TOLERANCE) {
-            cropH = activeArray.height();
-            cropW = activeArray.width();
-        } else if (aspectRatioPreview < aspectRatioArray) {
-            // The new width must be smaller than the height, so scale the width by AR
-            cropH = activeArray.height();
-            cropW = cropH * aspectRatioPreview;
-        } else {
-            // The new height must be smaller (or equal) than the width, so scale the height by AR
-            cropW = activeArray.width();
-            cropH = cropW / aspectRatioPreview;
-        }
-
-        Matrix translateMatrix = new Matrix();
-        RectF cropRect = new RectF(/*left*/0, /*top*/0, cropW, cropH);
-
-        // Now center the crop rectangle so its center is in the center of the active array
-        translateMatrix.setTranslate(activeArray.exactCenterX(), activeArray.exactCenterY());
-        translateMatrix.postTranslate(-cropRect.centerX(), -cropRect.centerY());
-
-        translateMatrix.mapRect(/*inout*/cropRect);
-
-        // Round the rect corners towards the nearest integer values
-        return ParamsUtils.createRect(cropRect);
-    }
-
-    /**
-     * Shrink the {@code shrinkTarget} rectangle to snugly fit inside of {@code reference};
-     * the aspect ratio of {@code shrinkTarget} will change to be the same aspect ratio as
-     * {@code reference}.
-     *
-     * <p>At most a single dimension will scale (down). Both dimensions will never be scaled.</p>
-     *
-     * @param reference the rectangle whose aspect ratio will be used as the new aspect ratio
-     * @param shrinkTarget the rectangle which will be scaled down to have a new aspect ratio
-     *
-     * @return a new rectangle, a subset of {@code shrinkTarget},
-     *          whose aspect ratio will match that of {@code reference}
-     */
-    private static Rect shrinkToSameAspectRatioCentered(Rect reference, Rect shrinkTarget) {
-        float aspectRatioReference = reference.width() * 1.0f / reference.height();
-        float aspectRatioShrinkTarget = shrinkTarget.width() * 1.0f / shrinkTarget.height();
-
-        float cropH, cropW;
-        if (aspectRatioShrinkTarget < aspectRatioReference) {
-            // The new width must be smaller than the height, so scale the width by AR
-            cropH = reference.height();
-            cropW = cropH * aspectRatioShrinkTarget;
-        } else {
-            // The new height must be smaller (or equal) than the width, so scale the height by AR
-            cropW = reference.width();
-            cropH = cropW / aspectRatioShrinkTarget;
-        }
-
-        Matrix translateMatrix = new Matrix();
-        RectF shrunkRect = new RectF(shrinkTarget);
-
-        // Scale the rectangle down, but keep its center in the same place as before
-        translateMatrix.setScale(cropW / reference.width(), cropH / reference.height(),
-                shrinkTarget.exactCenterX(), shrinkTarget.exactCenterY());
-
-        translateMatrix.mapRect(/*inout*/shrunkRect);
-
-        return ParamsUtils.createRect(shrunkRect);
-    }
-
-    /**
-     * Get the available 'crop' (zoom) rectangles for this camera that will be reported
-     * via a {@code CaptureResult} when a zoom is requested.
-     *
-     * <p>These crops ignores the underlying preview buffer size, and will always be reported
-     * the same values regardless of what configuration of outputs is used.</p>
-     *
-     * <p>When zoom is supported, this will return a list of {@code 1 + #getMaxZoom} size,
-     * where each crop rectangle corresponds to a zoom ratio (and is centered at the middle).</p>
-     *
-     * <p>Each crop rectangle is changed to have the same aspect ratio as {@code streamSize},
-     * by shrinking the rectangle if necessary.</p>
-     *
-     * <p>To get the reported crop region when applying a zoom to the sensor, use {@code streamSize}
-     * = {@code activeArray size}.</p>
-     *
-     * @param params non-{@code null} camera api1 parameters
-     * @param activeArray active array dimensions, in sensor space
-     * @param streamSize stream size dimensions, in pixels
-     *
-     * @return a list of available zoom rectangles, sorted from least zoomed to most zoomed
-     */
-    public static List<Rect> getAvailableZoomCropRectangles(
-            Camera.Parameters params, Rect activeArray) {
-        checkNotNull(params, "params must not be null");
-        checkNotNull(activeArray, "activeArray must not be null");
-
-        return getAvailableCropRectangles(params, activeArray, ParamsUtils.createSize(activeArray));
-    }
-
-    /**
-     * Get the available 'crop' (zoom) rectangles for this camera.
-     *
-     * <p>This is the effective (real) crop that is applied by the camera api1 device
-     * when projecting the zoom onto the intermediate preview buffer. Use this when
-     * deciding which zoom ratio to apply.</p>
-     *
-     * <p>When zoom is supported, this will return a list of {@code 1 + #getMaxZoom} size,
-     * where each crop rectangle corresponds to a zoom ratio (and is centered at the middle).</p>
-     *
-     * <p>Each crop rectangle is changed to have the same aspect ratio as {@code streamSize},
-     * by shrinking the rectangle if necessary.</p>
-     *
-     * <p>To get the reported crop region when applying a zoom to the sensor, use {@code streamSize}
-     * = {@code activeArray size}.</p>
-     *
-     * @param params non-{@code null} camera api1 parameters
-     * @param activeArray active array dimensions, in sensor space
-     * @param streamSize stream size dimensions, in pixels
-     *
-     * @return a list of available zoom rectangles, sorted from least zoomed to most zoomed
-     */
-    public static List<Rect> getAvailablePreviewZoomCropRectangles(Camera.Parameters params,
-            Rect activeArray, Size previewSize) {
-        checkNotNull(params, "params must not be null");
-        checkNotNull(activeArray, "activeArray must not be null");
-        checkNotNull(previewSize, "previewSize must not be null");
-
-        return getAvailableCropRectangles(params, activeArray, previewSize);
-    }
-
-    /**
-     * Get the available 'crop' (zoom) rectangles for this camera.
-     *
-     * <p>When zoom is supported, this will return a list of {@code 1 + #getMaxZoom} size,
-     * where each crop rectangle corresponds to a zoom ratio (and is centered at the middle).</p>
-     *
-     * <p>Each crop rectangle is changed to have the same aspect ratio as {@code streamSize},
-     * by shrinking the rectangle if necessary.</p>
-     *
-     * <p>To get the reported crop region when applying a zoom to the sensor, use {@code streamSize}
-     * = {@code activeArray size}.</p>
-     *
-     * @param params non-{@code null} camera api1 parameters
-     * @param activeArray active array dimensions, in sensor space
-     * @param streamSize stream size dimensions, in pixels
-     *
-     * @return a list of available zoom rectangles, sorted from least zoomed to most zoomed
-     */
-    private static List<Rect> getAvailableCropRectangles(Camera.Parameters params,
-            Rect activeArray, Size streamSize) {
-        checkNotNull(params, "params must not be null");
-        checkNotNull(activeArray, "activeArray must not be null");
-        checkNotNull(streamSize, "streamSize must not be null");
-
-        // TODO: change all uses of Rect activeArray to Size activeArray,
-        // since we want the crop to be active-array relative, not pixel-array relative
-
-        Rect unzoomedStreamCrop = getPreviewCropRectangleUnzoomed(activeArray, streamSize);
-
-        if (!params.isZoomSupported()) {
-            // Trivial case: No zoom -> only support the full size as the crop region
-            return new ArrayList<>(Arrays.asList(unzoomedStreamCrop));
-        }
-
-        List<Rect> zoomCropRectangles = new ArrayList<>(params.getMaxZoom() + 1);
-        Matrix scaleMatrix = new Matrix();
-        RectF scaledRect = new RectF();
-
-        for (int zoom : params.getZoomRatios()) {
-            float shrinkRatio = ZOOM_RATIO_MULTIPLIER * 1.0f / zoom; // normalize to 1.0 and smaller
-
-            // set scaledRect to unzoomedStreamCrop
-            ParamsUtils.convertRectF(unzoomedStreamCrop, /*out*/scaledRect);
-
-            scaleMatrix.setScale(
-                    shrinkRatio, shrinkRatio,
-                    activeArray.exactCenterX(),
-                    activeArray.exactCenterY());
-
-            scaleMatrix.mapRect(scaledRect);
-
-            Rect intRect = ParamsUtils.createRect(scaledRect);
-
-            // Round the rect corners towards the nearest integer values
-            zoomCropRectangles.add(intRect);
-        }
-
-        return zoomCropRectangles;
-    }
-
-    /**
-     * Get the largest possible zoom ratio (normalized to {@code 1.0f} and higher)
-     * that the camera can support.
-     *
-     * <p>If the camera does not support zoom, it always returns {@code 1.0f}.</p>
-     *
-     * @param params non-{@code null} camera api1 parameters
-     * @return normalized max zoom ratio, at least {@code 1.0f}
-     */
-    public static float getMaxZoomRatio(Camera.Parameters params) {
-        if (!params.isZoomSupported()) {
-            return 1.0f; // no zoom
-        }
-
-        List<Integer> zoomRatios = params.getZoomRatios(); // sorted smallest->largest
-        int zoom = zoomRatios.get(zoomRatios.size() - 1); // largest zoom ratio
-        float zoomRatio = zoom * 1.0f / ZOOM_RATIO_MULTIPLIER; // normalize to 1.0 and smaller
-
-        return zoomRatio;
-    }
-
-    /**
-     * Returns the component-wise zoom ratio (each greater or equal than {@code 1.0});
-     * largest values means more zoom.
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param cropSize size of the crop/zoom
-     *
-     * @return {@link SizeF} with width/height being the component-wise zoom ratio
-     *
-     * @throws NullPointerException if any of the args were {@code null}
-     * @throws IllegalArgumentException if any component of {@code cropSize} was {@code 0}
-     */
-    private static SizeF getZoomRatio(Size activeArraySize, Size cropSize) {
-        checkNotNull(activeArraySize, "activeArraySize must not be null");
-        checkNotNull(cropSize, "cropSize must not be null");
-        checkArgumentPositive(cropSize.getWidth(), "cropSize.width must be positive");
-        checkArgumentPositive(cropSize.getHeight(), "cropSize.height must be positive");
-
-        float zoomRatioWidth = activeArraySize.getWidth() * 1.0f / cropSize.getWidth();
-        float zoomRatioHeight = activeArraySize.getHeight() * 1.0f / cropSize.getHeight();
-
-        return new SizeF(zoomRatioWidth, zoomRatioHeight);
-    }
-
-    /**
-     * Convert the user-specified crop region/zoom into zoom data; which can be used
-     * to set the parameters to a specific zoom index, or to report back to the user what
-     * the actual zoom was, or for other calculations requiring the current preview crop region.
-     *
-     * <p>None of the parameters are mutated.<p>
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param cropRegion the user-specified crop region
-     * @param zoomRatio the user-specified zoom ratio
-     * @param previewSize the current preview size (in pixels)
-     * @param params the current camera parameters (not mutated)
-     *
-     * @return the zoom index, and the effective/reported crop regions (relative to active array)
-     */
-    public static ZoomData convertToLegacyZoom(Rect activeArraySize, Rect
-            cropRegion, Float zoomRatio, Size previewSize, Camera.Parameters params) {
-        final float FLOAT_EQUAL_THRESHOLD = 0.0001f;
-        if (zoomRatio != null &&
-                Math.abs(1.0f - zoomRatio) > FLOAT_EQUAL_THRESHOLD) {
-            // User uses CONTROL_ZOOM_RATIO to control zoom
-            return convertZoomRatio(activeArraySize, zoomRatio, previewSize, params);
-        }
-
-        return convertScalerCropRegion(activeArraySize, cropRegion, previewSize, params);
-    }
-
-    /**
-     * Convert the user-specified zoom ratio into zoom data; which can be used
-     * to set the parameters to a specific zoom index, or to report back to the user what the
-     * actual zoom was, or for other calculations requiring the current preview crop region.
-     *
-     * <p>None of the parameters are mutated.</p>
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param zoomRatio the current zoom ratio
-     * @param previewSize the current preview size (in pixels)
-     * @param params the current camera parameters (not mutated)
-     *
-     * @return the zoom index, and the effective/reported crop regions (relative to active array)
-     */
-    public static ZoomData convertZoomRatio(Rect activeArraySize, float zoomRatio,
-            Size previewSize, Camera.Parameters params) {
-        if (DEBUG) {
-            Log.v(TAG, "convertZoomRatio - user zoom ratio was " + zoomRatio);
-        }
-
-        List<Rect> availableReportedCropRegions =
-                getAvailableZoomCropRectangles(params, activeArraySize);
-        List<Rect> availablePreviewCropRegions =
-                getAvailablePreviewZoomCropRectangles(params, activeArraySize, previewSize);
-        if (availableReportedCropRegions.size() != availablePreviewCropRegions.size()) {
-            throw new AssertionError("available reported/preview crop region size mismatch");
-        }
-
-        // Find the best matched legacy zoom ratio for the requested camera2 zoom ratio.
-        int bestZoomIndex = 0;
-        Rect reportedCropRegion = new Rect(availableReportedCropRegions.get(0));
-        Rect previewCropRegion = new Rect(availablePreviewCropRegions.get(0));
-        float reportedZoomRatio = 1.0f;
-        if (params.isZoomSupported()) {
-            List<Integer> zoomRatios = params.getZoomRatios();
-            for (int i = 1; i < zoomRatios.size(); i++) {
-                if (zoomRatio * ZOOM_RATIO_MULTIPLIER >= zoomRatios.get(i)) {
-                    bestZoomIndex = i;
-                    reportedCropRegion = availableReportedCropRegions.get(i);
-                    previewCropRegion = availablePreviewCropRegions.get(i);
-                    reportedZoomRatio = zoomRatios.get(i);
-                } else {
-                    break;
-                }
-            }
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "convertZoomRatio - zoom calculated to: " +
-                    "zoomIndex = " + bestZoomIndex +
-                    ", reported crop region = " + reportedCropRegion +
-                    ", preview crop region = " + previewCropRegion +
-                    ", reported zoom ratio = " + reportedZoomRatio);
-        }
-
-        return new ZoomData(bestZoomIndex, reportedCropRegion,
-                previewCropRegion, reportedZoomRatio);
-    }
-
-    /**
-     * Convert the user-specified crop region into zoom data; which can be used
-     * to set the parameters to a specific zoom index, or to report back to the user what the
-     * actual zoom was, or for other calculations requiring the current preview crop region.
-     *
-     * <p>None of the parameters are mutated.</p>
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param cropRegion the user-specified crop region
-     * @param previewSize the current preview size (in pixels)
-     * @param params the current camera parameters (not mutated)
-     *
-     * @return the zoom index, and the effective/reported crop regions (relative to active array)
-     */
-    public static ZoomData convertScalerCropRegion(Rect activeArraySize, Rect
-            cropRegion, Size previewSize, Camera.Parameters params) {
-        Rect activeArraySizeOnly = new Rect(
-                /*left*/0, /*top*/0,
-                activeArraySize.width(), activeArraySize.height());
-
-        Rect userCropRegion = cropRegion;
-
-        if (userCropRegion == null) {
-            userCropRegion = activeArraySizeOnly;
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "convertScalerCropRegion - user crop region was " + userCropRegion);
-        }
-
-        final Rect reportedCropRegion = new Rect();
-        final Rect previewCropRegion = new Rect();
-        final int zoomIdx = ParameterUtils.getClosestAvailableZoomCrop(params, activeArraySizeOnly,
-                previewSize, userCropRegion,
-                /*out*/reportedCropRegion, /*out*/previewCropRegion);
-        final float reportedZoomRatio = 1.0f;
-
-        if (DEBUG) {
-            Log.v(TAG, "convertScalerCropRegion - zoom calculated to: " +
-                    "zoomIndex = " + zoomIdx +
-                    ", reported crop region = " + reportedCropRegion +
-                    ", preview crop region = " + previewCropRegion +
-                    ", reported zoom ratio = " + reportedZoomRatio);
-        }
-
-        return new ZoomData(zoomIdx, previewCropRegion, reportedCropRegion, reportedZoomRatio);
-    }
-
-    /**
-     * Calculate the actual/effective/reported normalized rectangle data from a metering
-     * rectangle.
-     *
-     * <p>If any of the rectangles are out-of-range of their intended bounding box,
-     * the {@link #RECTANGLE_EMPTY empty rectangle} is substituted instead
-     * (with a weight of {@code 0}).</p>
-     *
-     * <p>The metering rectangle is bound by the crop region (effective/reported respectively).
-     * The metering {@link Camera.Area area} is bound by {@code [-1000, 1000]}.</p>
-     *
-     * <p>No parameters are mutated; returns the new metering data.</p>
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param meteringRect the user-specified metering rectangle
-     * @param zoomData the calculated zoom data corresponding to this request
-     *
-     * @return the metering area, the reported/effective metering rectangles
-     */
-    public static MeteringData convertMeteringRectangleToLegacy(
-            Rect activeArray, MeteringRectangle meteringRect, ZoomData zoomData) {
-        Rect previewCrop = zoomData.previewCrop;
-
-        float scaleW = (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN) * 1.0f /
-                previewCrop.width();
-        float scaleH = (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN) * 1.0f /
-                previewCrop.height();
-
-        Matrix transform = new Matrix();
-        // Move the preview crop so that top,left is at (0,0), otherwise after scaling
-        // the corner bounds will be outside of [-1000, 1000]
-        transform.setTranslate(-previewCrop.left, -previewCrop.top);
-        // Scale into [0, 2000] range about the center of the preview
-        transform.postScale(scaleW, scaleH);
-        // Move so that top left of a typical rect is at [-1000, -1000]
-        transform.postTranslate(/*dx*/NORMALIZED_RECTANGLE_MIN, /*dy*/NORMALIZED_RECTANGLE_MIN);
-
-        /*
-         * Calculate the preview metering region (effective), and the camera1 api
-         * normalized metering region.
-         */
-        Rect normalizedRegionUnbounded = ParamsUtils.mapRect(transform, meteringRect.getRect());
-
-        /*
-         * Try to intersect normalized area with [-1000, 1000] rectangle; otherwise
-         * it's completely out of range
-         */
-        Rect normalizedIntersected = new Rect(normalizedRegionUnbounded);
-
-        Camera.Area meteringArea;
-        if (!normalizedIntersected.intersect(NORMALIZED_RECTANGLE_DEFAULT)) {
-            Log.w(TAG,
-                    "convertMeteringRectangleToLegacy - metering rectangle too small, " +
-                    "no metering will be done");
-            normalizedIntersected.set(RECTANGLE_EMPTY);
-            meteringArea = new Camera.Area(RECTANGLE_EMPTY,
-                    MeteringRectangle.METERING_WEIGHT_DONT_CARE);
-        } else {
-            meteringArea = new Camera.Area(normalizedIntersected,
-                    meteringRect.getMeteringWeight());
-        }
-
-        /*
-         * Calculate effective preview metering region
-         */
-        Rect previewMetering = meteringRect.getRect();
-        if (!previewMetering.intersect(previewCrop)) {
-            previewMetering.set(RECTANGLE_EMPTY);
-        }
-
-        /*
-         * Calculate effective reported metering region
-         * - Transform the calculated metering area back into active array space
-         * - Clip it to be a subset of the reported crop region
-         */
-        Rect reportedMetering;
-        {
-            Camera.Area normalizedAreaUnbounded = new Camera.Area(
-                    normalizedRegionUnbounded, meteringRect.getMeteringWeight());
-            WeightedRectangle reportedMeteringRect = convertCameraAreaToActiveArrayRectangle(
-                    activeArray, zoomData, normalizedAreaUnbounded, /*usePreviewCrop*/false);
-            reportedMetering = reportedMeteringRect.rect;
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, String.format(
-                    "convertMeteringRectangleToLegacy - activeArray = %s, meteringRect = %s, " +
-                    "previewCrop = %s, meteringArea = %s, previewMetering = %s, " +
-                    "reportedMetering = %s, normalizedRegionUnbounded = %s",
-                    activeArray, meteringRect,
-                    previewCrop, stringFromArea(meteringArea), previewMetering,
-                    reportedMetering, normalizedRegionUnbounded));
-        }
-
-        return new MeteringData(meteringArea, previewMetering, reportedMetering);
-    }
-
-    /**
-     * Convert the normalized camera area from [-1000, 1000] coordinate space
-     * into the active array-based coordinate space.
-     *
-     * <p>Values out of range are clipped to be within the resulting (reported) crop
-     * region. It is possible to have values larger than the preview crop.</p>
-     *
-     * <p>Weights out of range of [0, 1000] are clipped to be within the range.</p>
-     *
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param zoomData the calculated zoom data corresponding to this request
-     * @param area the normalized camera area
-     *
-     * @return the weighed rectangle in active array coordinate space, with the weight
-     */
-    public static WeightedRectangle convertCameraAreaToActiveArrayRectangle(
-            Rect activeArray, ZoomData zoomData, Camera.Area area) {
-        return convertCameraAreaToActiveArrayRectangle(activeArray, zoomData, area,
-                /*usePreviewCrop*/true);
-    }
-
-    /**
-     * Convert an api1 face into an active-array based api2 face.
-     *
-     * <p>Out-of-ranges scores and ids will be clipped to be within range (with a warning).</p>
-     *
-     * @param face a non-{@code null} api1 face
-     * @param activeArraySize active array size of the sensor (e.g. max jpeg size)
-     * @param zoomData the calculated zoom data corresponding to this request
-     *
-     * @return a non-{@code null} api2 face
-     *
-     * @throws NullPointerException if the {@code face} was {@code null}
-     */
-    public static Face convertFaceFromLegacy(Camera.Face face, Rect activeArray,
-            ZoomData zoomData) {
-        checkNotNull(face, "face must not be null");
-
-        Face api2Face;
-
-        Camera.Area fakeArea = new Camera.Area(face.rect, /*weight*/1);
-
-        WeightedRectangle faceRect =
-                convertCameraAreaToActiveArrayRectangle(activeArray, zoomData, fakeArea);
-
-        Point leftEye = face.leftEye, rightEye = face.rightEye, mouth = face.mouth;
-        if (leftEye != null && rightEye != null && mouth != null && leftEye.x != -2000 &&
-                leftEye.y != -2000 && rightEye.x != -2000 && rightEye.y != -2000 &&
-                mouth.x != -2000 && mouth.y != -2000) {
-            leftEye = convertCameraPointToActiveArrayPoint(activeArray, zoomData,
-                    leftEye, /*usePreviewCrop*/true);
-            rightEye = convertCameraPointToActiveArrayPoint(activeArray, zoomData,
-                    leftEye, /*usePreviewCrop*/true);
-            mouth = convertCameraPointToActiveArrayPoint(activeArray, zoomData,
-                    leftEye, /*usePreviewCrop*/true);
-
-            api2Face = faceRect.toFace(face.id, leftEye, rightEye, mouth);
-        } else {
-            api2Face = faceRect.toFace();
-        }
-
-        return api2Face;
-    }
-
-    private static Point convertCameraPointToActiveArrayPoint(
-            Rect activeArray, ZoomData zoomData, Point point, boolean usePreviewCrop) {
-        Rect pointedRect = new Rect(point.x, point.y, point.x, point.y);
-        Camera.Area pointedArea = new Area(pointedRect, /*weight*/1);
-
-        WeightedRectangle adjustedRect =
-                convertCameraAreaToActiveArrayRectangle(activeArray,
-                        zoomData, pointedArea, usePreviewCrop);
-
-        Point transformedPoint = new Point(adjustedRect.rect.left, adjustedRect.rect.top);
-
-        return transformedPoint;
-    }
-
-    private static WeightedRectangle convertCameraAreaToActiveArrayRectangle(
-            Rect activeArray, ZoomData zoomData, Camera.Area area, boolean usePreviewCrop) {
-        Rect previewCrop = zoomData.previewCrop;
-        Rect reportedCrop = zoomData.reportedCrop;
-
-        float scaleW = previewCrop.width() * 1.0f /
-                (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN);
-        float scaleH = previewCrop.height() * 1.0f /
-                (NORMALIZED_RECTANGLE_MAX - NORMALIZED_RECTANGLE_MIN);
-
-        /*
-         * Calculate the reported metering region from the non-intersected normalized region
-         * by scaling and translating back into active array-relative coordinates.
-         */
-        Matrix transform = new Matrix();
-
-        // Move top left from (-1000, -1000) to (0, 0)
-        transform.setTranslate(/*dx*/NORMALIZED_RECTANGLE_MAX, /*dy*/NORMALIZED_RECTANGLE_MAX);
-
-        // Scale from [0, 2000] back into the preview rectangle
-        transform.postScale(scaleW, scaleH);
-
-        // Move the rect so that the [-1000,-1000] point ends up at the preview [left, top]
-        transform.postTranslate(previewCrop.left, previewCrop.top);
-
-        Rect cropToIntersectAgainst = usePreviewCrop ? previewCrop : reportedCrop;
-
-        // Now apply the transformation backwards to get the reported metering region
-        Rect reportedMetering = ParamsUtils.mapRect(transform, area.rect);
-        // Intersect it with the crop region, to avoid reporting out-of-bounds
-        // metering regions
-        if (!reportedMetering.intersect(cropToIntersectAgainst)) {
-            reportedMetering.set(RECTANGLE_EMPTY);
-        }
-
-        int weight = area.weight;
-        if (weight < MeteringRectangle.METERING_WEIGHT_MIN) {
-            Log.w(TAG,
-                    "convertCameraAreaToMeteringRectangle - rectangle "
-                            + stringFromArea(area) + " has too small weight, clip to 0");
-            weight = 0;
-        }
-
-        return new WeightedRectangle(reportedMetering, area.weight);
-    }
-
-
-    private ParameterUtils() {
-        throw new AssertionError();
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/PerfMeasurement.java b/core/java/android/hardware/camera2/legacy/PerfMeasurement.java
deleted file mode 100644
index 53278c7..0000000
--- a/core/java/android/hardware/camera2/legacy/PerfMeasurement.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * GPU and CPU performance measurement for the legacy implementation.
- *
- * <p>Measures CPU and GPU processing duration for a set of operations, and dumps
- * the results into a file.</p>
- *
- * <p>Rough usage:
- * <pre>
- * {@code
- *   <set up workload>
- *   <start long-running workload>
- *   mPerfMeasurement.startTimer();
- *   ...render a frame...
- *   mPerfMeasurement.stopTimer();
- *   <end workload>
- *   mPerfMeasurement.dumpPerformanceData("/sdcard/my_data.txt");
- * }
- * </pre>
- * </p>
- *
- * <p>All calls to this object must be made within the same thread, and the same GL context.
- * PerfMeasurement cannot be used outside of a GL context.  The only exception is
- * dumpPerformanceData, which can be called outside of a valid GL context.</p>
- */
-class PerfMeasurement {
-    private static final String TAG = "PerfMeasurement";
-
-    public static final int DEFAULT_MAX_QUERIES = 3;
-
-    private final long mNativeContext;
-
-    private int mCompletedQueryCount = 0;
-
-    /**
-     * Values for completed measurements
-     */
-    private ArrayList<Long> mCollectedGpuDurations = new ArrayList<>();
-    private ArrayList<Long> mCollectedCpuDurations = new ArrayList<>();
-    private ArrayList<Long> mCollectedTimestamps = new ArrayList<>();
-
-    /**
-     * Values for in-progress measurements (waiting for async GPU results)
-     */
-    private Queue<Long> mTimestampQueue = new LinkedList<>();
-    private Queue<Long> mCpuDurationsQueue = new LinkedList<>();
-
-    private long mStartTimeNs;
-
-    /**
-     * The value returned by {@link #nativeGetNextGlDuration} if no new timing
-     * measurement is available since the last call.
-     */
-    private static final long NO_DURATION_YET = -1l;
-
-    /**
-     * The value returned by {@link #nativeGetNextGlDuration} if timing failed for
-     * the next timing interval
-     */
-    private static final long FAILED_TIMING = -2l;
-
-    /**
-     * Create a performance measurement object with a maximum of {@value #DEFAULT_MAX_QUERIES}
-     * in-progess queries.
-     */
-    public PerfMeasurement() {
-        mNativeContext = nativeCreateContext(DEFAULT_MAX_QUERIES);
-    }
-
-    /**
-     * Create a performance measurement object with maxQueries as the maximum number of
-     * in-progress queries.
-     *
-     * @param maxQueries maximum in-progress queries, must be larger than 0.
-     * @throws IllegalArgumentException if maxQueries is less than 1.
-     */
-    public PerfMeasurement(int maxQueries) {
-        if (maxQueries < 1) throw new IllegalArgumentException("maxQueries is less than 1");
-        mNativeContext = nativeCreateContext(maxQueries);
-    }
-
-    /**
-     * Returns true if the Gl timing methods will work, false otherwise.
-     *
-     * <p>Must be called within a valid GL context.</p>
-     */
-    public static boolean isGlTimingSupported() {
-        return nativeQuerySupport();
-    }
-
-    /**
-     * Dump collected data to file, and clear the stored data.
-     *
-     * <p>
-     * Format is a simple csv-like text file with a header,
-     * followed by a 3-column list of values in nanoseconds:
-     * <pre>
-     *   timestamp gpu_duration cpu_duration
-     *   <long> <long> <long>
-     *   <long> <long> <long>
-     *   <long> <long> <long>
-     *   ....
-     * </pre>
-     * </p>
-     */
-    public void dumpPerformanceData(String path) {
-        try (BufferedWriter dump = new BufferedWriter(new FileWriter(path))) {
-            dump.write("timestamp gpu_duration cpu_duration\n");
-            for (int i = 0; i < mCollectedGpuDurations.size(); i++) {
-                dump.write(String.format("%d %d %d\n",
-                                mCollectedTimestamps.get(i),
-                                mCollectedGpuDurations.get(i),
-                                mCollectedCpuDurations.get(i)));
-            }
-            mCollectedTimestamps.clear();
-            mCollectedGpuDurations.clear();
-            mCollectedCpuDurations.clear();
-        } catch (IOException e) {
-            Log.e(TAG, "Error writing data dump to " + path + ":" + e);
-        }
-    }
-
-    /**
-     * Start a GPU/CPU timing measurement.
-     *
-     * <p>Call before starting a rendering pass. Only one timing measurement can be active at once,
-     * so {@link #stopTimer} must be called before the next call to this method.</p>
-     *
-     * @throws IllegalStateException if the maximum number of queries are in progress already,
-     *                               or the method is called multiple times in a row, or there is
-     *                               a GPU error.
-     */
-    public void startTimer() {
-        nativeStartGlTimer(mNativeContext);
-        mStartTimeNs = SystemClock.elapsedRealtimeNanos();
-    }
-
-    /**
-     * Finish a GPU/CPU timing measurement.
-     *
-     * <p>Call after finishing all the drawing for a rendering pass. Only one timing measurement can
-     * be active at once, so {@link #startTimer} must be called before the next call to this
-     * method.</p>
-     *
-     * @throws IllegalStateException if no GL timer is currently started, or there is a GPU
-     *                               error.
-     */
-    public void stopTimer() {
-        // Complete CPU timing
-        long endTimeNs = SystemClock.elapsedRealtimeNanos();
-        mCpuDurationsQueue.add(endTimeNs - mStartTimeNs);
-        // Complete GL timing
-        nativeStopGlTimer(mNativeContext);
-
-        // Poll to see if GL timing results have arrived; if so
-        // store the results for a frame
-        long duration = getNextGlDuration();
-        if (duration > 0) {
-            mCollectedGpuDurations.add(duration);
-            mCollectedTimestamps.add(mTimestampQueue.isEmpty() ?
-                    NO_DURATION_YET : mTimestampQueue.poll());
-            mCollectedCpuDurations.add(mCpuDurationsQueue.isEmpty() ?
-                    NO_DURATION_YET : mCpuDurationsQueue.poll());
-        }
-        if (duration == FAILED_TIMING) {
-            // Discard timestamp and CPU measurement since GPU measurement failed
-            if (!mTimestampQueue.isEmpty()) {
-                mTimestampQueue.poll();
-            }
-            if (!mCpuDurationsQueue.isEmpty()) {
-                mCpuDurationsQueue.poll();
-            }
-        }
-    }
-
-    /**
-     * Add a timestamp to a timing measurement. These are queued up and matched to completed
-     * workload measurements as they become available.
-     */
-    public void addTimestamp(long timestamp) {
-        mTimestampQueue.add(timestamp);
-    }
-
-    /**
-     * Get the next available GPU timing measurement.
-     *
-     * <p>Since the GPU works asynchronously, the results of a single start/stopGlTimer measurement
-     * will only be available some time after the {@link #stopTimer} call is made. Poll this method
-     * until the result becomes available. If multiple start/endTimer measurements are made in a
-     * row, the results will be available in FIFO order.</p>
-     *
-     * @return The measured duration of the GPU workload for the next pending query, or
-     *         {@link #NO_DURATION_YET} if no queries are pending or the next pending query has not
-     *         yet finished, or {@link #FAILED_TIMING} if the GPU was unable to complete the
-     *         measurement.
-     *
-     * @throws IllegalStateException If there is a GPU error.
-     *
-     */
-    private long getNextGlDuration() {
-        long duration = nativeGetNextGlDuration(mNativeContext);
-        if (duration > 0) {
-            mCompletedQueryCount++;
-        }
-        return duration;
-    }
-
-    /**
-     * Returns the number of measurements so far that returned a valid duration
-     * measurement.
-     */
-    public int getCompletedQueryCount() {
-        return mCompletedQueryCount;
-    }
-
-    @Override
-    protected void finalize() {
-        nativeDeleteContext(mNativeContext);
-    }
-
-    /**
-     * Create a native performance measurement context.
-     *
-     * @param maxQueryCount maximum in-progress queries; must be >= 1.
-     */
-    private static native long nativeCreateContext(int maxQueryCount);
-
-    /**
-     * Delete the native context.
-     *
-     * <p>Not safe to call more than once.</p>
-     */
-    private static native void nativeDeleteContext(long contextHandle);
-
-    /**
-     * Query whether the relevant Gl extensions are available for Gl timing
-     */
-    private static native boolean nativeQuerySupport();
-
-    /**
-     * Start a GL timing section.
-     *
-     * <p>All GL commands between this method and the next {@link #nativeEndGlTimer} will be
-     * included in the timing.</p>
-     *
-     * <p>Must be called from the same thread as calls to {@link #nativeEndGlTimer} and
-     * {@link #nativeGetNextGlDuration}.</p>
-     *
-     * @throws IllegalStateException if a GL error occurs or start is called repeatedly.
-     */
-    protected static native void nativeStartGlTimer(long contextHandle);
-
-    /**
-     * Finish a GL timing section.
-     *
-     * <p>Some time after this call returns, the time the GPU took to
-     * execute all work submitted between the latest {@link #nativeStartGlTimer} and
-     * this call, will become available from calling {@link #nativeGetNextGlDuration}.</p>
-     *
-     * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and
-     * {@link #nativeGetNextGlDuration}.</p>
-     *
-     * @throws IllegalStateException if a GL error occurs or stop is called before start
-     */
-    protected static native void nativeStopGlTimer(long contextHandle);
-
-    /**
-     * Get the next available GL duration measurement, in nanoseconds.
-     *
-     * <p>Must be called from the same thread as calls to {@link #nativeStartGlTimer} and
-     * {@link #nativeEndGlTimer}.</p>
-     *
-     * @return the next GL duration measurement, or {@link #NO_DURATION_YET} if
-     *         no new measurement is available, or {@link #FAILED_TIMING} if timing
-     *         failed for the next duration measurement.
-     * @throws IllegalStateException if a GL error occurs
-     */
-    protected static native long nativeGetNextGlDuration(long contextHandle);
-
-
-}
diff --git a/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java b/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java
deleted file mode 100644
index e19ebf2..0000000
--- a/core/java/android/hardware/camera2/legacy/RequestHandlerThread.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.MessageQueue;
-
-public class RequestHandlerThread extends HandlerThread {
-
-    /**
-     * Ensure that the MessageQueue's idle handler gets run by poking the message queue;
-     * normally if the message queue is already idle, the idle handler won't get invoked.
-     *
-     * <p>Users of this handler thread should ignore this message.</p>
-     */
-    public final static int MSG_POKE_IDLE_HANDLER = -1;
-
-    private final ConditionVariable mStarted = new ConditionVariable(false);
-    private final ConditionVariable mIdle = new ConditionVariable(true);
-    private Handler.Callback mCallback;
-    private volatile Handler mHandler;
-
-    public RequestHandlerThread(String name, Handler.Callback callback) {
-        super(name, Thread.MAX_PRIORITY);
-        mCallback = callback;
-    }
-
-    @Override
-    protected void onLooperPrepared() {
-        mHandler = new Handler(getLooper(), mCallback);
-        mStarted.open();
-    }
-
-    // Blocks until thread has started
-    public void waitUntilStarted() {
-        mStarted.block();
-    }
-
-    // May return null if the handler is not set up yet.
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    // Blocks until thread has started
-    public Handler waitAndGetHandler() {
-        waitUntilStarted();
-        return getHandler();
-    }
-
-    // Atomic multi-type message existence check
-    public boolean hasAnyMessages(int[] what) {
-        synchronized (mHandler.getLooper().getQueue()) {
-            for (int i : what) {
-                if (mHandler.hasMessages(i)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    // Atomic multi-type message remove
-    public void removeMessages(int[] what) {
-        synchronized (mHandler.getLooper().getQueue()) {
-            for (int i : what) {
-                mHandler.removeMessages(i);
-            }
-        }
-    }
-
-    private final MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() {
-        @Override
-        public boolean queueIdle() {
-            mIdle.open();
-            return false;
-        }
-    };
-
-    // Blocks until thread is idling
-    public void waitUntilIdle() {
-        Handler handler = waitAndGetHandler();
-        MessageQueue queue = handler.getLooper().getQueue();
-        if (queue.isIdle()) {
-            return;
-        }
-        mIdle.close();
-        queue.addIdleHandler(mIdleHandler);
-        // Ensure that the idle handler gets run even if the looper already went idle
-        handler.sendEmptyMessage(MSG_POKE_IDLE_HANDLER);
-        if (queue.isIdle()) {
-            return;
-        }
-        mIdle.block();
-    }
-
-}
diff --git a/core/java/android/hardware/camera2/legacy/RequestHolder.java b/core/java/android/hardware/camera2/legacy/RequestHolder.java
deleted file mode 100644
index 98b761b..0000000
--- a/core/java/android/hardware/camera2/legacy/RequestHolder.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.camera2.CaptureRequest;
-import android.util.Log;
-import android.view.Surface;
-
-import java.util.Collection;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Semi-immutable container for a single capture request and associated information,
- * the only mutable characteristic of this container is whether or not is has been
- * marked as "failed" using {@code #failRequest}.
- */
-public class RequestHolder {
-    private static final String TAG = "RequestHolder";
-
-    private final boolean mRepeating;
-    private final CaptureRequest mRequest;
-    private final int mRequestId;
-    private final int mSubsequeceId;
-    private final long mFrameNumber;
-    private final int mNumJpegTargets;
-    private final int mNumPreviewTargets;
-    private volatile boolean mFailed = false;
-    private boolean mOutputAbandoned = false;
-
-    private final Collection<Long> mJpegSurfaceIds;
-
-    /**
-     * A builder class for {@link RequestHolder} objects.
-     *
-     * <p>
-     * This allows per-request queries to be cached for repeating {@link CaptureRequest} objects.
-     * </p>
-     */
-    public final static class Builder {
-        private final int mRequestId;
-        private final int mSubsequenceId;
-        private final CaptureRequest mRequest;
-        private final boolean mRepeating;
-        private final int mNumJpegTargets;
-        private final int mNumPreviewTargets;
-        private final Collection<Long> mJpegSurfaceIds;
-
-        /**
-         * Construct a new {@link Builder} to generate {@link RequestHolder} objects.
-         *
-         * @param requestId the ID to set in {@link RequestHolder} objects.
-         * @param subsequenceId the sequence ID to set in {@link RequestHolder} objects.
-         * @param request the original {@link CaptureRequest} to set in {@link RequestHolder}
-         *                objects.
-         * @param repeating {@code true} if the request is repeating.
-         */
-        public Builder(int requestId, int subsequenceId, CaptureRequest request,
-                       boolean repeating, Collection<Long> jpegSurfaceIds) {
-            checkNotNull(request, "request must not be null");
-            mRequestId = requestId;
-            mSubsequenceId = subsequenceId;
-            mRequest = request;
-            mRepeating = repeating;
-            mJpegSurfaceIds = jpegSurfaceIds;
-            mNumJpegTargets = numJpegTargets(mRequest);
-            mNumPreviewTargets = numPreviewTargets(mRequest);
-        }
-
-        /**
-         * Returns true if the given surface requires jpeg buffers.
-         *
-         * @param s a {@link android.view.Surface} to check.
-         * @return true if the surface requires a jpeg buffer.
-         */
-        private boolean jpegType(Surface s)
-                throws LegacyExceptionUtils.BufferQueueAbandonedException {
-            return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
-        }
-
-        /**
-         * Returns true if the given surface requires non-jpeg buffer types.
-         *
-         * <p>
-         * "Jpeg buffer" refers to the buffers returned in the jpeg
-         * {@link android.hardware.Camera.PictureCallback}.  Non-jpeg buffers are created using a tee
-         * of the preview stream drawn to the surface
-         * set via {@link android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)} or
-         * equivalent methods.
-         * </p>
-         * @param s a {@link android.view.Surface} to check.
-         * @return true if the surface requires a non-jpeg buffer type.
-         */
-        private boolean previewType(Surface s)
-                throws LegacyExceptionUtils.BufferQueueAbandonedException {
-            return !jpegType(s);
-        }
-
-        /**
-         * Returns the number of surfaces targeted by the request that require jpeg buffers.
-         */
-        private int numJpegTargets(CaptureRequest request) {
-            int count = 0;
-            for (Surface s : request.getTargets()) {
-                try {
-                    if (jpegType(s)) {
-                        ++count;
-                    }
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.d(TAG, "Surface abandoned, skipping...", e);
-                }
-            }
-            return count;
-        }
-
-        /**
-         * Returns the number of surfaces targeted by the request that require non-jpeg buffers.
-         */
-        private int numPreviewTargets(CaptureRequest request) {
-            int count = 0;
-            for (Surface s : request.getTargets()) {
-                try {
-                    if (previewType(s)) {
-                        ++count;
-                    }
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.d(TAG, "Surface abandoned, skipping...", e);
-                }
-            }
-            return count;
-        }
-
-        /**
-         * Build a new {@link RequestHolder} using with parameters generated from this
-         *      {@link Builder}.
-         *
-         * @param frameNumber the {@code framenumber} to generate in the {@link RequestHolder}.
-         * @return a {@link RequestHolder} constructed with the {@link Builder}'s parameters.
-         */
-        public RequestHolder build(long frameNumber) {
-            return new RequestHolder(mRequestId, mSubsequenceId, mRequest, mRepeating, frameNumber,
-                    mNumJpegTargets, mNumPreviewTargets, mJpegSurfaceIds);
-        }
-    }
-
-    private RequestHolder(int requestId, int subsequenceId, CaptureRequest request,
-                          boolean repeating, long frameNumber, int numJpegTargets,
-                          int numPreviewTargets, Collection<Long> jpegSurfaceIds) {
-        mRepeating = repeating;
-        mRequest = request;
-        mRequestId = requestId;
-        mSubsequeceId = subsequenceId;
-        mFrameNumber = frameNumber;
-        mNumJpegTargets = numJpegTargets;
-        mNumPreviewTargets = numPreviewTargets;
-        mJpegSurfaceIds = jpegSurfaceIds;
-    }
-
-    /**
-     * Return the request id for the contained {@link CaptureRequest}.
-     */
-    public int getRequestId() {
-        return mRequestId;
-    }
-
-    /**
-     * Returns true if the contained request is repeating.
-     */
-    public boolean isRepeating() {
-        return mRepeating;
-    }
-
-    /**
-     * Return the subsequence id for this request.
-     */
-    public int getSubsequeceId() {
-        return mSubsequeceId;
-    }
-
-    /**
-     * Returns the frame number for this request.
-     */
-    public long getFrameNumber() {
-        return mFrameNumber;
-    }
-
-    /**
-     * Returns the contained request.
-     */
-    public CaptureRequest getRequest() {
-        return mRequest;
-    }
-
-    /**
-     * Returns a read-only collection of the surfaces targeted by the contained request.
-     */
-    public Collection<Surface> getHolderTargets() {
-        return getRequest().getTargets();
-    }
-
-    /**
-     * Returns true if any of the surfaces targeted by the contained request require jpeg buffers.
-     */
-    public boolean hasJpegTargets() {
-        return mNumJpegTargets > 0;
-    }
-
-    /**
-     * Returns true if any of the surfaces targeted by the contained request require a
-     * non-jpeg buffer type.
-     */
-    public boolean hasPreviewTargets(){
-        return mNumPreviewTargets > 0;
-    }
-
-    /**
-     * Return the number of jpeg-type surfaces targeted by this request.
-     */
-    public int numJpegTargets() {
-        return mNumJpegTargets;
-    }
-
-    /**
-     * Return the number of non-jpeg-type surfaces targeted by this request.
-     */
-    public int numPreviewTargets() {
-        return mNumPreviewTargets;
-    }
-
-    /**
-     * Returns true if the given surface requires jpeg buffers.
-     *
-     * @param s a {@link android.view.Surface} to check.
-     * @return true if the surface requires a jpeg buffer.
-     */
-    public boolean jpegType(Surface s)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds);
-    }
-
-    /**
-     * Mark this request as failed.
-     */
-    public void failRequest() {
-        Log.w(TAG, "Capture failed for request: " + getRequestId());
-        mFailed = true;
-    }
-
-    /**
-     * Return {@code true} if this request failed.
-     */
-    public boolean requestFailed() {
-        return mFailed;
-    }
-
-    /**
-     * Mark at least one of this request's output surfaces is abandoned.
-     */
-    public void setOutputAbandoned() {
-        mOutputAbandoned = true;
-    }
-
-    /**
-     * Return if any of this request's output surface is abandoned.
-     */
-    public boolean isOutputAbandoned() {
-        return mOutputAbandoned;
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/RequestQueue.java b/core/java/android/hardware/camera2/legacy/RequestQueue.java
deleted file mode 100644
index fb44402..0000000
--- a/core/java/android/hardware/camera2/legacy/RequestQueue.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.camera2.legacy;
-
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.utils.SubmitInfo;
-import android.util.Log;
-
-import java.util.ArrayDeque;
-import java.util.List;
-
-/**
- * A queue of bursts of requests.
- *
- * <p>This queue maintains the count of frames that have been produced, and is thread safe.</p>
- */
-public class RequestQueue {
-    private static final String TAG = "RequestQueue";
-
-    public static final long INVALID_FRAME = -1;
-
-    private BurstHolder mRepeatingRequest = null;
-    private final ArrayDeque<BurstHolder> mRequestQueue = new ArrayDeque<BurstHolder>();
-
-    private long mCurrentFrameNumber = 0;
-    private long mCurrentRepeatingFrameNumber = INVALID_FRAME;
-    private int mCurrentRequestId = 0;
-    private final List<Long> mJpegSurfaceIds;
-
-    public final class RequestQueueEntry {
-        private final BurstHolder mBurstHolder;
-        private final Long mFrameNumber;
-        private final boolean mQueueEmpty;
-
-        public BurstHolder getBurstHolder() {
-            return mBurstHolder;
-        }
-        public Long getFrameNumber() {
-            return mFrameNumber;
-        }
-        public boolean isQueueEmpty() {
-            return mQueueEmpty;
-        }
-
-        public RequestQueueEntry(BurstHolder burstHolder, Long frameNumber, boolean queueEmpty) {
-            mBurstHolder = burstHolder;
-            mFrameNumber = frameNumber;
-            mQueueEmpty = queueEmpty;
-        }
-    }
-
-    public RequestQueue(List<Long> jpegSurfaceIds) {
-        mJpegSurfaceIds = jpegSurfaceIds;
-    }
-
-    /**
-     * Return and remove the next burst on the queue.
-     *
-     * <p>If a repeating burst is returned, it will not be removed.</p>
-     *
-     * @return an entry containing the next burst, the current frame number, and flag about whether
-     * request queue becomes empty. Null if no burst exists.
-     */
-    public synchronized RequestQueueEntry getNext() {
-        BurstHolder next = mRequestQueue.poll();
-        boolean queueEmptied = (next != null && mRequestQueue.size() == 0);
-        if (next == null && mRepeatingRequest != null) {
-            next = mRepeatingRequest;
-            mCurrentRepeatingFrameNumber = mCurrentFrameNumber +
-                    next.getNumberOfRequests();
-        }
-
-        if (next == null) {
-            return null;
-        }
-
-        RequestQueueEntry ret =  new RequestQueueEntry(next, mCurrentFrameNumber, queueEmptied);
-        mCurrentFrameNumber += next.getNumberOfRequests();
-        return ret;
-    }
-
-    /**
-     * Cancel a repeating request.
-     *
-     * @param requestId the id of the repeating request to cancel.
-     * @return the last frame to be returned from the HAL for the given repeating request, or
-     *          {@code INVALID_FRAME} if none exists.
-     */
-    public synchronized long stopRepeating(int requestId) {
-        long ret = INVALID_FRAME;
-        if (mRepeatingRequest != null && mRepeatingRequest.getRequestId() == requestId) {
-            mRepeatingRequest = null;
-            ret = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
-                    mCurrentRepeatingFrameNumber - 1;
-            mCurrentRepeatingFrameNumber = INVALID_FRAME;
-            Log.i(TAG, "Repeating capture request cancelled.");
-        } else {
-            Log.e(TAG, "cancel failed: no repeating request exists for request id: " + requestId);
-        }
-        return ret;
-    }
-
-    /**
-     * Cancel a repeating request.
-     *
-     * @return the last frame to be returned from the HAL for the given repeating request, or
-     *          {@code INVALID_FRAME} if none exists.
-     */
-    public synchronized long stopRepeating() {
-        if (mRepeatingRequest == null) {
-            Log.e(TAG, "cancel failed: no repeating request exists.");
-            return INVALID_FRAME;
-        }
-        return stopRepeating(mRepeatingRequest.getRequestId());
-    }
-
-    /**
-     * Add a the given burst to the queue.
-     *
-     * <p>If the burst is repeating, replace the current repeating burst.</p>
-     *
-     * @param requests the burst of requests to add to the queue.
-     * @param repeating true if the burst is repeating.
-     * @return the submission info, including the new request id, and the last frame number, which
-     *   contains either the frame number of the last frame that will be returned for this request,
-     *   or the frame number of the last frame that will be returned for the current repeating
-     *   request if this burst is set to be repeating.
-     */
-    public synchronized SubmitInfo submit(CaptureRequest[] requests, boolean repeating) {
-        int requestId = mCurrentRequestId++;
-        BurstHolder burst = new BurstHolder(requestId, repeating, requests, mJpegSurfaceIds);
-        long lastFrame = INVALID_FRAME;
-        if (burst.isRepeating()) {
-            Log.i(TAG, "Repeating capture request set.");
-            if (mRepeatingRequest != null) {
-                lastFrame = (mCurrentRepeatingFrameNumber == INVALID_FRAME) ? INVALID_FRAME :
-                        mCurrentRepeatingFrameNumber - 1;
-            }
-            mCurrentRepeatingFrameNumber = INVALID_FRAME;
-            mRepeatingRequest = burst;
-        } else {
-            mRequestQueue.offer(burst);
-            lastFrame = calculateLastFrame(burst.getRequestId());
-        }
-        SubmitInfo info = new SubmitInfo(requestId, lastFrame);
-        return info;
-    }
-
-    private long calculateLastFrame(int requestId) {
-        long total = mCurrentFrameNumber;
-        for (BurstHolder b : mRequestQueue) {
-            total += b.getNumberOfRequests();
-            if (b.getRequestId() == requestId) {
-                return total - 1;
-            }
-        }
-        throw new IllegalStateException(
-                "At least one request must be in the queue to calculate frame number");
-    }
-
-}
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
deleted file mode 100644
index f9a5029..0000000
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.camera2.legacy;
-
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.impl.CameraDeviceImpl;
-import android.hardware.camera2.utils.SubmitInfo;
-import android.hardware.camera2.utils.SizeAreaComparator;
-import android.hardware.camera2.impl.CameraMetadataNative;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
-import android.util.Log;
-import android.util.MutableLong;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * This class executes requests to the {@link Camera}.
- *
- * <p>
- * The main components of this class are:
- * - A message queue of requests to the {@link Camera}.
- * - A thread that consumes requests to the {@link Camera} and executes them.
- * - A {@link GLThreadManager} that draws to the configured output {@link Surface}s.
- * - An {@link CameraDeviceState} state machine that manages the callbacks for various operations.
- * </p>
- */
-@SuppressWarnings("deprecation")
-public class RequestThreadManager {
-    private final String TAG;
-    private final int mCameraId;
-    private final RequestHandlerThread mRequestThread;
-
-    private static final boolean DEBUG = false;
-    // For slightly more spammy messages that will get repeated every frame
-    private static final boolean VERBOSE = false;
-    private Camera mCamera;
-    private final CameraCharacteristics mCharacteristics;
-
-    private final CameraDeviceState mDeviceState;
-    private final CaptureCollector mCaptureCollector;
-    private final LegacyFocusStateMapper mFocusStateMapper;
-    private final LegacyFaceDetectMapper mFaceDetectMapper;
-
-    private static final int MSG_CONFIGURE_OUTPUTS = 1;
-    private static final int MSG_SUBMIT_CAPTURE_REQUEST = 2;
-    private static final int MSG_CLEANUP = 3;
-
-    private static final int MAX_IN_FLIGHT_REQUESTS = 2;
-
-    private static final int PREVIEW_FRAME_TIMEOUT = 1000; // ms
-    private static final int JPEG_FRAME_TIMEOUT = 4000; // ms (same as CTS for API2)
-    private static final int REQUEST_COMPLETE_TIMEOUT = JPEG_FRAME_TIMEOUT;
-
-    private static final float ASPECT_RATIO_TOLERANCE = 0.01f;
-    private boolean mPreviewRunning = false;
-
-    private final List<Surface> mPreviewOutputs = new ArrayList<>();
-    private final List<Surface> mCallbackOutputs = new ArrayList<>();
-    private GLThreadManager mGLThreadManager;
-    private SurfaceTexture mPreviewTexture;
-    private Camera.Parameters mParams;
-
-    private final List<Long> mJpegSurfaceIds = new ArrayList<>();
-
-    private Size mIntermediateBufferSize;
-
-    private final RequestQueue mRequestQueue = new RequestQueue(mJpegSurfaceIds);
-    private LegacyRequest mLastRequest = null;
-    private SurfaceTexture mDummyTexture;
-    private Surface mDummySurface;
-
-    private final Object mIdleLock = new Object();
-    private final FpsCounter mPrevCounter = new FpsCounter("Incoming Preview");
-    private final FpsCounter mRequestCounter = new FpsCounter("Incoming Requests");
-
-    private final AtomicBoolean mQuit = new AtomicBoolean(false);
-
-    // Stuff JPEGs into HAL_PIXEL_FORMAT_RGBA_8888 gralloc buffers to get around SW write
-    // limitations for (b/17379185).
-    private static final boolean USE_BLOB_FORMAT_OVERRIDE = true;
-
-    /**
-     * Container object for Configure messages.
-     */
-    private static class ConfigureHolder {
-        public final ConditionVariable condition;
-        public final Collection<Pair<Surface, Size>> surfaces;
-
-        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
-                Size>> surfaces) {
-            this.condition = condition;
-            this.surfaces = surfaces;
-        }
-    }
-
-    /**
-     * Counter class used to calculate and log the current FPS of frame production.
-     */
-    public static class FpsCounter {
-        //TODO: Hook this up to SystTrace?
-        private static final String TAG = "FpsCounter";
-        private int mFrameCount = 0;
-        private long mLastTime = 0;
-        private long mLastPrintTime = 0;
-        private double mLastFps = 0;
-        private final String mStreamType;
-        private static final long NANO_PER_SECOND = 1000000000; //ns
-
-        public FpsCounter(String streamType) {
-            mStreamType = streamType;
-        }
-
-        public synchronized void countFrame() {
-            mFrameCount++;
-            long nextTime = SystemClock.elapsedRealtimeNanos();
-            if (mLastTime == 0) {
-                mLastTime = nextTime;
-            }
-            if (nextTime > mLastTime + NANO_PER_SECOND) {
-                long elapsed = nextTime - mLastTime;
-                mLastFps = mFrameCount * (NANO_PER_SECOND / (double) elapsed);
-                mFrameCount = 0;
-                mLastTime = nextTime;
-            }
-        }
-
-        public synchronized double checkFps() {
-            return mLastFps;
-        }
-
-        public synchronized void staggeredLog() {
-            if (mLastTime > mLastPrintTime + 5 * NANO_PER_SECOND) {
-                mLastPrintTime = mLastTime;
-                Log.d(TAG, "FPS for " + mStreamType + " stream: " + mLastFps );
-            }
-        }
-
-        public synchronized void countAndLog() {
-            countFrame();
-            staggeredLog();
-        }
-    }
-    /**
-     * Fake preview for jpeg captures when there is no active preview
-     */
-    private void createDummySurface() {
-        if (mDummyTexture == null || mDummySurface == null) {
-            mDummyTexture = new SurfaceTexture(/*ignored*/0);
-            // TODO: use smallest default sizes
-            mDummyTexture.setDefaultBufferSize(640, 480);
-            mDummySurface = new Surface(mDummyTexture);
-        }
-    }
-
-    private final Camera.ErrorCallback mErrorCallback = new Camera.ErrorCallback() {
-        @Override
-        public void onError(int i, Camera camera) {
-            switch(i) {
-                case Camera.CAMERA_ERROR_EVICTED: {
-                    flush();
-                    mDeviceState.setError(
-                            CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DISCONNECTED);
-                } break;
-                case Camera.CAMERA_ERROR_DISABLED: {
-                    flush();
-                    mDeviceState.setError(
-                            CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DISABLED);
-                } break;
-                default:  {
-                    Log.e(TAG, "Received error " + i + " from the Camera1 ErrorCallback");
-                    mDeviceState.setError(
-                            CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                } break;
-            }
-        }
-    };
-
-    private final ConditionVariable mReceivedJpeg = new ConditionVariable(false);
-
-    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {
-        @Override
-        public void onPictureTaken(byte[] data, Camera camera) {
-            Log.i(TAG, "Received jpeg.");
-            Pair<RequestHolder, Long> captureInfo = mCaptureCollector.jpegProduced();
-            if (captureInfo == null || captureInfo.first == null) {
-                Log.e(TAG, "Dropping jpeg frame.");
-                return;
-            }
-            RequestHolder holder = captureInfo.first;
-            long timestamp = captureInfo.second;
-            for (Surface s : holder.getHolderTargets()) {
-                try {
-                    if (LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds)) {
-                        Log.i(TAG, "Producing jpeg buffer...");
-
-                        int totalSize = data.length + LegacyCameraDevice.nativeGetJpegFooterSize();
-                        totalSize = (totalSize + 3) & ~0x3; // round up to nearest octonibble
-                        LegacyCameraDevice.setNextTimestamp(s, timestamp);
-
-                        if (USE_BLOB_FORMAT_OVERRIDE) {
-                            // Override to RGBA_8888 format.
-                            LegacyCameraDevice.setSurfaceFormat(s,
-                                    LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888);
-
-                            int dimen = (int) Math.ceil(Math.sqrt(totalSize));
-                            dimen = (dimen + 0xf) & ~0xf; // round up to nearest multiple of 16
-                            LegacyCameraDevice.setSurfaceDimens(s, dimen, dimen);
-                            LegacyCameraDevice.produceFrame(s, data, dimen, dimen,
-                                    CameraMetadataNative.NATIVE_JPEG_FORMAT);
-                        } else {
-                            LegacyCameraDevice.setSurfaceDimens(s, totalSize, /*height*/1);
-                            LegacyCameraDevice.produceFrame(s, data, totalSize, /*height*/1,
-                                    CameraMetadataNative.NATIVE_JPEG_FORMAT);
-                        }
-                    }
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, dropping frame. ", e);
-                }
-            }
-
-            mReceivedJpeg.open();
-        }
-    };
-
-    private final Camera.ShutterCallback mJpegShutterCallback = new Camera.ShutterCallback() {
-        @Override
-        public void onShutter() {
-            mCaptureCollector.jpegCaptured(SystemClock.elapsedRealtimeNanos());
-        }
-    };
-
-    private final SurfaceTexture.OnFrameAvailableListener mPreviewCallback =
-            new SurfaceTexture.OnFrameAvailableListener() {
-                @Override
-                public void onFrameAvailable(SurfaceTexture surfaceTexture) {
-                    if (DEBUG) {
-                        mPrevCounter.countAndLog();
-                    }
-                    mGLThreadManager.queueNewFrame();
-                }
-            };
-
-    private void stopPreview() {
-        if (VERBOSE) {
-            Log.v(TAG, "stopPreview - preview running? " + mPreviewRunning);
-        }
-        if (mPreviewRunning) {
-            mCamera.stopPreview();
-            mPreviewRunning = false;
-        }
-    }
-
-    private void startPreview() {
-        if (VERBOSE) {
-            Log.v(TAG, "startPreview - preview running? " + mPreviewRunning);
-        }
-        if (!mPreviewRunning) {
-            // XX: CameraClient:;startPreview is not getting called after a stop
-            mCamera.startPreview();
-            mPreviewRunning = true;
-        }
-    }
-
-    private void doJpegCapturePrepare(RequestHolder request) throws IOException {
-        if (DEBUG) Log.d(TAG, "doJpegCapturePrepare - preview running? " + mPreviewRunning);
-
-        if (!mPreviewRunning) {
-            if (DEBUG) Log.d(TAG, "doJpegCapture - create fake surface");
-
-            createDummySurface();
-            mCamera.setPreviewTexture(mDummyTexture);
-            startPreview();
-        }
-    }
-
-    private void doJpegCapture(RequestHolder request) {
-        if (DEBUG) Log.d(TAG, "doJpegCapturePrepare");
-
-        mCamera.takePicture(mJpegShutterCallback, /*raw*/null, mJpegCallback);
-        mPreviewRunning = false;
-    }
-
-    private void doPreviewCapture(RequestHolder request) throws IOException {
-        if (VERBOSE) {
-            Log.v(TAG, "doPreviewCapture - preview running? " + mPreviewRunning);
-        }
-
-        if (mPreviewRunning) {
-            return; // Already running
-        }
-
-        if (mPreviewTexture == null) {
-            throw new IllegalStateException(
-                    "Preview capture called with no preview surfaces configured.");
-        }
-
-        mPreviewTexture.setDefaultBufferSize(mIntermediateBufferSize.getWidth(),
-                mIntermediateBufferSize.getHeight());
-        mCamera.setPreviewTexture(mPreviewTexture);
-
-        startPreview();
-    }
-
-    private void disconnectCallbackSurfaces() {
-        for (Surface s : mCallbackOutputs) {
-            try {
-                LegacyCameraDevice.disconnectSurface(s);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.d(TAG, "Surface abandoned, skipping...", e);
-            }
-        }
-    }
-
-    private void configureOutputs(Collection<Pair<Surface, Size>> outputs) {
-        if (DEBUG) {
-            String outputsStr = outputs == null ? "null" : (outputs.size() + " surfaces");
-            Log.d(TAG, "configureOutputs with " + outputsStr);
-        }
-
-        try {
-            stopPreview();
-        }  catch (RuntimeException e) {
-            Log.e(TAG, "Received device exception in configure call: ", e);
-            mDeviceState.setError(
-                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-            return;
-        }
-
-        /*
-         * Try to release the previous preview's surface texture earlier if we end up
-         * using a different one; this also reduces the likelihood of getting into a deadlock
-         * when disconnecting from the old previous texture at a later time.
-         */
-        try {
-            mCamera.setPreviewTexture(/*surfaceTexture*/null);
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to clear prior SurfaceTexture, may cause GL deadlock: ", e);
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Received device exception in configure call: ", e);
-            mDeviceState.setError(
-                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-            return;
-        }
-
-        if (mGLThreadManager != null) {
-            mGLThreadManager.waitUntilStarted();
-            mGLThreadManager.ignoreNewFrames();
-            mGLThreadManager.waitUntilIdle();
-        }
-        resetJpegSurfaceFormats(mCallbackOutputs);
-        disconnectCallbackSurfaces();
-
-        mPreviewOutputs.clear();
-        mCallbackOutputs.clear();
-        mJpegSurfaceIds.clear();
-        mPreviewTexture = null;
-
-        List<Size> previewOutputSizes = new ArrayList<>();
-        List<Size> callbackOutputSizes = new ArrayList<>();
-
-        int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
-        int orientation = mCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
-        if (outputs != null) {
-            for (Pair<Surface, Size> outPair : outputs) {
-                Surface s = outPair.first;
-                Size outSize = outPair.second;
-                try {
-                    int format = LegacyCameraDevice.detectSurfaceType(s);
-                    LegacyCameraDevice.setSurfaceOrientation(s, facing, orientation);
-                    switch (format) {
-                        case CameraMetadataNative.NATIVE_JPEG_FORMAT:
-                            if (USE_BLOB_FORMAT_OVERRIDE) {
-                                // Override to RGBA_8888 format.
-                                LegacyCameraDevice.setSurfaceFormat(s,
-                                        LegacyMetadataMapper.HAL_PIXEL_FORMAT_RGBA_8888);
-                            }
-                            mJpegSurfaceIds.add(LegacyCameraDevice.getSurfaceId(s));
-                            mCallbackOutputs.add(s);
-                            callbackOutputSizes.add(outSize);
-
-                            // LegacyCameraDevice is the producer of JPEG output surfaces
-                            // so LegacyCameraDevice needs to connect to the surfaces.
-                            LegacyCameraDevice.connectSurface(s);
-                            break;
-                        default:
-                            LegacyCameraDevice.setScalingMode(s, LegacyCameraDevice.
-                                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
-                            mPreviewOutputs.add(s);
-                            previewOutputSizes.add(outSize);
-                            break;
-                    }
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, skipping...", e);
-                }
-            }
-        }
-        try {
-            mParams = mCamera.getParameters();
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Received device exception: ", e);
-            mDeviceState.setError(
-                CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-            return;
-        }
-
-        List<int[]> supportedFpsRanges = mParams.getSupportedPreviewFpsRange();
-        int[] bestRange = getPhotoPreviewFpsRange(supportedFpsRanges);
-        if (DEBUG) {
-            Log.d(TAG, "doPreviewCapture - Selected range [" +
-                    bestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX] + "," +
-                    bestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] + "]");
-        }
-        mParams.setPreviewFpsRange(bestRange[Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
-                bestRange[Camera.Parameters.PREVIEW_FPS_MAX_INDEX]);
-
-        Size smallestSupportedJpegSize = calculatePictureSize(mCallbackOutputs,
-                callbackOutputSizes, mParams);
-
-        if (previewOutputSizes.size() > 0) {
-
-            Size largestOutput = SizeAreaComparator.findLargestByArea(previewOutputSizes);
-
-            // Find largest jpeg dimension - assume to have the same aspect ratio as sensor.
-            Size largestJpegDimen = ParameterUtils.getLargestSupportedJpegSizeByArea(mParams);
-
-            Size chosenJpegDimen = (smallestSupportedJpegSize != null) ? smallestSupportedJpegSize
-                    : largestJpegDimen;
-
-            List<Size> supportedPreviewSizes = ParameterUtils.convertSizeList(
-                    mParams.getSupportedPreviewSizes());
-
-            // Use smallest preview dimension with same aspect ratio as sensor that is >= than all
-            // of the configured output dimensions.  If none exists, fall back to using the largest
-            // supported preview size.
-            long largestOutputArea = largestOutput.getHeight() * (long) largestOutput.getWidth();
-            Size bestPreviewDimen = SizeAreaComparator.findLargestByArea(supportedPreviewSizes);
-            for (Size s : supportedPreviewSizes) {
-                long currArea = s.getWidth() * s.getHeight();
-                long bestArea = bestPreviewDimen.getWidth() * bestPreviewDimen.getHeight();
-                if (checkAspectRatiosMatch(chosenJpegDimen, s) && (currArea < bestArea &&
-                        currArea >= largestOutputArea)) {
-                    bestPreviewDimen = s;
-                }
-            }
-
-            mIntermediateBufferSize = bestPreviewDimen;
-            mParams.setPreviewSize(mIntermediateBufferSize.getWidth(),
-                    mIntermediateBufferSize.getHeight());
-
-            if (DEBUG) {
-                Log.d(TAG, "Intermediate buffer selected with dimens: " +
-                        bestPreviewDimen.toString());
-            }
-        } else {
-            mIntermediateBufferSize = null;
-            if (DEBUG) {
-                Log.d(TAG, "No Intermediate buffer selected, no preview outputs were configured");
-            }
-        }
-
-        if (smallestSupportedJpegSize != null) {
-            /*
-             * Set takePicture size to the smallest supported JPEG size large enough
-             * to scale/crop out of for the bounding rectangle of the configured JPEG sizes.
-             */
-
-            Log.i(TAG, "configureOutputs - set take picture size to " + smallestSupportedJpegSize);
-            mParams.setPictureSize(
-                    smallestSupportedJpegSize.getWidth(), smallestSupportedJpegSize.getHeight());
-        }
-
-        // TODO: Detect and optimize single-output paths here to skip stream teeing.
-        if (mGLThreadManager == null) {
-            mGLThreadManager = new GLThreadManager(mCameraId, facing, mDeviceState);
-            mGLThreadManager.start();
-        }
-        mGLThreadManager.waitUntilStarted();
-        List<Pair<Surface, Size>> previews = new ArrayList<>();
-        Iterator<Size> previewSizeIter = previewOutputSizes.iterator();
-        for (Surface p : mPreviewOutputs) {
-            previews.add(new Pair<>(p, previewSizeIter.next()));
-        }
-        mGLThreadManager.setConfigurationAndWait(previews, mCaptureCollector);
-
-        for (Surface p : mPreviewOutputs) {
-            try {
-                LegacyCameraDevice.setSurfaceOrientation(p, facing, orientation);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.e(TAG, "Surface abandoned, skipping setSurfaceOrientation()", e);
-            }
-        }
-
-        mGLThreadManager.allowNewFrames();
-        mPreviewTexture = mGLThreadManager.getCurrentSurfaceTexture();
-        if (mPreviewTexture != null) {
-            mPreviewTexture.setOnFrameAvailableListener(mPreviewCallback);
-        }
-
-        try {
-            mCamera.setParameters(mParams);
-        } catch (RuntimeException e) {
-                Log.e(TAG, "Received device exception while configuring: ", e);
-                mDeviceState.setError(
-                        CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-
-        }
-    }
-
-    private void resetJpegSurfaceFormats(Collection<Surface> surfaces) {
-        if (!USE_BLOB_FORMAT_OVERRIDE || surfaces == null) {
-            return;
-        }
-        for(Surface s : surfaces) {
-            if (s == null || !s.isValid()) {
-                Log.w(TAG, "Jpeg surface is invalid, skipping...");
-                continue;
-            }
-            try {
-                LegacyCameraDevice.setSurfaceFormat(s, LegacyMetadataMapper.HAL_PIXEL_FORMAT_BLOB);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
-        }
-    }
-
-    /**
-     * Find a JPEG size (that is supported by the legacy camera device) which is equal to or larger
-     * than all of the configured {@code JPEG} outputs (by both width and height).
-     *
-     * <p>If multiple supported JPEG sizes are larger, select the smallest of them which
-     * still satisfies the above constraint.</p>
-     *
-     * <p>As a result, the returned size is guaranteed to be usable without needing
-     * to upscale any of the outputs. If only one {@code JPEG} surface is used,
-     * then no scaling/cropping is necessary between the taken picture and
-     * the {@code JPEG} output surface.</p>
-     *
-     * @param callbackOutputs a non-{@code null} list of {@code Surface}s with any image formats
-     * @param params api1 parameters (used for reading only)
-     *
-     * @return a size large enough to fit all of the configured {@code JPEG} outputs, or
-     *          {@code null} if the {@code callbackOutputs} did not have any {@code JPEG}
-     *          surfaces.
-     */
-    private Size calculatePictureSize( List<Surface> callbackOutputs,
-                                       List<Size> callbackSizes, Camera.Parameters params) {
-        /*
-         * Find the largest JPEG size (if any), from the configured outputs:
-         * - the api1 picture size should be set to the smallest legal size that's at least as large
-         *   as the largest configured JPEG size
-         */
-        if (callbackOutputs.size() != callbackSizes.size()) {
-            throw new IllegalStateException("Input collections must be same length");
-        }
-        List<Size> configuredJpegSizes = new ArrayList<>();
-        Iterator<Size> sizeIterator = callbackSizes.iterator();
-        for (Surface callbackSurface : callbackOutputs) {
-            Size jpegSize = sizeIterator.next();
-                if (!LegacyCameraDevice.containsSurfaceId(callbackSurface, mJpegSurfaceIds)) {
-                    continue; // Ignore non-JPEG callback formats
-                }
-
-                configuredJpegSizes.add(jpegSize);
-        }
-        if (!configuredJpegSizes.isEmpty()) {
-            /*
-             * Find the largest configured JPEG width, and height, independently
-             * of the rest.
-             *
-             * The rest of the JPEG streams can be cropped out of this smallest bounding
-             * rectangle.
-             */
-            int maxConfiguredJpegWidth = -1;
-            int maxConfiguredJpegHeight = -1;
-            for (Size jpegSize : configuredJpegSizes) {
-                maxConfiguredJpegWidth = jpegSize.getWidth() > maxConfiguredJpegWidth ?
-                        jpegSize.getWidth() : maxConfiguredJpegWidth;
-                maxConfiguredJpegHeight = jpegSize.getHeight() > maxConfiguredJpegHeight ?
-                        jpegSize.getHeight() : maxConfiguredJpegHeight;
-            }
-            Size smallestBoundJpegSize = new Size(maxConfiguredJpegWidth, maxConfiguredJpegHeight);
-
-            List<Size> supportedJpegSizes = ParameterUtils.convertSizeList(
-                    params.getSupportedPictureSizes());
-
-            /*
-             * Find the smallest supported JPEG size that can fit the smallest bounding
-             * rectangle for the configured JPEG sizes.
-             */
-            List<Size> candidateSupportedJpegSizes = new ArrayList<>();
-            for (Size supportedJpegSize : supportedJpegSizes) {
-                if (supportedJpegSize.getWidth() >= maxConfiguredJpegWidth &&
-                    supportedJpegSize.getHeight() >= maxConfiguredJpegHeight) {
-                    candidateSupportedJpegSizes.add(supportedJpegSize);
-                }
-            }
-
-            if (candidateSupportedJpegSizes.isEmpty()) {
-                throw new AssertionError(
-                        "Could not find any supported JPEG sizes large enough to fit " +
-                        smallestBoundJpegSize);
-            }
-
-            Size smallestSupportedJpegSize = Collections.min(candidateSupportedJpegSizes,
-                    new SizeAreaComparator());
-
-            if (!smallestSupportedJpegSize.equals(smallestBoundJpegSize)) {
-                Log.w(TAG,
-                        String.format(
-                                "configureOutputs - Will need to crop picture %s into "
-                                + "smallest bound size %s",
-                                smallestSupportedJpegSize, smallestBoundJpegSize));
-            }
-
-            return smallestSupportedJpegSize;
-        }
-
-        return null;
-    }
-
-    private static boolean checkAspectRatiosMatch(Size a, Size b) {
-        float aAspect = a.getWidth() / (float) a.getHeight();
-        float bAspect = b.getWidth() / (float) b.getHeight();
-
-        return Math.abs(aAspect - bAspect) < ASPECT_RATIO_TOLERANCE;
-    }
-
-    // Calculate the highest FPS range supported
-    private int[] getPhotoPreviewFpsRange(List<int[]> frameRates) {
-        if (frameRates.size() == 0) {
-            Log.e(TAG, "No supported frame rates returned!");
-            return null;
-        }
-
-        int bestMin = 0;
-        int bestMax = 0;
-        int bestIndex = 0;
-        int index = 0;
-        for (int[] rate : frameRates) {
-            int minFps = rate[Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
-            int maxFps = rate[Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
-            if (maxFps > bestMax || (maxFps == bestMax && minFps > bestMin)) {
-                bestMin = minFps;
-                bestMax = maxFps;
-                bestIndex = index;
-            }
-            index++;
-        }
-
-        return frameRates.get(bestIndex);
-    }
-
-    private final Handler.Callback mRequestHandlerCb = new Handler.Callback() {
-        private boolean mCleanup = false;
-        private final LegacyResultMapper mMapper = new LegacyResultMapper();
-
-        @Override
-        public boolean handleMessage(Message msg) {
-            if (mCleanup) {
-                return true;
-            }
-
-            if (DEBUG) {
-                Log.d(TAG, "Request thread handling message:" + msg.what);
-            }
-            long startTime = 0;
-            if (DEBUG) {
-                startTime = SystemClock.elapsedRealtimeNanos();
-            }
-            switch (msg.what) {
-                case MSG_CONFIGURE_OUTPUTS:
-                    ConfigureHolder config = (ConfigureHolder) msg.obj;
-                    int sizes = config.surfaces != null ? config.surfaces.size() : 0;
-                    Log.i(TAG, "Configure outputs: " + sizes + " surfaces configured.");
-
-                    try {
-                        boolean success = mCaptureCollector.waitForEmpty(JPEG_FRAME_TIMEOUT,
-                                TimeUnit.MILLISECONDS);
-                        if (!success) {
-                            Log.e(TAG, "Timed out while queueing configure request.");
-                            mCaptureCollector.failAll();
-                        }
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "Interrupted while waiting for requests to complete.");
-                        mDeviceState.setError(
-                                CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                        break;
-                    }
-
-                    configureOutputs(config.surfaces);
-                    config.condition.open();
-                    if (DEBUG) {
-                        long totalTime = SystemClock.elapsedRealtimeNanos() - startTime;
-                        Log.d(TAG, "Configure took " + totalTime + " ns");
-                    }
-                    break;
-                case MSG_SUBMIT_CAPTURE_REQUEST:
-                    Handler handler = RequestThreadManager.this.mRequestThread.getHandler();
-                    boolean anyRequestOutputAbandoned = false;
-
-                    // Get the next burst from the request queue.
-                    RequestQueue.RequestQueueEntry nextBurst = mRequestQueue.getNext();
-
-                    if (nextBurst == null) {
-                        // If there are no further requests queued, wait for any currently executing
-                        // requests to complete, then switch to idle state.
-                        try {
-                            boolean success = mCaptureCollector.waitForEmpty(JPEG_FRAME_TIMEOUT,
-                                    TimeUnit.MILLISECONDS);
-                            if (!success) {
-                                Log.e(TAG,
-                                        "Timed out while waiting for prior requests to complete.");
-                                mCaptureCollector.failAll();
-                            }
-                        } catch (InterruptedException e) {
-                            Log.e(TAG, "Interrupted while waiting for requests to complete: ", e);
-                            mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                            break;
-                        }
-
-                        synchronized (mIdleLock) {
-                            // Retry the the request queue.
-                            nextBurst = mRequestQueue.getNext();
-
-                            // If we still have no queued requests, go idle.
-                            if (nextBurst == null) {
-                                mDeviceState.setIdle();
-                                break;
-                            }
-                        }
-                    }
-
-                    if (nextBurst != null) {
-                        // Queue another capture if we did not get the last burst.
-                        handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST);
-
-                        // Check whether capture queue becomes empty
-                        if (nextBurst.isQueueEmpty()) {
-                            mDeviceState.setRequestQueueEmpty();
-                        }
-                    }
-
-                    // Complete each request in the burst
-                    BurstHolder burstHolder = nextBurst.getBurstHolder();
-                    List<RequestHolder> requests =
-                            burstHolder.produceRequestHolders(nextBurst.getFrameNumber());
-                    for (RequestHolder holder : requests) {
-                        CaptureRequest request = holder.getRequest();
-
-                        boolean paramsChanged = false;
-
-                        // Only update parameters if the request has changed
-                        if (mLastRequest == null || mLastRequest.captureRequest != request) {
-
-                            // The intermediate buffer is sometimes null, but we always need
-                            // the Camera1 API configured preview size
-                            Size previewSize = ParameterUtils.convertSize(mParams.getPreviewSize());
-
-                            LegacyRequest legacyRequest = new LegacyRequest(mCharacteristics,
-                                    request, previewSize, mParams); // params are copied
-
-
-                            // Parameters are mutated as a side-effect
-                            LegacyMetadataMapper.convertRequestMetadata(/*inout*/legacyRequest);
-
-                            // If the parameters have changed, set them in the Camera1 API.
-                            if (!mParams.same(legacyRequest.parameters)) {
-                                try {
-                                    mCamera.setParameters(legacyRequest.parameters);
-                                } catch (RuntimeException e) {
-                                    // If setting the parameters failed, report a request error to
-                                    // the camera client, and skip any further work for this request
-                                    Log.e(TAG, "Exception while setting camera parameters: ", e);
-                                    holder.failRequest();
-                                    mDeviceState.setCaptureStart(holder, /*timestamp*/0,
-                                            CameraDeviceImpl.CameraDeviceCallbacks.
-                                                    ERROR_CAMERA_REQUEST);
-                                    continue;
-                                }
-                                paramsChanged = true;
-                                mParams = legacyRequest.parameters;
-                            }
-
-                            mLastRequest = legacyRequest;
-                        }
-
-                        try {
-                            boolean success = mCaptureCollector.queueRequest(holder,
-                                    mLastRequest, JPEG_FRAME_TIMEOUT, TimeUnit.MILLISECONDS);
-
-                            if (!success) {
-                                // Report a request error if we timed out while queuing this.
-                                Log.e(TAG, "Timed out while queueing capture request.");
-                                holder.failRequest();
-                                mDeviceState.setCaptureStart(holder, /*timestamp*/0,
-                                        CameraDeviceImpl.CameraDeviceCallbacks.
-                                                ERROR_CAMERA_REQUEST);
-                                continue;
-                            }
-
-                            // Starting the preview needs to happen before enabling
-                            // face detection or auto focus
-                            if (holder.hasPreviewTargets()) {
-                                doPreviewCapture(holder);
-                            }
-                            if (holder.hasJpegTargets()) {
-                                while(!mCaptureCollector.waitForPreviewsEmpty(PREVIEW_FRAME_TIMEOUT,
-                                        TimeUnit.MILLISECONDS)) {
-                                    // Fail preview requests until the queue is empty.
-                                    Log.e(TAG, "Timed out while waiting for preview requests to " +
-                                            "complete.");
-                                    mCaptureCollector.failNextPreview();
-                                }
-                                mReceivedJpeg.close();
-                                doJpegCapturePrepare(holder);
-                            }
-
-                            /*
-                             * Do all the actions that require a preview to have been started
-                             */
-
-                            // Toggle face detection on/off
-                            // - do this before AF to give AF a chance to use faces
-                            mFaceDetectMapper.processFaceDetectMode(request, /*in*/mParams);
-
-                            // Unconditionally process AF triggers, since they're non-idempotent
-                            // - must be done after setting the most-up-to-date AF mode
-                            mFocusStateMapper.processRequestTriggers(request, mParams);
-
-                            if (holder.hasJpegTargets()) {
-                                doJpegCapture(holder);
-                                if (!mReceivedJpeg.block(JPEG_FRAME_TIMEOUT)) {
-                                    Log.e(TAG, "Hit timeout for jpeg callback!");
-                                    mCaptureCollector.failNextJpeg();
-                                }
-                            }
-
-                        } catch (IOException e) {
-                            Log.e(TAG, "Received device exception during capture call: ", e);
-                            mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                            break;
-                        } catch (InterruptedException e) {
-                            Log.e(TAG, "Interrupted during capture: ", e);
-                            mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                            break;
-                        } catch (RuntimeException e) {
-                            Log.e(TAG, "Received device exception during capture call: ", e);
-                            mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                            break;
-                        }
-
-                        if (paramsChanged) {
-                            if (DEBUG) {
-                                Log.d(TAG, "Params changed -- getting new Parameters from HAL.");
-                            }
-                            try {
-                                mParams = mCamera.getParameters();
-                            } catch (RuntimeException e) {
-                                Log.e(TAG, "Received device exception: ", e);
-                                mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                                break;
-                            }
-
-                            // Update parameters to the latest that we think the camera is using
-                            mLastRequest.setParameters(mParams);
-                        }
-
-                        MutableLong timestampMutable = new MutableLong(/*value*/0L);
-                        try {
-                            boolean success = mCaptureCollector.waitForRequestCompleted(holder,
-                                    REQUEST_COMPLETE_TIMEOUT, TimeUnit.MILLISECONDS,
-                                    /*out*/timestampMutable);
-
-                            if (!success) {
-                                Log.e(TAG, "Timed out while waiting for request to complete.");
-                                mCaptureCollector.failAll();
-                            }
-                        } catch (InterruptedException e) {
-                            Log.e(TAG, "Interrupted waiting for request completion: ", e);
-                            mDeviceState.setError(
-                                    CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                            break;
-                        }
-
-                        CameraMetadataNative result = mMapper.cachedConvertResultMetadata(
-                                mLastRequest, timestampMutable.value);
-                        /*
-                         * Order matters: The default result mapper is state-less; the
-                         * other mappers carry state and may override keys set by the default
-                         * mapper with their own values.
-                         */
-
-                        // Update AF state
-                        mFocusStateMapper.mapResultTriggers(result);
-                        // Update face-related results
-                        mFaceDetectMapper.mapResultFaces(result, mLastRequest);
-
-                        if (!holder.requestFailed()) {
-                            mDeviceState.setCaptureResult(holder, result);
-                        }
-
-                        if (holder.isOutputAbandoned()) {
-                            anyRequestOutputAbandoned = true;
-                        }
-                    }
-
-                    // Stop the repeating request if any of its output surfaces is abandoned.
-                    if (anyRequestOutputAbandoned && burstHolder.isRepeating()) {
-                        long lastFrameNumber = cancelRepeating(burstHolder.getRequestId());
-                        if (DEBUG) {
-                            Log.d(TAG, "Stopped repeating request. Last frame number is " +
-                                    lastFrameNumber);
-                        }
-                        if (lastFrameNumber != RequestQueue.INVALID_FRAME) {
-                            mDeviceState.setRepeatingRequestError(lastFrameNumber,
-                                    burstHolder.getRequestId());
-                        } else {
-                            Log.e(TAG, "Repeating request id: " + burstHolder.getRequestId() +
-                                    " already canceled!");
-                        }
-                    }
-
-                    if (DEBUG) {
-                        long totalTime = SystemClock.elapsedRealtimeNanos() - startTime;
-                        Log.d(TAG, "Capture request took " + totalTime + " ns");
-                        mRequestCounter.countAndLog();
-                    }
-                    break;
-                case MSG_CLEANUP:
-                    mCleanup = true;
-                    try {
-                        boolean success = mCaptureCollector.waitForEmpty(JPEG_FRAME_TIMEOUT,
-                                TimeUnit.MILLISECONDS);
-                        if (!success) {
-                            Log.e(TAG, "Timed out while queueing cleanup request.");
-                            mCaptureCollector.failAll();
-                        }
-                    } catch (InterruptedException e) {
-                        Log.e(TAG, "Interrupted while waiting for requests to complete: ", e);
-                        mDeviceState.setError(
-                                CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
-                    }
-                    if (mGLThreadManager != null) {
-                        mGLThreadManager.quit();
-                        mGLThreadManager = null;
-                    }
-                    disconnectCallbackSurfaces();
-                    if (mCamera != null) {
-                        mCamera.release();
-                        mCamera = null;
-                    }
-                    break;
-                case RequestHandlerThread.MSG_POKE_IDLE_HANDLER:
-                    // OK: Ignore message.
-                    break;
-                default:
-                    throw new AssertionError("Unhandled message " + msg.what +
-                            " on RequestThread.");
-            }
-            return true;
-        }
-    };
-
-    /**
-     * Create a new RequestThreadManager.
-     *
-     * @param cameraId the id of the camera to use.
-     * @param camera an open camera object.  The RequestThreadManager takes ownership of this camera
-     *               object, and is responsible for closing it.
-     * @param characteristics the static camera characteristics corresponding to this camera device
-     * @param deviceState a {@link CameraDeviceState} state machine.
-     */
-    public RequestThreadManager(int cameraId, Camera camera, CameraCharacteristics characteristics,
-                                CameraDeviceState deviceState) {
-        mCamera = checkNotNull(camera, "camera must not be null");
-        mCameraId = cameraId;
-        mCharacteristics = checkNotNull(characteristics, "characteristics must not be null");
-        String name = String.format("RequestThread-%d", cameraId);
-        TAG = name;
-        mDeviceState = checkNotNull(deviceState, "deviceState must not be null");
-        mFocusStateMapper = new LegacyFocusStateMapper(mCamera);
-        mFaceDetectMapper = new LegacyFaceDetectMapper(mCamera, mCharacteristics);
-        mCaptureCollector = new CaptureCollector(MAX_IN_FLIGHT_REQUESTS, mDeviceState);
-        mRequestThread = new RequestHandlerThread(name, mRequestHandlerCb);
-        mCamera.setDetailedErrorCallback(mErrorCallback);
-    }
-
-    /**
-     * Start the request thread.
-     */
-    public void start() {
-        mRequestThread.start();
-    }
-
-    /**
-     * Flush any pending requests.
-     *
-     * @return the last frame number.
-     */
-    public long flush() {
-        Log.i(TAG, "Flushing all pending requests.");
-        long lastFrame = mRequestQueue.stopRepeating();
-        mCaptureCollector.failAll();
-        return lastFrame;
-    }
-
-    /**
-     * Quit the request thread, and clean up everything.
-     */
-    public void quit() {
-        if (!mQuit.getAndSet(true)) {  // Avoid sending messages on dead thread's handler.
-            Handler handler = mRequestThread.waitAndGetHandler();
-            handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP));
-            mRequestThread.quitSafely();
-            try {
-                mRequestThread.join();
-            } catch (InterruptedException e) {
-                Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
-                        mRequestThread.getName(), mRequestThread.getId()));
-            }
-        }
-    }
-
-    /**
-     * Submit the given burst of requests to be captured.
-     *
-     * <p>If the burst is repeating, replace the current repeating burst.</p>
-     *
-     * @param requests the burst of requests to add to the queue.
-     * @param repeating true if the burst is repeating.
-     * @return the submission info, including the new request id, and the last frame number, which
-     *   contains either the frame number of the last frame that will be returned for this request,
-     *   or the frame number of the last frame that will be returned for the current repeating
-     *   request if this burst is set to be repeating.
-     */
-    public SubmitInfo submitCaptureRequests(CaptureRequest[] requests, boolean repeating) {
-        Handler handler = mRequestThread.waitAndGetHandler();
-        SubmitInfo info;
-        synchronized (mIdleLock) {
-            info = mRequestQueue.submit(requests, repeating);
-            handler.sendEmptyMessage(MSG_SUBMIT_CAPTURE_REQUEST);
-        }
-        return info;
-    }
-
-    /**
-     * Cancel a repeating request.
-     *
-     * @param requestId the id of the repeating request to cancel.
-     * @return the last frame to be returned from the HAL for the given repeating request, or
-     *          {@code INVALID_FRAME} if none exists.
-     */
-    public long cancelRepeating(int requestId) {
-        return mRequestQueue.stopRepeating(requestId);
-    }
-
-    /**
-     * Configure with the current list of output Surfaces.
-     *
-     * <p>
-     * This operation blocks until the configuration is complete.
-     * </p>
-     *
-     * <p>Using a {@code null} or empty {@code outputs} list is the equivalent of unconfiguring.</p>
-     *
-     * @param outputs a {@link java.util.Collection} of outputs to configure.
-     */
-    public void configure(Collection<Pair<Surface, Size>> outputs) {
-        Handler handler = mRequestThread.waitAndGetHandler();
-        final ConditionVariable condition = new ConditionVariable(/*closed*/false);
-        ConfigureHolder holder = new ConfigureHolder(condition, outputs);
-        handler.sendMessage(handler.obtainMessage(MSG_CONFIGURE_OUTPUTS, 0, 0, holder));
-        condition.block();
-    }
-
-    public void setAudioRestriction(int mode) {
-        if (mCamera != null) {
-            mCamera.setAudioRestriction(mode);
-        }
-        throw new IllegalStateException("Camera has been released!");
-    }
-
-    public int getAudioRestriction() {
-        if (mCamera != null) {
-            return mCamera.getAudioRestriction();
-        }
-        throw new IllegalStateException("Camera has been released!");
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/SizeAreaComparator.java b/core/java/android/hardware/camera2/legacy/SizeAreaComparator.java
deleted file mode 100644
index 75a5bab..0000000
--- a/core/java/android/hardware/camera2/legacy/SizeAreaComparator.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.hardware.camera2.legacy;
-
-import android.hardware.Camera;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import static com.android.internal.util.Preconditions.*;
-
-/**
- * Comparator for api1 {@link Camera.Size} objects by the area.
- *
- * <p>This comparator totally orders by rectangle area. Tie-breaks on width.</p>
- */
-@SuppressWarnings("deprecation")
-public class SizeAreaComparator implements Comparator<Camera.Size> {
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int compare(Camera.Size size, Camera.Size size2) {
-        checkNotNull(size, "size must not be null");
-        checkNotNull(size2, "size2 must not be null");
-
-        if (size.equals(size2)) {
-            return 0;
-        }
-
-        long width = size.width;
-        long width2 = size2.width;
-        long area = width * size.height;
-        long area2 = width2 * size2.height;
-
-        if (area == area2) {
-            return (width > width2) ? 1 : -1;
-        }
-
-        return (area > area2) ? 1 : -1;
-    }
-
-    /**
-     * Get the largest api1 {@code Camera.Size} from the list by comparing each size's area
-     * by each other using {@link SizeAreaComparator}.
-     *
-     * @param sizes a non-{@code null} list of non-{@code null} sizes
-     * @return a non-{@code null} size
-     *
-     * @throws NullPointerException if {@code sizes} or any elements in it were {@code null}
-     */
-    public static Camera.Size findLargestByArea(List<Camera.Size> sizes) {
-        checkNotNull(sizes, "sizes must not be null");
-
-        return Collections.max(sizes, new SizeAreaComparator());
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java b/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
deleted file mode 100644
index a4c65ae..0000000
--- a/core/java/android/hardware/camera2/legacy/SurfaceTextureRenderer.java
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.hardware.camera2.legacy;
-
-import android.graphics.ImageFormat;
-import android.graphics.RectF;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCharacteristics;
-import android.os.Environment;
-import android.opengl.EGL14;
-import android.opengl.EGLConfig;
-import android.opengl.EGLContext;
-import android.opengl.EGLDisplay;
-import android.opengl.EGLSurface;
-import android.opengl.GLES11Ext;
-import android.opengl.GLES20;
-import android.opengl.Matrix;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-import android.os.SystemProperties;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.ZoneId;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * A renderer class that manages the GL state, and can draw a frame into a set of output
- * {@link Surface}s.
- */
-public class SurfaceTextureRenderer {
-    private static final String TAG = SurfaceTextureRenderer.class.getSimpleName();
-    private static final boolean DEBUG = false;
-    private static final int EGL_RECORDABLE_ANDROID = 0x3142; // from EGL/eglext.h
-    private static final int GL_MATRIX_SIZE = 16;
-    private static final int VERTEX_POS_SIZE = 3;
-    private static final int VERTEX_UV_SIZE = 2;
-    private static final int EGL_COLOR_BITLENGTH = 8;
-    private static final int GLES_VERSION = 2;
-    private static final int PBUFFER_PIXEL_BYTES = 4;
-
-    private static final int FLIP_TYPE_NONE = 0;
-    private static final int FLIP_TYPE_HORIZONTAL = 1;
-    private static final int FLIP_TYPE_VERTICAL = 2;
-    private static final int FLIP_TYPE_BOTH = FLIP_TYPE_HORIZONTAL | FLIP_TYPE_VERTICAL;
-
-    private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER =
-            DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss", Locale.ROOT);
-
-    private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
-    private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
-    private EGLConfig mConfigs;
-
-    private class EGLSurfaceHolder {
-        Surface surface;
-        EGLSurface eglSurface;
-        int width;
-        int height;
-    }
-
-    private List<EGLSurfaceHolder> mSurfaces = new ArrayList<EGLSurfaceHolder>();
-    private List<EGLSurfaceHolder> mConversionSurfaces = new ArrayList<EGLSurfaceHolder>();
-
-    private ByteBuffer mPBufferPixels;
-
-    // Hold this to avoid GC
-    private volatile SurfaceTexture mSurfaceTexture;
-
-    private static final int FLOAT_SIZE_BYTES = 4;
-    private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
-    private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
-    private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
-
-    // Sampling is mirrored across the horizontal axis
-    private static final float[] sHorizontalFlipTriangleVertices = {
-            // X, Y, Z, U, V
-            -1.0f, -1.0f, 0, 1.f, 0.f,
-            1.0f, -1.0f, 0, 0.f, 0.f,
-            -1.0f,  1.0f, 0, 1.f, 1.f,
-            1.0f,  1.0f, 0, 0.f, 1.f,
-    };
-
-    // Sampling is mirrored across the vertical axis
-    private static final float[] sVerticalFlipTriangleVertices = {
-            // X, Y, Z, U, V
-            -1.0f, -1.0f, 0, 0.f, 1.f,
-            1.0f, -1.0f, 0, 1.f, 1.f,
-            -1.0f,  1.0f, 0, 0.f, 0.f,
-            1.0f,  1.0f, 0, 1.f, 0.f,
-    };
-
-    // Sampling is mirrored across the both axes
-    private static final float[] sBothFlipTriangleVertices = {
-            // X, Y, Z, U, V
-            -1.0f, -1.0f, 0, 1.f, 1.f,
-            1.0f, -1.0f, 0, 0.f, 1.f,
-            -1.0f,  1.0f, 0, 1.f, 0.f,
-            1.0f,  1.0f, 0, 0.f, 0.f,
-    };
-
-    // Sampling is 1:1 for a straight copy for the back camera
-    private static final float[] sRegularTriangleVertices = {
-            // X, Y, Z, U, V
-            -1.0f, -1.0f, 0, 0.f, 0.f,
-            1.0f, -1.0f, 0, 1.f, 0.f,
-            -1.0f,  1.0f, 0, 0.f, 1.f,
-            1.0f,  1.0f, 0, 1.f, 1.f,
-    };
-
-    private FloatBuffer mRegularTriangleVertices;
-    private FloatBuffer mHorizontalFlipTriangleVertices;
-    private FloatBuffer mVerticalFlipTriangleVertices;
-    private FloatBuffer mBothFlipTriangleVertices;
-    private final int mFacing;
-
-    /**
-     * As used in this file, this vertex shader maps a unit square to the view, and
-     * tells the fragment shader to interpolate over it.  Each surface pixel position
-     * is mapped to a 2D homogeneous texture coordinate of the form (s, t, 0, 1) with
-     * s and t in the inclusive range [0, 1], and the matrix from
-     * {@link SurfaceTexture#getTransformMatrix(float[])} is used to map this
-     * coordinate to a texture location.
-     */
-    private static final String VERTEX_SHADER =
-            "uniform mat4 uMVPMatrix;\n" +
-            "uniform mat4 uSTMatrix;\n" +
-            "attribute vec4 aPosition;\n" +
-            "attribute vec4 aTextureCoord;\n" +
-            "varying vec2 vTextureCoord;\n" +
-            "void main() {\n" +
-            "  gl_Position = uMVPMatrix * aPosition;\n" +
-            "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
-            "}\n";
-
-    /**
-     * This fragment shader simply draws the color in the 2D texture at
-     * the location from the {@code VERTEX_SHADER}.
-     */
-    private static final String FRAGMENT_SHADER =
-            "#extension GL_OES_EGL_image_external : require\n" +
-            "precision mediump float;\n" +
-            "varying vec2 vTextureCoord;\n" +
-            "uniform samplerExternalOES sTexture;\n" +
-            "void main() {\n" +
-            "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
-            "}\n";
-
-    private float[] mMVPMatrix = new float[GL_MATRIX_SIZE];
-    private float[] mSTMatrix = new float[GL_MATRIX_SIZE];
-
-    private int mProgram;
-    private int mTextureID = 0;
-    private int muMVPMatrixHandle;
-    private int muSTMatrixHandle;
-    private int maPositionHandle;
-    private int maTextureHandle;
-
-    private PerfMeasurement mPerfMeasurer = null;
-    private static final String LEGACY_PERF_PROPERTY = "persist.camera.legacy_perf";
-
-    public SurfaceTextureRenderer(int facing) {
-        mFacing = facing;
-
-        mRegularTriangleVertices = ByteBuffer.allocateDirect(sRegularTriangleVertices.length *
-                FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
-        mRegularTriangleVertices.put(sRegularTriangleVertices).position(0);
-
-        mHorizontalFlipTriangleVertices = ByteBuffer.allocateDirect(
-                sHorizontalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
-                order(ByteOrder.nativeOrder()).asFloatBuffer();
-        mHorizontalFlipTriangleVertices.put(sHorizontalFlipTriangleVertices).position(0);
-
-        mVerticalFlipTriangleVertices = ByteBuffer.allocateDirect(
-                sVerticalFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
-                order(ByteOrder.nativeOrder()).asFloatBuffer();
-        mVerticalFlipTriangleVertices.put(sVerticalFlipTriangleVertices).position(0);
-
-        mBothFlipTriangleVertices = ByteBuffer.allocateDirect(
-                sBothFlipTriangleVertices.length * FLOAT_SIZE_BYTES).
-                order(ByteOrder.nativeOrder()).asFloatBuffer();
-        mBothFlipTriangleVertices.put(sBothFlipTriangleVertices).position(0);
-
-        Matrix.setIdentityM(mSTMatrix, 0);
-    }
-
-    private int loadShader(int shaderType, String source) {
-        int shader = GLES20.glCreateShader(shaderType);
-        checkGlError("glCreateShader type=" + shaderType);
-        GLES20.glShaderSource(shader, source);
-        GLES20.glCompileShader(shader);
-        int[] compiled = new int[1];
-        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
-        if (compiled[0] == 0) {
-            Log.e(TAG, "Could not compile shader " + shaderType + ":");
-            Log.e(TAG, " " + GLES20.glGetShaderInfoLog(shader));
-            GLES20.glDeleteShader(shader);
-            // TODO: handle this more gracefully
-            throw new IllegalStateException("Could not compile shader " + shaderType);
-        }
-        return shader;
-    }
-
-    private int createProgram(String vertexSource, String fragmentSource) {
-        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
-        if (vertexShader == 0) {
-            return 0;
-        }
-        int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
-        if (pixelShader == 0) {
-            return 0;
-        }
-
-        int program = GLES20.glCreateProgram();
-        checkGlError("glCreateProgram");
-        if (program == 0) {
-            Log.e(TAG, "Could not create program");
-        }
-        GLES20.glAttachShader(program, vertexShader);
-        checkGlError("glAttachShader");
-        GLES20.glAttachShader(program, pixelShader);
-        checkGlError("glAttachShader");
-        GLES20.glLinkProgram(program);
-        int[] linkStatus = new int[1];
-        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
-        if (linkStatus[0] != GLES20.GL_TRUE) {
-            Log.e(TAG, "Could not link program: ");
-            Log.e(TAG, GLES20.glGetProgramInfoLog(program));
-            GLES20.glDeleteProgram(program);
-            // TODO: handle this more gracefully
-            throw new IllegalStateException("Could not link program");
-        }
-        return program;
-    }
-
-    private void drawFrame(SurfaceTexture st, int width, int height, int flipType)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        checkGlError("onDrawFrame start");
-        st.getTransformMatrix(mSTMatrix);
-
-        Matrix.setIdentityM(mMVPMatrix, /*smOffset*/0);
-
-        // Find intermediate buffer dimensions
-        Size dimens;
-        try {
-            dimens = LegacyCameraDevice.getTextureSize(st);
-        } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-            // Should never hit this.
-            throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e);
-        }
-        float texWidth = dimens.getWidth();
-        float texHeight = dimens.getHeight();
-
-        if (texWidth <= 0 || texHeight <= 0) {
-            throw new IllegalStateException("Illegal intermediate texture with dimension of 0");
-        }
-
-        // Letterbox or pillar-box output dimensions into intermediate dimensions.
-        RectF intermediate = new RectF(/*left*/0, /*top*/0, /*right*/texWidth, /*bottom*/texHeight);
-        RectF output = new RectF(/*left*/0, /*top*/0, /*right*/width, /*bottom*/height);
-        android.graphics.Matrix boxingXform = new android.graphics.Matrix();
-        boxingXform.setRectToRect(output, intermediate, android.graphics.Matrix.ScaleToFit.CENTER);
-        boxingXform.mapRect(output);
-
-        // Find scaling factor from pillar-boxed/letter-boxed output dimensions to intermediate
-        // buffer dimensions.
-        float scaleX = intermediate.width() / output.width();
-        float scaleY = intermediate.height() / output.height();
-
-        // Intermediate texture is implicitly scaled to 'fill' the output dimensions in clip space
-        // coordinates in the shader.  To avoid stretching, we need to scale the larger dimension
-        // of the intermediate buffer so that the output buffer is actually letter-boxed
-        // or pillar-boxed into the intermediate buffer after clipping.
-        Matrix.scaleM(mMVPMatrix, /*offset*/0, /*x*/scaleX, /*y*/scaleY, /*z*/1);
-
-        if (DEBUG) {
-            Log.d(TAG, "Scaling factors (S_x = " + scaleX + ",S_y = " + scaleY + ") used for " +
-                    width + "x" + height + " surface, intermediate buffer size is " + texWidth +
-                    "x" + texHeight);
-        }
-
-        // Set viewport to be output buffer dimensions
-        GLES20.glViewport(0, 0, width, height);
-
-        if (DEBUG) {
-            GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
-            GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
-        }
-
-        GLES20.glUseProgram(mProgram);
-        checkGlError("glUseProgram");
-
-        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
-        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
-
-        FloatBuffer triangleVertices;
-        switch(flipType) {
-            case FLIP_TYPE_HORIZONTAL:
-                triangleVertices = mHorizontalFlipTriangleVertices;
-                break;
-            case FLIP_TYPE_VERTICAL:
-                triangleVertices = mVerticalFlipTriangleVertices;
-                break;
-            case FLIP_TYPE_BOTH:
-                triangleVertices = mBothFlipTriangleVertices;
-                break;
-            default:
-                triangleVertices = mRegularTriangleVertices;
-                break;
-        }
-
-        triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
-        GLES20.glVertexAttribPointer(maPositionHandle, VERTEX_POS_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
-        checkGlError("glVertexAttribPointer maPosition");
-        GLES20.glEnableVertexAttribArray(maPositionHandle);
-        checkGlError("glEnableVertexAttribArray maPositionHandle");
-
-        triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
-        GLES20.glVertexAttribPointer(maTextureHandle, VERTEX_UV_SIZE, GLES20.GL_FLOAT,
-                /*normalized*/ false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
-        checkGlError("glVertexAttribPointer maTextureHandle");
-        GLES20.glEnableVertexAttribArray(maTextureHandle);
-        checkGlError("glEnableVertexAttribArray maTextureHandle");
-
-        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, /*count*/ 1, /*transpose*/ false, mMVPMatrix,
-                /*offset*/ 0);
-        GLES20.glUniformMatrix4fv(muSTMatrixHandle, /*count*/ 1, /*transpose*/ false, mSTMatrix,
-                /*offset*/ 0);
-
-        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, /*offset*/ 0, /*count*/ 4);
-        checkGlDrawError("glDrawArrays");
-    }
-
-    /**
-     * Initializes GL state.  Call this after the EGL surface has been created and made current.
-     */
-    private void initializeGLState() {
-        mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
-        if (mProgram == 0) {
-            throw new IllegalStateException("failed creating program");
-        }
-        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
-        checkGlError("glGetAttribLocation aPosition");
-        if (maPositionHandle == -1) {
-            throw new IllegalStateException("Could not get attrib location for aPosition");
-        }
-        maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
-        checkGlError("glGetAttribLocation aTextureCoord");
-        if (maTextureHandle == -1) {
-            throw new IllegalStateException("Could not get attrib location for aTextureCoord");
-        }
-
-        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
-        checkGlError("glGetUniformLocation uMVPMatrix");
-        if (muMVPMatrixHandle == -1) {
-            throw new IllegalStateException("Could not get attrib location for uMVPMatrix");
-        }
-
-        muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
-        checkGlError("glGetUniformLocation uSTMatrix");
-        if (muSTMatrixHandle == -1) {
-            throw new IllegalStateException("Could not get attrib location for uSTMatrix");
-        }
-
-        int[] textures = new int[1];
-        GLES20.glGenTextures(/*n*/ 1, textures, /*offset*/ 0);
-
-        mTextureID = textures[0];
-        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
-        checkGlError("glBindTexture mTextureID");
-
-        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
-                GLES20.GL_NEAREST);
-        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
-                GLES20.GL_LINEAR);
-        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
-                GLES20.GL_CLAMP_TO_EDGE);
-        GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
-                GLES20.GL_CLAMP_TO_EDGE);
-        checkGlError("glTexParameter");
-    }
-
-    private int getTextureId() {
-        return mTextureID;
-    }
-
-    private void clearState() {
-        mSurfaces.clear();
-        for (EGLSurfaceHolder holder : mConversionSurfaces) {
-            try {
-                LegacyCameraDevice.disconnectSurface(holder.surface);
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping...", e);
-            }
-        }
-        mConversionSurfaces.clear();
-        mPBufferPixels = null;
-        if (mSurfaceTexture != null) {
-            mSurfaceTexture.release();
-        }
-        mSurfaceTexture = null;
-    }
-
-    private void configureEGLContext() {
-        mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
-        if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
-            throw new IllegalStateException("No EGL14 display");
-        }
-        int[] version = new int[2];
-        if (!EGL14.eglInitialize(mEGLDisplay, version, /*offset*/ 0, version, /*offset*/ 1)) {
-            throw new IllegalStateException("Cannot initialize EGL14");
-        }
-
-        int[] attribList = {
-                EGL14.EGL_RED_SIZE, EGL_COLOR_BITLENGTH,
-                EGL14.EGL_GREEN_SIZE, EGL_COLOR_BITLENGTH,
-                EGL14.EGL_BLUE_SIZE, EGL_COLOR_BITLENGTH,
-                EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
-                EGL_RECORDABLE_ANDROID, 1,
-                EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT | EGL14.EGL_WINDOW_BIT,
-                EGL14.EGL_NONE
-        };
-        EGLConfig[] configs = new EGLConfig[1];
-        int[] numConfigs = new int[1];
-        EGL14.eglChooseConfig(mEGLDisplay, attribList, /*offset*/ 0, configs, /*offset*/ 0,
-                configs.length, numConfigs, /*offset*/ 0);
-        checkEglError("eglCreateContext RGB888+recordable ES2");
-        mConfigs = configs[0];
-        int[] attrib_list = {
-                EGL14.EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION,
-                EGL14.EGL_NONE
-        };
-        mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], EGL14.EGL_NO_CONTEXT,
-                attrib_list, /*offset*/ 0);
-        checkEglError("eglCreateContext");
-        if(mEGLContext == EGL14.EGL_NO_CONTEXT) {
-            throw new IllegalStateException("No EGLContext could be made");
-        }
-    }
-
-    private void configureEGLOutputSurfaces(Collection<EGLSurfaceHolder> surfaces) {
-        if (surfaces == null || surfaces.size() == 0) {
-            throw new IllegalStateException("No Surfaces were provided to draw to");
-        }
-        int[] surfaceAttribs = {
-                EGL14.EGL_NONE
-        };
-        for (EGLSurfaceHolder holder : surfaces) {
-            holder.eglSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs,
-                    holder.surface, surfaceAttribs, /*offset*/ 0);
-            checkEglError("eglCreateWindowSurface");
-        }
-    }
-
-    private void configureEGLPbufferSurfaces(Collection<EGLSurfaceHolder> surfaces) {
-        if (surfaces == null || surfaces.size() == 0) {
-            throw new IllegalStateException("No Surfaces were provided to draw to");
-        }
-
-        int maxLength = 0;
-        for (EGLSurfaceHolder holder : surfaces) {
-            int length = holder.width * holder.height;
-            // Find max surface size, ensure PBuffer can hold this many pixels
-            maxLength = (length > maxLength) ? length : maxLength;
-            int[] surfaceAttribs = {
-                    EGL14.EGL_WIDTH, holder.width,
-                    EGL14.EGL_HEIGHT, holder.height,
-                    EGL14.EGL_NONE
-            };
-            holder.eglSurface =
-                    EGL14.eglCreatePbufferSurface(mEGLDisplay, mConfigs, surfaceAttribs, 0);
-            checkEglError("eglCreatePbufferSurface");
-        }
-        mPBufferPixels = ByteBuffer.allocateDirect(maxLength * PBUFFER_PIXEL_BYTES)
-                .order(ByteOrder.nativeOrder());
-    }
-
-    private void releaseEGLContext() {
-        if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
-            EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE,
-                    EGL14.EGL_NO_CONTEXT);
-            dumpGlTiming();
-            if (mSurfaces != null) {
-                for (EGLSurfaceHolder holder : mSurfaces) {
-                    if (holder.eglSurface != null) {
-                        EGL14.eglDestroySurface(mEGLDisplay, holder.eglSurface);
-                    }
-                }
-            }
-            if (mConversionSurfaces != null) {
-                for (EGLSurfaceHolder holder : mConversionSurfaces) {
-                    if (holder.eglSurface != null) {
-                        EGL14.eglDestroySurface(mEGLDisplay, holder.eglSurface);
-                    }
-                }
-            }
-            EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
-            EGL14.eglReleaseThread();
-            EGL14.eglTerminate(mEGLDisplay);
-        }
-
-        mConfigs = null;
-        mEGLDisplay = EGL14.EGL_NO_DISPLAY;
-        mEGLContext = EGL14.EGL_NO_CONTEXT;
-        clearState();
-    }
-
-    private void makeCurrent(EGLSurface surface)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        EGL14.eglMakeCurrent(mEGLDisplay, surface, surface, mEGLContext);
-        checkEglDrawError("makeCurrent");
-    }
-
-    private boolean swapBuffers(EGLSurface surface)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        boolean result = EGL14.eglSwapBuffers(mEGLDisplay, surface);
-
-        int error = EGL14.eglGetError();
-        switch (error) {
-            case EGL14.EGL_SUCCESS:
-                return result;
-
-            // Check for an abandoned buffer queue, or other error conditions out
-            // of the user's control.
-            //
-            // From the EGL 1.4 spec (2013-12-04), Section 3.9.4 Posting Errors:
-            //
-            //   If eglSwapBuffers is called and the native window associated with
-            //   surface is no longer valid, an EGL_BAD_NATIVE_WINDOW error is
-            //   generated.
-            //
-            // We also interpret EGL_BAD_SURFACE as indicating an abandoned
-            // surface, even though the EGL spec does not document it as such, for
-            // backwards compatibility with older versions of this file.
-            case EGL14.EGL_BAD_NATIVE_WINDOW:
-            case EGL14.EGL_BAD_SURFACE:
-                throw new LegacyExceptionUtils.BufferQueueAbandonedException();
-
-            default:
-                throw new IllegalStateException(
-                        "swapBuffers: EGL error: 0x" + Integer.toHexString(error));
-        }
-    }
-
-    private void checkEglDrawError(String msg)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        int error;
-        if ((error = EGL14.eglGetError()) == EGL14.EGL_BAD_NATIVE_WINDOW) {
-            throw new LegacyExceptionUtils.BufferQueueAbandonedException();
-        }
-        if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) {
-            throw new IllegalStateException(msg + ": EGL error: 0x" + Integer.toHexString(error));
-        }
-    }
-
-    private void checkEglError(String msg) {
-        int error;
-        if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) {
-            throw new IllegalStateException(msg + ": EGL error: 0x" + Integer.toHexString(error));
-        }
-    }
-
-    private void checkGlError(String msg) {
-        int error;
-        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
-            throw new IllegalStateException(
-                    msg + ": GLES20 error: 0x" + Integer.toHexString(error));
-        }
-    }
-
-    private void checkGlDrawError(String msg)
-            throws LegacyExceptionUtils.BufferQueueAbandonedException {
-        int error;
-        boolean surfaceAbandoned = false;
-        boolean glError = false;
-        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
-            if (error == GLES20.GL_OUT_OF_MEMORY) {
-                surfaceAbandoned = true;
-            } else {
-                glError = true;
-            }
-        }
-        if (glError) {
-            throw new IllegalStateException(
-                    msg + ": GLES20 error: 0x" + Integer.toHexString(error));
-        }
-        if (surfaceAbandoned) {
-            throw new LegacyExceptionUtils.BufferQueueAbandonedException();
-        }
-    }
-
-    /**
-     * Save a measurement dump to disk, in
-     * {@code /sdcard/CameraLegacy/durations_<time>_<width1>x<height1>_...txt}
-     */
-    private void dumpGlTiming() {
-        if (mPerfMeasurer == null) return;
-
-        File legacyStorageDir = new File(Environment.getExternalStorageDirectory(), "CameraLegacy");
-        if (!legacyStorageDir.exists()){
-            if (!legacyStorageDir.mkdirs()){
-                Log.e(TAG, "Failed to create directory for data dump");
-                return;
-            }
-        }
-
-        StringBuilder path = new StringBuilder(legacyStorageDir.getPath());
-        path.append(File.separator);
-        path.append("durations_");
-
-        path.append(formatTimestamp(System.currentTimeMillis()));
-        path.append("_S");
-        for (EGLSurfaceHolder surface : mSurfaces) {
-            path.append(String.format("_%d_%d", surface.width, surface.height));
-        }
-        path.append("_C");
-        for (EGLSurfaceHolder surface : mConversionSurfaces) {
-            path.append(String.format("_%d_%d", surface.width, surface.height));
-        }
-        path.append(".txt");
-        mPerfMeasurer.dumpPerformanceData(path.toString());
-    }
-
-    private static String formatTimestamp(long timeMillis) {
-        // This is a replacement for {@link Time#format2445()} that doesn't suffer from Y2038
-        // issues.
-        Instant instant = Instant.ofEpochMilli(timeMillis);
-        ZoneId zoneId = ZoneId.systemDefault();
-        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
-        return LOG_NAME_TIME_FORMATTER.format(localDateTime);
-    }
-
-    private void setupGlTiming() {
-        if (PerfMeasurement.isGlTimingSupported()) {
-            Log.d(TAG, "Enabling GL performance measurement");
-            mPerfMeasurer = new PerfMeasurement();
-        } else {
-            Log.d(TAG, "GL performance measurement not supported on this device");
-            mPerfMeasurer = null;
-        }
-    }
-
-    private void beginGlTiming() {
-        if (mPerfMeasurer == null) return;
-        mPerfMeasurer.startTimer();
-    }
-
-    private void addGlTimestamp(long timestamp) {
-        if (mPerfMeasurer == null) return;
-        mPerfMeasurer.addTimestamp(timestamp);
-    }
-
-    private void endGlTiming() {
-        if (mPerfMeasurer == null) return;
-        mPerfMeasurer.stopTimer();
-    }
-
-    /**
-     * Return the surface texture to draw to - this is the texture use to when producing output
-     * surface buffers.
-     *
-     * @return a {@link SurfaceTexture}.
-     */
-    public SurfaceTexture getSurfaceTexture() {
-        return mSurfaceTexture;
-    }
-
-    /**
-     * Set a collection of output {@link Surface}s that can be drawn to.
-     *
-     * @param surfaces a {@link Collection} of surfaces.
-     */
-    public void configureSurfaces(Collection<Pair<Surface, Size>> surfaces) {
-        releaseEGLContext();
-
-        if (surfaces == null || surfaces.size() == 0) {
-            Log.w(TAG, "No output surfaces configured for GL drawing.");
-            return;
-        }
-
-        for (Pair<Surface, Size> p : surfaces) {
-            Surface s = p.first;
-            Size surfaceSize = p.second;
-            // If pixel conversions aren't handled by egl, use a pbuffer
-            try {
-                EGLSurfaceHolder holder = new EGLSurfaceHolder();
-                holder.surface = s;
-                holder.width = surfaceSize.getWidth();
-                holder.height = surfaceSize.getHeight();
-                if (LegacyCameraDevice.needsConversion(s)) {
-                    mConversionSurfaces.add(holder);
-                    // LegacyCameraDevice is the producer of surfaces if it's not handled by EGL,
-                    // so LegacyCameraDevice needs to connect to the surfaces.
-                    LegacyCameraDevice.connectSurface(s);
-                } else {
-                    mSurfaces.add(holder);
-                }
-            } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping configuration... ", e);
-            }
-        }
-
-        // Set up egl display
-        configureEGLContext();
-
-        // Set up regular egl surfaces if needed
-        if (mSurfaces.size() > 0) {
-            configureEGLOutputSurfaces(mSurfaces);
-        }
-
-        // Set up pbuffer surface if needed
-        if (mConversionSurfaces.size() > 0) {
-            configureEGLPbufferSurfaces(mConversionSurfaces);
-        }
-
-        try {
-            makeCurrent((mSurfaces.size() > 0) ? mSurfaces.get(0).eglSurface :
-                mConversionSurfaces.get(0).eglSurface);
-        } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                Log.w(TAG, "Surface abandoned, skipping configuration... ", e);
-        }
-
-        initializeGLState();
-        mSurfaceTexture = new SurfaceTexture(getTextureId());
-
-        // Set up performance tracking if enabled
-        if (SystemProperties.getBoolean(LEGACY_PERF_PROPERTY, false)) {
-            setupGlTiming();
-        }
-    }
-
-    /**
-     * Draw the current buffer in the {@link SurfaceTexture} returned from
-     * {@link #getSurfaceTexture()} into the set of target {@link Surface}s
-     * in the next request from the given {@link CaptureCollector}, or drop
-     * the frame if none is available.
-     *
-     * <p>
-     * Any {@link Surface}s targeted must be a subset of the {@link Surface}s
-     * set in the last {@link #configureSurfaces(java.util.Collection)} call.
-     * </p>
-     *
-     * @param targetCollector the surfaces to draw to.
-     */
-    public void drawIntoSurfaces(CaptureCollector targetCollector) {
-        if ((mSurfaces == null || mSurfaces.size() == 0)
-                && (mConversionSurfaces == null || mConversionSurfaces.size() == 0)) {
-            return;
-        }
-
-        boolean doTiming = targetCollector.hasPendingPreviewCaptures();
-        checkGlError("before updateTexImage");
-
-        if (doTiming) {
-            beginGlTiming();
-        }
-
-        mSurfaceTexture.updateTexImage();
-
-        long timestamp = mSurfaceTexture.getTimestamp();
-
-        Pair<RequestHolder, Long> captureHolder = targetCollector.previewCaptured(timestamp);
-
-        // No preview request queued, drop frame.
-        if (captureHolder == null) {
-            if (DEBUG) {
-                Log.d(TAG, "Dropping preview frame.");
-            }
-            if (doTiming) {
-                endGlTiming();
-            }
-            return;
-        }
-
-        RequestHolder request = captureHolder.first;
-
-        Collection<Surface> targetSurfaces = request.getHolderTargets();
-        if (doTiming) {
-            addGlTimestamp(timestamp);
-        }
-
-        List<Long> targetSurfaceIds = new ArrayList();
-        try {
-            targetSurfaceIds = LegacyCameraDevice.getSurfaceIds(targetSurfaces);
-        } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-            Log.w(TAG, "Surface abandoned, dropping frame. ", e);
-            request.setOutputAbandoned();
-        }
-
-        for (EGLSurfaceHolder holder : mSurfaces) {
-            if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
-                try{
-                    LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
-                            holder.height);
-                    makeCurrent(holder.eglSurface);
-
-                    LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
-                    drawFrame(mSurfaceTexture, holder.width, holder.height,
-                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
-                                    FLIP_TYPE_HORIZONTAL : FLIP_TYPE_NONE);
-                    swapBuffers(holder.eglSurface);
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, dropping frame. ", e);
-                    request.setOutputAbandoned();
-                }
-            }
-        }
-        for (EGLSurfaceHolder holder : mConversionSurfaces) {
-            if (LegacyCameraDevice.containsSurfaceId(holder.surface, targetSurfaceIds)) {
-                // glReadPixels reads from the bottom of the buffer, so add an extra vertical flip
-                try {
-                    makeCurrent(holder.eglSurface);
-                    drawFrame(mSurfaceTexture, holder.width, holder.height,
-                            (mFacing == CameraCharacteristics.LENS_FACING_FRONT) ?
-                                    FLIP_TYPE_BOTH : FLIP_TYPE_VERTICAL);
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    // Should never hit this.
-                    throw new IllegalStateException("Surface abandoned, skipping drawFrame...", e);
-                }
-                mPBufferPixels.clear();
-                GLES20.glReadPixels(/*x*/ 0, /*y*/ 0, holder.width, holder.height,
-                        GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, mPBufferPixels);
-                checkGlError("glReadPixels");
-
-                try {
-                    int format = LegacyCameraDevice.detectSurfaceType(holder.surface);
-                    LegacyCameraDevice.setSurfaceDimens(holder.surface, holder.width,
-                            holder.height);
-                    LegacyCameraDevice.setNextTimestamp(holder.surface, captureHolder.second);
-                    LegacyCameraDevice.produceFrame(holder.surface, mPBufferPixels.array(),
-                            holder.width, holder.height, format);
-                } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) {
-                    Log.w(TAG, "Surface abandoned, dropping frame. ", e);
-                    request.setOutputAbandoned();
-                }
-            }
-        }
-        targetCollector.previewProduced();
-
-        if (doTiming) {
-            endGlTiming();
-        }
-    }
-
-    /**
-     * Clean up the current GL context.
-     */
-    public void cleanupEGLContext() {
-        releaseEGLContext();
-    }
-
-    /**
-     * Drop all current GL operations on the floor.
-     */
-    public void flush() {
-        // TODO: implement flush
-        Log.e(TAG, "Flush not yet implemented.");
-    }
-}
diff --git a/core/java/android/hardware/camera2/legacy/package.html b/core/java/android/hardware/camera2/legacy/package.html
deleted file mode 100644
index db6f78b..0000000
--- a/core/java/android/hardware/camera2/legacy/package.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<body>
-{@hide}
-</body>
\ No newline at end of file
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index c37f9fe..52251ba 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -24,7 +24,6 @@
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.CameraMetadata;
 import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.legacy.LegacyCameraDevice;
 import android.hardware.camera2.utils.HashCodeHelpers;
 import android.hardware.camera2.utils.SurfaceUtils;
 import android.util.Range;
@@ -69,6 +68,8 @@
 
     private static final String TAG = "StreamConfigurationMap";
 
+    private static final int MAX_DIMEN_FOR_ROUNDING = 1920; // maximum allowed width for rounding
+
     /**
      * Create a new {@link StreamConfigurationMap}.
      *
@@ -568,7 +569,7 @@
                 if (config.getSize().equals(surfaceSize)) {
                     return true;
                 } else if (isFlexible &&
-                        (config.getSize().getWidth() <= LegacyCameraDevice.MAX_DIMEN_FOR_ROUNDING)) {
+                        (config.getSize().getWidth() <= MAX_DIMEN_FOR_ROUNDING)) {
                     return true;
                 }
             }
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index abe1372..35b5c15 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -16,10 +16,14 @@
 
 package android.hardware.camera2.utils;
 
+import static android.system.OsConstants.EINVAL;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.graphics.ImageFormat;
-import android.hardware.camera2.legacy.LegacyCameraDevice;
-import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException;
+import android.graphics.PixelFormat;
+import android.hardware.HardwareBuffer;
 import android.hardware.camera2.params.StreamConfigurationMap;
 import android.util.Range;
 import android.util.Size;
@@ -35,6 +39,15 @@
  */
 public class SurfaceUtils {
 
+    // Usage flags not yet included in HardwareBuffer
+    private static final int USAGE_RENDERSCRIPT = 0x00100000;
+    private static final int USAGE_HW_COMPOSER = 0x00000800;
+
+    // Image formats not yet included in PixelFormat
+    private static final int BGRA_8888 = 0x5;
+
+    private static final int BAD_VALUE = -EINVAL;
+
     /**
      * Check if a surface is for preview consumer based on consumer end point Gralloc usage flags.
      *
@@ -42,7 +55,17 @@
      * @return true if the surface is for preview consumer, false otherwise.
      */
     public static boolean isSurfaceForPreview(Surface surface) {
-        return LegacyCameraDevice.isPreviewConsumer(surface);
+        checkNotNull(surface);
+        long usageFlags = nativeDetectSurfaceUsageFlags(surface);
+        long disallowedFlags = HardwareBuffer.USAGE_VIDEO_ENCODE | USAGE_RENDERSCRIPT
+                | HardwareBuffer.USAGE_CPU_READ_OFTEN;
+        long allowedFlags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | USAGE_HW_COMPOSER
+                | HardwareBuffer.USAGE_GPU_COLOR_OUTPUT;
+        boolean previewConsumer = ((usageFlags & disallowedFlags) == 0
+                && (usageFlags & allowedFlags) != 0);
+        int surfaceFormat = getSurfaceFormat(surface);
+
+        return previewConsumer;
     }
 
     /**
@@ -53,7 +76,17 @@
      * @return true if the surface is for hardware video encoder consumer, false otherwise.
      */
     public static boolean isSurfaceForHwVideoEncoder(Surface surface) {
-        return LegacyCameraDevice.isVideoEncoderConsumer(surface);
+        checkNotNull(surface);
+        long usageFlags = nativeDetectSurfaceUsageFlags(surface);
+        long disallowedFlags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE | USAGE_HW_COMPOSER
+                | USAGE_RENDERSCRIPT | HardwareBuffer.USAGE_CPU_READ_OFTEN;
+        long allowedFlags = HardwareBuffer.USAGE_VIDEO_ENCODE;
+        boolean videoEncoderConsumer = ((usageFlags & disallowedFlags) == 0
+                && (usageFlags & allowedFlags) != 0);
+
+        int surfaceFormat = getSurfaceFormat(surface);
+
+        return videoEncoderConsumer;
     }
 
     /**
@@ -63,9 +96,10 @@
      * @return the native object id of the surface, 0 if surface is not backed by a native object.
      */
     public static long getSurfaceId(Surface surface) {
+        checkNotNull(surface);
         try {
-            return LegacyCameraDevice.getSurfaceId(surface);
-        } catch (BufferQueueAbandonedException e) {
+            return nativeGetSurfaceId(surface);
+        } catch (IllegalArgumentException e) {
             return 0;
         }
     }
@@ -80,11 +114,13 @@
      */
     @UnsupportedAppUsage
     public static Size getSurfaceSize(Surface surface) {
-        try {
-            return LegacyCameraDevice.getSurfaceSize(surface);
-        } catch (BufferQueueAbandonedException e) {
-            throw new IllegalArgumentException("Surface was abandoned", e);
-        }
+        checkNotNull(surface);
+
+        int[] dimens = new int[2];
+        int errorFlag =  nativeDetectSurfaceDimens(surface, /*out*/dimens);
+        if (errorFlag == BAD_VALUE) throw new IllegalArgumentException("Surface was abandoned");
+
+        return new Size(dimens[0], dimens[1]);
     }
 
     /**
@@ -96,11 +132,17 @@
      * @throws IllegalArgumentException if the surface is already abandoned.
      */
     public static int getSurfaceFormat(Surface surface) {
-        try {
-            return LegacyCameraDevice.detectSurfaceType(surface);
-        } catch (BufferQueueAbandonedException e) {
-            throw new IllegalArgumentException("Surface was abandoned", e);
+        checkNotNull(surface);
+        int surfaceType = nativeDetectSurfaceType(surface);
+        if (surfaceType == BAD_VALUE) throw new IllegalArgumentException("Surface was abandoned");
+
+        // TODO: remove this override since the default format should be
+        // ImageFormat.PRIVATE. b/9487482
+        if ((surfaceType >= PixelFormat.RGBA_8888
+                && surfaceType <= BGRA_8888)) {
+            surfaceType = ImageFormat.PRIVATE;
         }
+        return surfaceType;
     }
 
     /**
@@ -112,11 +154,10 @@
      * @throws IllegalArgumentException if the surface is already abandoned.
      */
     public static int getSurfaceDataspace(Surface surface) {
-        try {
-            return LegacyCameraDevice.detectSurfaceDataspace(surface);
-        } catch (BufferQueueAbandonedException e) {
-            throw new IllegalArgumentException("Surface was abandoned", e);
-        }
+        checkNotNull(surface);
+        int dataSpace = nativeDetectSurfaceDataspace(surface);
+        if (dataSpace == BAD_VALUE) throw new IllegalArgumentException("Surface was abandoned");
+        return dataSpace;
     }
 
     /**
@@ -125,9 +166,21 @@
      *
      */
     public static boolean isFlexibleConsumer(Surface output) {
-        return LegacyCameraDevice.isFlexibleConsumer(output);
+        checkNotNull(output);
+        long usageFlags = nativeDetectSurfaceUsageFlags(output);
+
+        // Keep up to date with allowed consumer types in
+        // frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+        long disallowedFlags = HardwareBuffer.USAGE_VIDEO_ENCODE | USAGE_RENDERSCRIPT;
+        long allowedFlags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
+                | HardwareBuffer.USAGE_CPU_READ_OFTEN
+                | USAGE_HW_COMPOSER;
+        boolean flexibleConsumer = ((usageFlags & disallowedFlags) == 0
+                && (usageFlags & allowedFlags) != 0);
+        return flexibleConsumer;
     }
 
+
     /**
      * A high speed output surface can only be preview or hardware encoder surface.
      *
@@ -209,4 +262,14 @@
         }
     }
 
+    private static native int nativeDetectSurfaceType(Surface surface);
+
+    private static native int nativeDetectSurfaceDataspace(Surface surface);
+
+    private static native long nativeDetectSurfaceUsageFlags(Surface surface);
+
+    private static native int nativeDetectSurfaceDimens(Surface surface,
+            /*out*/int[/*2*/] dimens);
+
+    private static native long nativeGetSurfaceId(Surface surface);
 }
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index c7fc2ad..b4546a4 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -592,7 +592,7 @@
                         new IBiometricServiceLockoutResetCallback.Stub() {
 
                             @Override
-                            public void onLockoutReset(IRemoteCallback serverCallback)
+                            public void onLockoutReset(int sensorId, IRemoteCallback serverCallback)
                                     throws RemoteException {
                                 try {
                                     final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
@@ -601,7 +601,7 @@
                                     wakeLock.acquire();
                                     mHandler.post(() -> {
                                         try {
-                                            callback.onLockoutReset();
+                                            callback.onLockoutReset(sensorId);
                                         } finally {
                                             wakeLock.release();
                                         }
@@ -978,7 +978,7 @@
          * authentication
          * again.
          */
-        public void onLockoutReset() {
+        public void onLockoutReset(int sensorId) {
         }
     }
 
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 9dacca7..4ca75d9 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -347,7 +347,7 @@
          * Called when lockout period expired and clients are allowed to listen for fingerprint
          * again.
          */
-        public void onLockoutReset() { }
+        public void onLockoutReset(int sensorId) { }
     };
 
     /**
@@ -751,7 +751,7 @@
                         new IBiometricServiceLockoutResetCallback.Stub() {
 
                     @Override
-                    public void onLockoutReset(IRemoteCallback serverCallback)
+                    public void onLockoutReset(int sensorId, IRemoteCallback serverCallback)
                             throws RemoteException {
                         try {
                             final PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
@@ -759,7 +759,7 @@
                             wakeLock.acquire();
                             mHandler.post(() -> {
                                 try {
-                                    callback.onLockoutReset();
+                                    callback.onLockoutReset(sensorId);
                                 } finally {
                                     wakeLock.release();
                                 }
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index ad58fea..38d7d2b 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -117,12 +117,6 @@
     // Returns whether the specified sensor is an under-display fingerprint sensor (UDFPS).
     boolean isUdfps(int sensorId);
 
-    // Shows the UDFPS overlay.
-    void showUdfpsOverlay();
-
-    // Hides the UDFPS overlay.
-    void hideUdfpsOverlay();
-
     // Sets the controller for managing the UDFPS overlay.
     void setUdfpsOverlayController(in IUdfpsOverlayController controller);
 }
diff --git a/core/java/android/inputmethodservice/InlineSuggestionSession.java b/core/java/android/inputmethodservice/InlineSuggestionSession.java
index 90d0ff0a..20bf6e0 100644
--- a/core/java/android/inputmethodservice/InlineSuggestionSession.java
+++ b/core/java/android/inputmethodservice/InlineSuggestionSession.java
@@ -152,7 +152,7 @@
         try {
             mCallback.onInlineSuggestionsSessionInvalidated();
         } catch (RemoteException e) {
-            Log.w(TAG, "onInlineSuggestionsSessionInvalidated() remote exception:" + e);
+            Log.w(TAG, "onInlineSuggestionsSessionInvalidated() remote exception", e);
         }
         if (mResponseCallback != null) {
             consumeInlineSuggestionsResponse(EMPTY_RESPONSE);
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index ce6c0ff..d2fc1d3 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -32,6 +32,7 @@
     @UnsupportedAppUsage
     void releaseWakeLock(IBinder lock, int flags);
     void updateWakeLockUids(IBinder lock, in int[] uids);
+    oneway void powerHint(int hintId, int data);
     oneway void setPowerBoost(int boost, int durationMs);
     oneway void setPowerMode(int mode, boolean enabled);
 
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index e30a409..653a559 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -196,6 +196,12 @@
     public abstract void uidIdle(int uid);
 
     /**
+     * The hintId sent through this method should be in-line with the
+     * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h
+     */
+    public abstract void powerHint(int hintId, int data);
+
+    /**
      * Boost: It is sent when user interacting with the device, for example,
      * touchscreen events are incoming.
      * Defined in hardware/interfaces/power/aidl/android/hardware/power/Boost.aidl
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 0863a81..683c747 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -19,12 +19,12 @@
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.icu.text.DateTimePatternGenerator;
 import android.provider.Settings;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.SpannedString;
 
-import libcore.icu.ICU;
 import libcore.icu.LocaleData;
 
 import java.text.SimpleDateFormat;
@@ -251,7 +251,8 @@
      * @return a string pattern suitable for use with {@link java.text.SimpleDateFormat}.
      */
     public static String getBestDateTimePattern(Locale locale, String skeleton) {
-        return ICU.getBestDateTimePattern(skeleton, locale);
+        DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale);
+        return dtpg.getBestPattern(skeleton);
     }
 
     /**
@@ -333,7 +334,52 @@
      * order returned here.
      */
     public static char[] getDateFormatOrder(Context context) {
-        return ICU.getDateFormatOrder(getDateFormatString(context));
+        return getDateFormatOrder(getDateFormatString(context));
+    }
+
+    /**
+     * @hide Used by internal framework class {@link android.widget.DatePickerSpinnerDelegate}.
+     */
+    public static char[] getDateFormatOrder(String pattern) {
+        char[] result = new char[3];
+        int resultIndex = 0;
+        boolean sawDay = false;
+        boolean sawMonth = false;
+        boolean sawYear = false;
+
+        for (int i = 0; i < pattern.length(); ++i) {
+            char ch = pattern.charAt(i);
+            if (ch == 'd' || ch == 'L' || ch == 'M' || ch == 'y') {
+                if (ch == 'd' && !sawDay) {
+                    result[resultIndex++] = 'd';
+                    sawDay = true;
+                } else if ((ch == 'L' || ch == 'M') && !sawMonth) {
+                    result[resultIndex++] = 'M';
+                    sawMonth = true;
+                } else if ((ch == 'y') && !sawYear) {
+                    result[resultIndex++] = 'y';
+                    sawYear = true;
+                }
+            } else if (ch == 'G') {
+                // Ignore the era specifier, if present.
+            } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
+                throw new IllegalArgumentException("Bad pattern character '" + ch + "' in "
+                    + pattern);
+            } else if (ch == '\'') {
+                if (i < pattern.length() - 1 && pattern.charAt(i + 1) == '\'') {
+                    ++i;
+                } else {
+                    i = pattern.indexOf('\'', i + 1);
+                    if (i == -1) {
+                        throw new IllegalArgumentException("Bad quoting in " + pattern);
+                    }
+                    ++i;
+                }
+            } else {
+                // Ignore spaces and punctuation.
+            }
+        }
+        return result;
     }
 
     private static String getDateFormatString(Context context) {
diff --git a/core/java/android/text/format/DateTimeFormat.java b/core/java/android/text/format/DateTimeFormat.java
new file mode 100644
index 0000000..064d717
--- /dev/null
+++ b/core/java/android/text/format/DateTimeFormat.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import android.icu.text.DateFormat;
+import android.icu.text.DateTimePatternGenerator;
+import android.icu.text.DisplayContext;
+import android.icu.text.SimpleDateFormat;
+import android.icu.util.Calendar;
+import android.icu.util.ULocale;
+import android.util.LruCache;
+
+/**
+ * A formatter that outputs a single date/time.
+ *
+ * @hide
+ */
+class DateTimeFormat {
+    private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
+
+    static class FormatterCache extends LruCache<String, DateFormat> {
+        FormatterCache() {
+            super(8);
+        }
+    }
+
+    private DateTimeFormat() {
+    }
+
+    public static String format(ULocale icuLocale, Calendar time, int flags,
+            DisplayContext displayContext) {
+        String skeleton = DateUtilsBridge.toSkeleton(time, flags);
+        String key = skeleton + "\t" + icuLocale + "\t" + time.getTimeZone();
+        synchronized (CACHED_FORMATTERS) {
+            DateFormat formatter = CACHED_FORMATTERS.get(key);
+            if (formatter == null) {
+                DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(
+                        icuLocale);
+                formatter = new SimpleDateFormat(generator.getBestPattern(skeleton), icuLocale);
+                CACHED_FORMATTERS.put(key, formatter);
+            }
+            formatter.setContext(displayContext);
+            return formatter.format(time);
+        }
+    }
+}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index ce676e0..51bea77 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -29,7 +29,6 @@
 
 import libcore.icu.DateIntervalFormat;
 import libcore.icu.LocaleData;
-import libcore.icu.RelativeDateTimeFormatter;
 
 import java.io.IOException;
 import java.time.Instant;
diff --git a/core/java/android/text/format/DateUtilsBridge.java b/core/java/android/text/format/DateUtilsBridge.java
new file mode 100644
index 0000000..370d999
--- /dev/null
+++ b/core/java/android/text/format/DateUtilsBridge.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.TimeZone;
+import android.icu.util.ULocale;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Common methods and constants for the various ICU formatters used to support {@link
+ * android.text.format.DateUtils}.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = PACKAGE)
+public final class DateUtilsBridge {
+    // These are all public API in DateUtils. There are others, but they're either for use with
+    // other methods (like FORMAT_ABBREV_RELATIVE), don't internationalize (like FORMAT_CAP_AMPM),
+    // or have never been implemented anyway.
+    public static final int FORMAT_SHOW_TIME = 0x00001;
+    public static final int FORMAT_SHOW_WEEKDAY = 0x00002;
+    public static final int FORMAT_SHOW_YEAR = 0x00004;
+    public static final int FORMAT_NO_YEAR = 0x00008;
+    public static final int FORMAT_SHOW_DATE = 0x00010;
+    public static final int FORMAT_NO_MONTH_DAY = 0x00020;
+    public static final int FORMAT_12HOUR = 0x00040;
+    public static final int FORMAT_24HOUR = 0x00080;
+    public static final int FORMAT_UTC = 0x02000;
+    public static final int FORMAT_ABBREV_TIME = 0x04000;
+    public static final int FORMAT_ABBREV_WEEKDAY = 0x08000;
+    public static final int FORMAT_ABBREV_MONTH = 0x10000;
+    public static final int FORMAT_NUMERIC_DATE = 0x20000;
+    public static final int FORMAT_ABBREV_RELATIVE = 0x40000;
+    public static final int FORMAT_ABBREV_ALL = 0x80000;
+
+    /**
+     * Creates an immutable ICU timezone backed by the specified libcore timezone data. At the time
+     * of writing the libcore implementation is faster but restricted to 1902 - 2038. Callers must
+     * not modify the {@code tz} after calling this method.
+     */
+    public static TimeZone icuTimeZone(java.util.TimeZone tz) {
+        TimeZone icuTimeZone = TimeZone.getTimeZone(tz.getID());
+        icuTimeZone.freeze(); // Optimization - allows the timezone to be copied cheaply.
+        return icuTimeZone;
+    }
+
+    /**
+     * Create a GregorianCalendar based on the arguments
+     */
+    public static Calendar createIcuCalendar(TimeZone icuTimeZone, ULocale icuLocale,
+            long timeInMillis) {
+        Calendar calendar = new GregorianCalendar(icuTimeZone, icuLocale);
+        calendar.setTimeInMillis(timeInMillis);
+        return calendar;
+    }
+
+    public static String toSkeleton(Calendar calendar, int flags) {
+        return toSkeleton(calendar, calendar, flags);
+    }
+
+    public static String toSkeleton(Calendar startCalendar, Calendar endCalendar, int flags) {
+        if ((flags & FORMAT_ABBREV_ALL) != 0) {
+            flags |= FORMAT_ABBREV_MONTH | FORMAT_ABBREV_TIME | FORMAT_ABBREV_WEEKDAY;
+        }
+
+        String monthPart = "MMMM";
+        if ((flags & FORMAT_NUMERIC_DATE) != 0) {
+            monthPart = "M";
+        } else if ((flags & FORMAT_ABBREV_MONTH) != 0) {
+            monthPart = "MMM";
+        }
+
+        String weekPart = "EEEE";
+        if ((flags & FORMAT_ABBREV_WEEKDAY) != 0) {
+            weekPart = "EEE";
+        }
+
+        String timePart = "j"; // "j" means choose 12 or 24 hour based on current locale.
+        if ((flags & FORMAT_24HOUR) != 0) {
+            timePart = "H";
+        } else if ((flags & FORMAT_12HOUR) != 0) {
+            timePart = "h";
+        }
+
+        // If we've not been asked to abbreviate times, or we're using the 24-hour clock (where it
+        // never makes sense to leave out the minutes), include minutes. This gets us times like
+        // "4 PM" while avoiding times like "16" (for "16:00").
+        if ((flags & FORMAT_ABBREV_TIME) == 0 || (flags & FORMAT_24HOUR) != 0) {
+            timePart += "m";
+        } else {
+            // Otherwise, we're abbreviating a 12-hour time, and should only show the minutes
+            // if they're not both "00".
+            if (!(onTheHour(startCalendar) && onTheHour(endCalendar))) {
+                timePart = timePart + "m";
+            }
+        }
+
+        if (fallOnDifferentDates(startCalendar, endCalendar)) {
+            flags |= FORMAT_SHOW_DATE;
+        }
+
+        if (fallInSameMonth(startCalendar, endCalendar) && (flags & FORMAT_NO_MONTH_DAY) != 0) {
+            flags &= (~FORMAT_SHOW_WEEKDAY);
+            flags &= (~FORMAT_SHOW_TIME);
+        }
+
+        if ((flags & (FORMAT_SHOW_DATE | FORMAT_SHOW_TIME | FORMAT_SHOW_WEEKDAY)) == 0) {
+            flags |= FORMAT_SHOW_DATE;
+        }
+
+        // If we've been asked to show the date, work out whether we think we should show the year.
+        if ((flags & FORMAT_SHOW_DATE) != 0) {
+            if ((flags & FORMAT_SHOW_YEAR) != 0) {
+                // The caller explicitly wants us to show the year.
+            } else if ((flags & FORMAT_NO_YEAR) != 0) {
+                // The caller explicitly doesn't want us to show the year, even if we otherwise
+                // would.
+            } else if (!fallInSameYear(startCalendar, endCalendar) || !isThisYear(startCalendar)) {
+                flags |= FORMAT_SHOW_YEAR;
+            }
+        }
+
+        StringBuilder builder = new StringBuilder();
+        if ((flags & (FORMAT_SHOW_DATE | FORMAT_NO_MONTH_DAY)) != 0) {
+            if ((flags & FORMAT_SHOW_YEAR) != 0) {
+                builder.append("y");
+            }
+            builder.append(monthPart);
+            if ((flags & FORMAT_NO_MONTH_DAY) == 0) {
+                builder.append("d");
+            }
+        }
+        if ((flags & FORMAT_SHOW_WEEKDAY) != 0) {
+            builder.append(weekPart);
+        }
+        if ((flags & FORMAT_SHOW_TIME) != 0) {
+            builder.append(timePart);
+        }
+        return builder.toString();
+    }
+
+    public static int dayDistance(Calendar c1, Calendar c2) {
+        return c2.get(Calendar.JULIAN_DAY) - c1.get(Calendar.JULIAN_DAY);
+    }
+
+    /**
+     * Returns whether the argument will be displayed as if it were midnight, using any of the
+     * skeletons provided by {@link #toSkeleton}.
+     */
+    public static boolean isDisplayMidnightUsingSkeleton(Calendar c) {
+        // All the skeletons returned by toSkeleton have minute precision (they may abbreviate
+        // 4:00 PM to 4 PM but will still show the following minute as 4:01 PM).
+        return c.get(Calendar.HOUR_OF_DAY) == 0 && c.get(Calendar.MINUTE) == 0;
+    }
+
+    private static boolean onTheHour(Calendar c) {
+        return c.get(Calendar.MINUTE) == 0 && c.get(Calendar.SECOND) == 0;
+    }
+
+    private static boolean fallOnDifferentDates(Calendar c1, Calendar c2) {
+        return c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR)
+                || c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH)
+                || c1.get(Calendar.DAY_OF_MONTH) != c2.get(Calendar.DAY_OF_MONTH);
+    }
+
+    private static boolean fallInSameMonth(Calendar c1, Calendar c2) {
+        return c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH);
+    }
+
+    private static boolean fallInSameYear(Calendar c1, Calendar c2) {
+        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR);
+    }
+
+    private static boolean isThisYear(Calendar c) {
+        Calendar now = (Calendar) c.clone();
+        now.setTimeInMillis(System.currentTimeMillis());
+        return c.get(Calendar.YEAR) == now.get(Calendar.YEAR);
+    }
+}
diff --git a/core/java/android/text/format/RelativeDateTimeFormatter.java b/core/java/android/text/format/RelativeDateTimeFormatter.java
new file mode 100644
index 0000000..c5bca17
--- /dev/null
+++ b/core/java/android/text/format/RelativeDateTimeFormatter.java
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import static android.text.format.DateUtilsBridge.FORMAT_ABBREV_ALL;
+import static android.text.format.DateUtilsBridge.FORMAT_ABBREV_MONTH;
+import static android.text.format.DateUtilsBridge.FORMAT_ABBREV_RELATIVE;
+import static android.text.format.DateUtilsBridge.FORMAT_NO_YEAR;
+import static android.text.format.DateUtilsBridge.FORMAT_NUMERIC_DATE;
+import static android.text.format.DateUtilsBridge.FORMAT_SHOW_DATE;
+import static android.text.format.DateUtilsBridge.FORMAT_SHOW_TIME;
+import static android.text.format.DateUtilsBridge.FORMAT_SHOW_YEAR;
+
+import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
+
+import android.icu.text.DisplayContext;
+import android.icu.util.Calendar;
+import android.icu.util.ULocale;
+import android.util.LruCache;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Locale;
+
+/**
+ * Exposes icu4j's RelativeDateTimeFormatter.
+ *
+ * @hide
+ */
+@VisibleForTesting(visibility = PACKAGE)
+public final class RelativeDateTimeFormatter {
+
+    public static final long SECOND_IN_MILLIS = 1000;
+    public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
+    public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
+    public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
+    public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
+    // YEAR_IN_MILLIS considers 364 days as a year. However, since this
+    // constant comes from public API in DateUtils, it cannot be fixed here.
+    public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
+
+    private static final int DAY_IN_MS = 24 * 60 * 60 * 1000;
+    private static final int EPOCH_JULIAN_DAY = 2440588;
+
+    private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
+
+    static class FormatterCache
+            extends LruCache<String, android.icu.text.RelativeDateTimeFormatter> {
+        FormatterCache() {
+            super(8);
+        }
+    }
+
+    private RelativeDateTimeFormatter() {
+    }
+
+    /**
+     * This is the internal API that implements the functionality of DateUtils
+     * .getRelativeTimeSpanString(long,
+     * long, long, int), which is to return a string describing 'time' as a time relative to 'now'
+     * such as '5 minutes ago', or 'In 2 days'. More examples can be found in DateUtils' doc.
+     * <p>
+     * In the implementation below, it selects the appropriate time unit based on the elapsed time
+     * between time' and 'now', e.g. minutes, days and etc. Callers may also specify the desired
+     * minimum resolution to show in the result. For example, '45 minutes ago' will become '0 hours
+     * ago' when minResolution is HOUR_IN_MILLIS. Once getting the quantity and unit to display, it
+     * calls icu4j's RelativeDateTimeFormatter to format the actual string according to the given
+     * locale.
+     * <p>
+     * Note that when minResolution is set to DAY_IN_MILLIS, it returns the result depending on the
+     * actual date difference. For example, it will return 'Yesterday' even if 'time' was less than
+     * 24 hours ago but falling onto a different calendar day.
+     * <p>
+     * It takes two additional parameters of Locale and TimeZone than the DateUtils' API. Caller
+     * must specify the locale and timezone. FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set
+     * in 'flags' to get the abbreviated forms when available. When 'time' equals to 'now', it
+     * always // returns a string like '0 seconds/minutes/... ago' according to minResolution.
+     */
+    public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time,
+            long now, long minResolution, int flags) {
+        // Android has been inconsistent about capitalization in the past. e.g. bug
+        // http://b/20247811.
+        // Now we capitalize everything consistently.
+        final DisplayContext displayContext =
+                DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE;
+        return getRelativeTimeSpanString(locale, tz, time, now, minResolution, flags,
+                displayContext);
+    }
+
+    public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time,
+            long now, long minResolution, int flags, DisplayContext displayContext) {
+        if (locale == null) {
+            throw new NullPointerException("locale == null");
+        }
+        if (tz == null) {
+            throw new NullPointerException("tz == null");
+        }
+        ULocale icuLocale = ULocale.forLocale(locale);
+        android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
+        return getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution, flags,
+                displayContext);
+    }
+
+    private static String getRelativeTimeSpanString(ULocale icuLocale,
+            android.icu.util.TimeZone icuTimeZone, long time, long now, long minResolution,
+            int flags,
+            DisplayContext displayContext) {
+
+        long duration = Math.abs(now - time);
+        boolean past = (now >= time);
+
+        android.icu.text.RelativeDateTimeFormatter.Style style;
+        if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) {
+            style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT;
+        } else {
+            style = android.icu.text.RelativeDateTimeFormatter.Style.LONG;
+        }
+
+        android.icu.text.RelativeDateTimeFormatter.Direction direction;
+        if (past) {
+            direction = android.icu.text.RelativeDateTimeFormatter.Direction.LAST;
+        } else {
+            direction = android.icu.text.RelativeDateTimeFormatter.Direction.NEXT;
+        }
+
+        // 'relative' defaults to true as we are generating relative time span
+        // string. It will be set to false when we try to display strings without
+        // a quantity, such as 'Yesterday', etc.
+        boolean relative = true;
+        int count;
+        android.icu.text.RelativeDateTimeFormatter.RelativeUnit unit;
+        android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit aunit = null;
+
+        if (duration < MINUTE_IN_MILLIS && minResolution < MINUTE_IN_MILLIS) {
+            count = (int) (duration / SECOND_IN_MILLIS);
+            unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.SECONDS;
+        } else if (duration < HOUR_IN_MILLIS && minResolution < HOUR_IN_MILLIS) {
+            count = (int) (duration / MINUTE_IN_MILLIS);
+            unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.MINUTES;
+        } else if (duration < DAY_IN_MILLIS && minResolution < DAY_IN_MILLIS) {
+            // Even if 'time' actually happened yesterday, we don't format it as
+            // "Yesterday" in this case. Unless the duration is longer than a day,
+            // or minResolution is specified as DAY_IN_MILLIS by user.
+            count = (int) (duration / HOUR_IN_MILLIS);
+            unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.HOURS;
+        } else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
+            count = Math.abs(dayDistance(icuTimeZone, time, now));
+            unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.DAYS;
+
+            if (count == 2) {
+                // Some locales have special terms for "2 days ago". Return them if
+                // available. Note that we cannot set up direction and unit here and
+                // make it fall through to use the call near the end of the function,
+                // because for locales that don't have special terms for "2 days ago",
+                // icu4j returns an empty string instead of falling back to strings
+                // like "2 days ago".
+                String str;
+                if (past) {
+                    synchronized (CACHED_FORMATTERS) {
+                        str = getFormatter(icuLocale, style, displayContext).format(
+                                android.icu.text.RelativeDateTimeFormatter.Direction.LAST_2,
+                                android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
+                    }
+                } else {
+                    synchronized (CACHED_FORMATTERS) {
+                        str = getFormatter(icuLocale, style, displayContext).format(
+                                android.icu.text.RelativeDateTimeFormatter.Direction.NEXT_2,
+                                android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
+                    }
+                }
+                if (str != null && !str.isEmpty()) {
+                    return str;
+                }
+                // Fall back to show something like "2 days ago".
+            } else if (count == 1) {
+                // Show "Yesterday / Tomorrow" instead of "1 day ago / In 1 day".
+                aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY;
+                relative = false;
+            } else if (count == 0) {
+                // Show "Today" if time and now are on the same day.
+                aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY;
+                direction = android.icu.text.RelativeDateTimeFormatter.Direction.THIS;
+                relative = false;
+            }
+        } else if (minResolution == WEEK_IN_MILLIS) {
+            count = (int) (duration / WEEK_IN_MILLIS);
+            unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.WEEKS;
+        } else {
+            Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time);
+            // The duration is longer than a week and minResolution is not
+            // WEEK_IN_MILLIS. Return the absolute date instead of relative time.
+
+            // Bug 19822016:
+            // If user doesn't supply the year display flag, we need to explicitly
+            // set that to show / hide the year based on time and now. Otherwise
+            // formatDateRange() would determine that based on the current system
+            // time and may give wrong results.
+            if ((flags & (FORMAT_NO_YEAR | FORMAT_SHOW_YEAR)) == 0) {
+                Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale,
+                        now);
+
+                if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
+                    flags |= FORMAT_SHOW_YEAR;
+                } else {
+                    flags |= FORMAT_NO_YEAR;
+                }
+            }
+            return DateTimeFormat.format(icuLocale, timeCalendar, flags, displayContext);
+        }
+
+        synchronized (CACHED_FORMATTERS) {
+            android.icu.text.RelativeDateTimeFormatter formatter =
+                    getFormatter(icuLocale, style, displayContext);
+            if (relative) {
+                return formatter.format(count, direction, unit);
+            } else {
+                return formatter.format(direction, aunit);
+            }
+        }
+    }
+
+    /**
+     * This is the internal API that implements DateUtils.getRelativeDateTimeString(long, long,
+     * long, long, int), which is to return a string describing 'time' as a time relative to 'now',
+     * formatted like '[relative time/date], [time]'. More examples can be found in DateUtils' doc.
+     * <p>
+     * The function is similar to getRelativeTimeSpanString, but it always appends the absolute time
+     * to the relative time string to return '[relative time/date clause], [absolute time clause]'.
+     * It also takes an extra parameter transitionResolution to determine the format of the date
+     * clause. When the elapsed time is less than the transition resolution, it displays the
+     * relative time string. Otherwise, it gives the absolute numeric date string as the date
+     * clause. With the date and time clauses, it relies on icu4j's
+     * RelativeDateTimeFormatter::combineDateAndTime()
+     * to concatenate the two.
+     * <p>
+     * It takes two additional parameters of Locale and TimeZone than the DateUtils' API. Caller
+     * must specify the locale and timezone. FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set
+     * in 'flags' to get the abbreviated forms when they are available.
+     * <p>
+     * Bug 5252772: Since the absolute time will always be part of the result, minResolution will be
+     * set to at least DAY_IN_MILLIS to correctly indicate the date difference. For example, when
+     * it's 1:30 AM, it will return 'Yesterday, 11:30 PM' for getRelativeDateTimeString(null, null,
+     * now - 2 hours, now, HOUR_IN_MILLIS, DAY_IN_MILLIS, 0), instead of '2 hours ago, 11:30 PM'
+     * even with minResolution being HOUR_IN_MILLIS.
+     */
+    public static String getRelativeDateTimeString(Locale locale, java.util.TimeZone tz, long time,
+            long now, long minResolution, long transitionResolution, int flags) {
+
+        if (locale == null) {
+            throw new NullPointerException("locale == null");
+        }
+        if (tz == null) {
+            throw new NullPointerException("tz == null");
+        }
+        ULocale icuLocale = ULocale.forLocale(locale);
+        android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
+
+        long duration = Math.abs(now - time);
+        // It doesn't make much sense to have results like: "1 week ago, 10:50 AM".
+        if (transitionResolution > WEEK_IN_MILLIS) {
+            transitionResolution = WEEK_IN_MILLIS;
+        }
+        android.icu.text.RelativeDateTimeFormatter.Style style;
+        if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) {
+            style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT;
+        } else {
+            style = android.icu.text.RelativeDateTimeFormatter.Style.LONG;
+        }
+
+        Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time);
+        Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, now);
+
+        int days = Math.abs(DateUtilsBridge.dayDistance(timeCalendar, nowCalendar));
+
+        // Now get the date clause, either in relative format or the actual date.
+        String dateClause;
+        if (duration < transitionResolution) {
+            // This is to fix bug 5252772. If there is any date difference, we should
+            // promote the minResolution to DAY_IN_MILLIS so that it can display the
+            // date instead of "x hours/minutes ago, [time]".
+            if (days > 0 && minResolution < DAY_IN_MILLIS) {
+                minResolution = DAY_IN_MILLIS;
+            }
+            dateClause = getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution,
+                    flags, DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE);
+        } else {
+            // We always use fixed flags to format the date clause. User-supplied
+            // flags are ignored.
+            if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
+                // Different years
+                flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
+            } else {
+                // Default
+                flags = FORMAT_SHOW_DATE | FORMAT_NO_YEAR | FORMAT_ABBREV_MONTH;
+            }
+
+            dateClause = DateTimeFormat.format(icuLocale, timeCalendar, flags,
+                    DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE);
+        }
+
+        String timeClause = DateTimeFormat.format(icuLocale, timeCalendar, FORMAT_SHOW_TIME,
+                DisplayContext.CAPITALIZATION_NONE);
+
+        // icu4j also has other options available to control the capitalization. We are currently
+        // using
+        // the _NONE option only.
+        DisplayContext capitalizationContext = DisplayContext.CAPITALIZATION_NONE;
+
+        // Combine the two clauses, such as '5 days ago, 10:50 AM'.
+        synchronized (CACHED_FORMATTERS) {
+            return getFormatter(icuLocale, style, capitalizationContext)
+                    .combineDateAndTime(dateClause, timeClause);
+        }
+    }
+
+    /**
+     * getFormatter() caches the RelativeDateTimeFormatter instances based on the combination of
+     * localeName, sytle and capitalizationContext. It should always be used along with the action
+     * of the formatter in a synchronized block, because otherwise the formatter returned by
+     * getFormatter() may have been evicted by the time of the call to formatter->action().
+     */
+    private static android.icu.text.RelativeDateTimeFormatter getFormatter(
+            ULocale locale, android.icu.text.RelativeDateTimeFormatter.Style style,
+            DisplayContext displayContext) {
+        String key = locale + "\t" + style + "\t" + displayContext;
+        android.icu.text.RelativeDateTimeFormatter formatter = CACHED_FORMATTERS.get(key);
+        if (formatter == null) {
+            formatter = android.icu.text.RelativeDateTimeFormatter.getInstance(
+                    locale, null, style, displayContext);
+            CACHED_FORMATTERS.put(key, formatter);
+        }
+        return formatter;
+    }
+
+    // Return the date difference for the two times in a given timezone.
+    private static int dayDistance(android.icu.util.TimeZone icuTimeZone, long startTime,
+            long endTime) {
+        return julianDay(icuTimeZone, endTime) - julianDay(icuTimeZone, startTime);
+    }
+
+    private static int julianDay(android.icu.util.TimeZone icuTimeZone, long time) {
+        long utcMs = time + icuTimeZone.getOffset(time);
+        return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
+    }
+}
diff --git a/core/java/android/view/ImeFocusController.java b/core/java/android/view/ImeFocusController.java
index 825077ff..ad43f95 100644
--- a/core/java/android/view/ImeFocusController.java
+++ b/core/java/android/view/ImeFocusController.java
@@ -125,11 +125,11 @@
         final View viewForWindowFocus = focusedView != null ? focusedView : mViewRootImpl.mView;
         onViewFocusChanged(viewForWindowFocus, true);
 
-        // Skip starting input when the next focused view is same as served view and the served
-        // input connection still exists.
+        // Starting new input when the next focused view is same as served view but the
+        // editor is not aligned with the same editor or editor is inactive.
         final boolean nextFocusIsServedView = mServedView != null && mServedView == focusedView;
-        if (nextFocusIsServedView && immDelegate.isAcceptingText()) {
-            forceFocus = false;
+        if (nextFocusIsServedView && !immDelegate.isSameEditorAndAcceptingText(focusedView)) {
+            forceFocus = true;
         }
 
         immDelegate.startInputAsyncOnWindowFocusGain(viewForWindowFocus,
@@ -254,7 +254,7 @@
         void setCurrentRootView(ViewRootImpl rootView);
         boolean isCurrentRootView(ViewRootImpl rootView);
         boolean isRestartOnNextWindowFocus(boolean reset);
-        boolean isAcceptingText();
+        boolean isSameEditorAndAcceptingText(View view);
     }
 
     public View getServedView() {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c6be91f..a679b37 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -737,7 +737,7 @@
             }
         }
 
-        final boolean hasControl = mTmpControlArray.size() > 0;
+        boolean requestedStateStale = false;
         final int[] showTypes = new int[1];
         final int[] hideTypes = new int[1];
 
@@ -754,9 +754,26 @@
         // Ensure to create source consumers if not available yet.
         for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
             final InsetsSourceControl control = mTmpControlArray.valueAt(i);
-            InsetsSourceConsumer consumer = getSourceConsumer(control.getType());
+            final @InternalInsetsType int type = control.getType();
+            final InsetsSourceConsumer consumer = getSourceConsumer(type);
             consumer.setControl(control, showTypes, hideTypes);
 
+            if (!requestedStateStale) {
+                final boolean requestedVisible = consumer.isRequestedVisible();
+
+                // We might have changed our requested visibilities while we don't have the control,
+                // so we need to update our requested state once we have control. Otherwise, our
+                // requested state at the server side might be incorrect.
+                final boolean requestedVisibilityChanged =
+                        requestedVisible != mRequestedState.getSourceOrDefaultVisibility(type);
+
+                // The IME client visibility will be reset by insets source provider while updating
+                // control, so if IME is requested visible, we need to send the request to server.
+                final boolean imeRequestedVisible = type == ITYPE_IME && requestedVisible;
+
+                requestedStateStale = requestedVisibilityChanged || imeRequestedVisible;
+            }
+
         }
         mTmpControlArray.clear();
 
@@ -772,10 +789,7 @@
         if (hideTypes[0] != 0) {
             applyAnimation(hideTypes[0], false /* show */, false /* fromIme */);
         }
-        if (hasControl && mRequestedState.hasSources()) {
-            // We might have changed our requested visibilities while we don't have the control,
-            // so we need to update our requested state once we have control. Otherwise, our
-            // requested state at the server side might be incorrect.
+        if (requestedStateStale) {
             updateRequestedState();
         }
     }
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b022d2a..f2cec25 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1816,13 +1816,19 @@
     /**
      * Called after window layout to update the bounds surface. If the surface insets have changed
      * or the surface has resized, update the bounds surface.
+     *
+     * @param shouldReparent Whether it should reparent the bounds layer to the main SurfaceControl.
      */
-    private void updateBoundsLayer() {
+    private void updateBoundsLayer(boolean shouldReparent) {
         if (mBoundsLayer != null) {
             setBoundsLayerCrop();
-            mTransaction.deferTransactionUntil(mBoundsLayer,
-                    getRenderSurfaceControl(), mSurface.getNextFrameNumber())
-                    .apply();
+            mTransaction.deferTransactionUntil(mBoundsLayer, getRenderSurfaceControl(),
+                    mSurface.getNextFrameNumber());
+
+            if (shouldReparent) {
+                mTransaction.reparent(mBoundsLayer, getRenderSurfaceControl());
+            }
+            mTransaction.apply();
         }
     }
 
@@ -2904,7 +2910,16 @@
         }
 
         if (surfaceSizeChanged || surfaceReplaced || surfaceCreated || windowAttributesChanged) {
-            updateBoundsLayer();
+            // If the surface has been replaced, there's a chance the bounds layer is not parented
+            // to the new layer. When updating bounds layer, also reparent to the main VRI
+            // SurfaceControl to ensure it's correctly placed in the hierarchy.
+            //
+            // This needs to be done on the client side since WMS won't reparent the children to the
+            // new surface if it thinks the app is closing. WMS gets the signal that the app is
+            // stopping, but on the client side it doesn't get stopped since it's restarted quick
+            // enough. WMS doesn't want to keep around old children since they will leak when the
+            // client creates new children.
+            updateBoundsLayer(surfaceReplaced);
         }
 
         final boolean didLayout = layoutRequested && (!mStopped || mReportNextDraw);
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index fa92e29c..599a7c2 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -633,20 +633,21 @@
                 // we'll just do a window focus gain and call it a day.
                 try {
                     View servedView = controller.getServedView();
-                    boolean nextFocusIsServedView = servedView != null && servedView == focusedView;
+                    boolean nextFocusSameEditor = servedView != null && servedView == focusedView
+                            && isSameEditorAndAcceptingText(focusedView);
                     if (DEBUG) {
                         Log.v(TAG, "Reporting focus gain, without startInput"
-                                + ", nextFocusIsServedView=" + nextFocusIsServedView);
+                                + ", nextFocusIsServedView=" + nextFocusSameEditor);
                     }
                     final int startInputReason =
-                            nextFocusIsServedView ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
+                            nextFocusSameEditor ? WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
                                     : WINDOW_FOCUS_GAIN_REPORT_WITHOUT_EDITOR;
                     mService.startInputOrWindowGainedFocus(
                             startInputReason, mClient,
                             focusedView.getWindowToken(), startInputFlags, softInputMode,
                             windowFlags,
-                            nextFocusIsServedView ? mCurrentTextBoxAttribute : null,
-                            nextFocusIsServedView ? mServedInputConnectionWrapper : null,
+                            null,
+                            null,
                             0 /* missingMethodFlags */,
                             mCurRootView.mContext.getApplicationInfo().targetSdkVersion);
                 } catch (RemoteException e) {
@@ -671,10 +672,6 @@
         @Override
         public void setCurrentRootView(ViewRootImpl rootView) {
             synchronized (mH) {
-                if (mCurRootView != null) {
-                    // Restart the input when the next window focus state of the root view changed.
-                    mRestartOnNextWindowFocus = true;
-                }
                 mCurRootView = rootView;
             }
         }
@@ -704,14 +701,33 @@
         }
 
         /**
-         * For {@link ImeFocusController} to check if the currently served view is accepting full
-         * text edits.
+         * For {@link ImeFocusController} to check if the given focused view aligns with the same
+         * editor and the editor is active to accept the text input.
+         *
+         * TODO(b/160968797): Remove this method and move mCurrentTextBoxAttritube to
+         *  ImeFocusController.
+         * In the long-term, we should make mCurrentTextBoxAtrtribue as per-window base instance,
+         * so that we we can directly check if the current focused view aligned with the same editor
+         * in the window without using this checking.
+         *
+         * Note that this method is only use for fixing start new input may ignored issue
+         * (e.g. b/160391516), DO NOT leverage this method to do another check.
          */
-        @Override
-        public boolean isAcceptingText() {
+        public boolean isSameEditorAndAcceptingText(View view) {
             synchronized (mH) {
-                return mServedInputConnectionWrapper != null
-                        && mServedInputConnectionWrapper.getInputConnection() != null;
+                if (!hasServedByInputMethodLocked(view) || mCurrentTextBoxAttribute == null) {
+                    return false;
+                }
+
+                final EditorInfo ic = mCurrentTextBoxAttribute;
+                // This sameEditor checking is based on using object hash comparison to check if
+                // some fields of the current EditorInfo (e.g. autoFillId, OpPackageName) the
+                // hash code is same as the given focused view.
+                final boolean sameEditor = view.onCheckIsTextEditor() && view.getId() == ic.fieldId
+                        && view.getAutofillId() == ic.autofillId
+                        && view.getContext().getOpPackageName() == ic.packageName;
+                return sameEditor && mServedInputConnectionWrapper != null
+                        && mServedInputConnectionWrapper.isActive();
             }
         }
     }
diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java
index 096e6ea..fd89b2e 100644
--- a/core/java/android/widget/DatePickerSpinnerDelegate.java
+++ b/core/java/android/widget/DatePickerSpinnerDelegate.java
@@ -34,8 +34,6 @@
 import android.widget.DatePicker.AbstractDatePickerDelegate;
 import android.widget.NumberPicker.OnValueChangeListener;
 
-import libcore.icu.ICU;
-
 import java.text.DateFormatSymbols;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -459,7 +457,7 @@
         // We use numeric spinners for year and day, but textual months. Ask icu4c what
         // order the user's locale uses for that combination. http://b/7207103.
         String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), "yyyyMMMdd");
-        char[] order = ICU.getDateFormatOrder(pattern);
+        char[] order = DateFormat.getDateFormatOrder(pattern);
         final int spinnerCount = order.length;
         for (int i = 0; i < spinnerCount; i++) {
             switch (order[i]) {
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 14cf258..fbf050a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -2640,7 +2640,10 @@
         }
         RecyclerView recyclerView = mChooserMultiProfilePagerAdapter.getActiveAdapterView();
         ChooserGridAdapter gridAdapter = mChooserMultiProfilePagerAdapter.getCurrentRootAdapter();
-        if (gridAdapter == null || recyclerView == null) {
+        // Skip height calculation if recycler view was scrolled to prevent it inaccurately
+        // calculating the height, as the logic below does not account for the scrolled offset.
+        if (gridAdapter == null || recyclerView == null
+                || recyclerView.computeVerticalScrollOffset() != 0) {
             return;
         }
 
@@ -3127,6 +3130,10 @@
         ChooserGridAdapter currentRootAdapter =
                 mChooserMultiProfilePagerAdapter.getCurrentRootAdapter();
         currentRootAdapter.updateDirectShareExpansion();
+        // This fixes an edge case where after performing a variety of gestures, vertical scrolling
+        // ends up disabled. That's because at some point the old tab's vertical scrolling is
+        // disabled and the new tab's is enabled. For context, see b/159997845
+        setVerticalScrollEnabled(true);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
index ffa6041..3a65a32 100644
--- a/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
+++ b/core/java/com/android/internal/app/ChooserMultiProfilePagerAdapter.java
@@ -252,8 +252,10 @@
 
     @Override
     protected void setupContainerPadding(View container) {
+        int initialBottomPadding = getContext().getResources().getDimensionPixelSize(
+                R.dimen.resolver_empty_state_container_padding_bottom);
         container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
-                container.getPaddingRight(), container.getPaddingBottom() + mBottomOffset);
+                container.getPaddingRight(), initialBottomPadding + mBottomOffset);
     }
 
     class ChooserProfileDescriptor extends ProfileDescriptor {
diff --git a/core/java/com/android/internal/app/ResolverListAdapter.java b/core/java/com/android/internal/app/ResolverListAdapter.java
index eef722e..c16ee42 100644
--- a/core/java/com/android/internal/app/ResolverListAdapter.java
+++ b/core/java/com/android/internal/app/ResolverListAdapter.java
@@ -833,7 +833,7 @@
         String getAppSubLabelInternal() {
             // Will default to app name if no intent filter or activity label set, make sure to
             // check if subLabel matches label before final display
-            return (String) mRi.loadLabel(mPm);
+            return mRi.loadLabel(mPm).toString();
         }
     }
 
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index cffb0ad..3d35d2f 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -153,19 +153,32 @@
     }
 
     /**
+     * Attempt to wait for suspend_control service if not immediately available.
+     */
+    private ISuspendControlService waitForSuspendControlService() throws ServiceNotFoundException {
+        final String name = "suspend_control";
+        final int numRetries = 5;
+        for (int i = 0; i < numRetries; i++) {
+            mSuspendControlService = ISuspendControlService.Stub.asInterface(
+                                        ServiceManager.getService(name));
+            if (mSuspendControlService != null) {
+                return mSuspendControlService;
+            }
+        }
+        throw new ServiceNotFoundException(name);
+    }
+
+    /**
      * On success, returns the updated stats from SystemSupend, else returns null.
      */
     private KernelWakelockStats getWakelockStatsFromSystemSuspend(
             final KernelWakelockStats staleStats) {
         WakeLockInfo[] wlStats = null;
-        if (mSuspendControlService == null) {
-            try {
-                mSuspendControlService = ISuspendControlService.Stub.asInterface(
-                    ServiceManager.getServiceOrThrow("suspend_control"));
-            } catch (ServiceNotFoundException e) {
-                Slog.wtf(TAG, "Required service suspend_control not available", e);
-                return null;
-            }
+        try {
+            mSuspendControlService = waitForSuspendControlService();
+        } catch (ServiceNotFoundException e) {
+            Slog.wtf(TAG, "Required service suspend_control not available", e);
+            return null;
         }
 
         try {
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 0c24065..7a79cc9 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -2088,10 +2088,11 @@
         pw.println(getName() + ":");
         pw.println(" total records=" + getLogRecCount());
         for (int i = 0; i < getLogRecSize(); i++) {
-            pw.println(" rec[" + i + "]: " + getLogRec(i).toString());
+            pw.println(" rec[" + i + "]: " + getLogRec(i));
             pw.flush();
         }
-        pw.println("curState=" + getCurrentState().getName());
+        final IState curState = getCurrentState();
+        pw.println("curState=" + (curState == null ? "<QUIT>" : curState.getName()));
     }
 
     @Override
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 9e2e85a..b4b58ff 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -155,9 +155,8 @@
                 "android_media_ToneGenerator.cpp",
                 "android_hardware_Camera.cpp",
                 "android_hardware_camera2_CameraMetadata.cpp",
-                "android_hardware_camera2_legacy_LegacyCameraDevice.cpp",
-                "android_hardware_camera2_legacy_PerfMeasurement.cpp",
                 "android_hardware_camera2_DngCreator.cpp",
+                "android_hardware_camera2_utils_SurfaceUtils.cpp",
                 "android_hardware_display_DisplayManagerGlobal.cpp",
                 "android_hardware_display_DisplayViewport.cpp",
                 "android_hardware_HardwareBuffer.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7b708ef..5b1196d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -73,9 +73,8 @@
 
 extern int register_android_hardware_Camera(JNIEnv *env);
 extern int register_android_hardware_camera2_CameraMetadata(JNIEnv *env);
-extern int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv *env);
-extern int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv *env);
 extern int register_android_hardware_camera2_DngCreator(JNIEnv *env);
+extern int register_android_hardware_camera2_utils_SurfaceUtils(JNIEnv* env);
 extern int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env);
 extern int register_android_hardware_HardwareBuffer(JNIEnv *env);
 extern int register_android_hardware_SensorManager(JNIEnv *env);
@@ -1526,9 +1525,8 @@
         REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
         REG_JNI(register_android_hardware_Camera),
         REG_JNI(register_android_hardware_camera2_CameraMetadata),
-        REG_JNI(register_android_hardware_camera2_legacy_LegacyCameraDevice),
-        REG_JNI(register_android_hardware_camera2_legacy_PerfMeasurement),
         REG_JNI(register_android_hardware_camera2_DngCreator),
+        REG_JNI(register_android_hardware_camera2_utils_SurfaceUtils),
         REG_JNI(register_android_hardware_display_DisplayManagerGlobal),
         REG_JNI(register_android_hardware_HardwareBuffer),
         REG_JNI(register_android_hardware_SensorManager),
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index bc69735..e47f18a 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -556,7 +556,7 @@
 
 // connect to camera service
 static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
-    jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
+    jobject weak_this, jint cameraId, jstring clientPackageName)
 {
     // Convert jstring to String16
     const char16_t *rawClientName = reinterpret_cast<const char16_t*>(
@@ -566,19 +566,8 @@
     env->ReleaseStringChars(clientPackageName,
                             reinterpret_cast<const jchar*>(rawClientName));
 
-    sp<Camera> camera;
-    if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
-        // Default path: hal version is don't care, do normal camera connect.
-        camera = Camera::connect(cameraId, clientName,
-                Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
-    } else {
-        jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
-                Camera::USE_CALLING_UID, camera);
-        if (status != NO_ERROR) {
-            return status;
-        }
-    }
-
+    sp<Camera> camera =
+            Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
     if (camera == NULL) {
         return -EACCES;
     }
@@ -1068,7 +1057,7 @@
     "(ILandroid/hardware/Camera$CameraInfo;)V",
     (void*)android_hardware_Camera_getCameraInfo },
   { "native_setup",
-    "(Ljava/lang/Object;IILjava/lang/String;)I",
+    "(Ljava/lang/Object;ILjava/lang/String;)I",
     (void*)android_hardware_Camera_native_setup },
   { "native_release",
     "()V",
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
deleted file mode 100644
index 8cf1d2c..0000000
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Legacy-CameraDevice-JNI"
-// #define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Trace.h>
-#include <camera/CameraUtils.h>
-
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-#include "android_runtime/android_view_Surface.h"
-#include "android_runtime/android_graphics_SurfaceTexture.h"
-
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
-#include <hardware/camera3.h>
-#include <surfacetexture/SurfaceTexture.h>
-#include <system/camera_metadata.h>
-#include <system/window.h>
-#include <ui/GraphicBuffer.h>
-
-#include <stdint.h>
-#include <inttypes.h>
-
-using namespace android;
-
-// fully-qualified class name
-#define CAMERA_DEVICE_CLASS_NAME "android/hardware/camera2/legacy/LegacyCameraDevice"
-#define CAMERA_DEVICE_BUFFER_SLACK  3
-#define DONT_CARE 0
-
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a)))
-
-#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
-
-// Use BAD_VALUE for surface abandoned error
-#define OVERRIDE_SURFACE_ERROR(err) \
-do {                                \
-    if (err == -ENODEV) {           \
-        err = BAD_VALUE;            \
-    }                               \
-} while (0)
-
-#define UPDATE(md, tag, data, size)               \
-do {                                              \
-    if ((md).update((tag), (data), (size))) {     \
-        ALOGE("Update " #tag " failed!");         \
-        return BAD_VALUE;                         \
-    }                                             \
-} while (0)
-
-/**
- * Convert from RGB 888 to Y'CbCr using the conversion specified in JFIF v1.02
- */
-static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, uint8_t* yPlane,
-        uint8_t* crPlane, uint8_t* cbPlane, size_t chromaStep, size_t yStride, size_t chromaStride) {
-    uint8_t R, G, B;
-    size_t index = 0;
-    for (size_t j = 0; j < height; j++) {
-        uint8_t* cr = crPlane;
-        uint8_t* cb = cbPlane;
-        uint8_t* y = yPlane;
-        bool jEven = (j & 1) == 0;
-        for (size_t i = 0; i < width; i++) {
-            R = rgbBuf[index++];
-            G = rgbBuf[index++];
-            B = rgbBuf[index++];
-            *y++ = (77 * R + 150 * G +  29 * B) >> 8;
-            if (jEven && (i & 1) == 0) {
-                *cb = (( -43 * R - 85 * G + 128 * B) >> 8) + 128;
-                *cr = (( 128 * R - 107 * G - 21 * B) >> 8) + 128;
-                cr += chromaStep;
-                cb += chromaStep;
-            }
-            // Skip alpha
-            index++;
-        }
-        yPlane += yStride;
-        if (jEven) {
-            crPlane += chromaStride;
-            cbPlane += chromaStride;
-        }
-    }
-}
-
-static void rgbToYuv420(uint8_t* rgbBuf, size_t width, size_t height, android_ycbcr* ycbcr) {
-    size_t cStep = ycbcr->chroma_step;
-    size_t cStride = ycbcr->cstride;
-    size_t yStride = ycbcr->ystride;
-    ALOGV("%s: yStride is: %zu, cStride is: %zu, cStep is: %zu", __FUNCTION__, yStride, cStride,
-            cStep);
-    rgbToYuv420(rgbBuf, width, height, reinterpret_cast<uint8_t*>(ycbcr->y),
-            reinterpret_cast<uint8_t*>(ycbcr->cr), reinterpret_cast<uint8_t*>(ycbcr->cb),
-            cStep, yStride, cStride);
-}
-
-static status_t connectSurface(const sp<Surface>& surface, int32_t maxBufferSlack) {
-    status_t err = NO_ERROR;
-
-    err = surface->connect(NATIVE_WINDOW_API_CAMERA, /*listener*/NULL);
-    if (err != OK) {
-        ALOGE("%s: Unable to connect to surface, error %s (%d).", __FUNCTION__,
-                strerror(-err), err);
-        return err;
-    }
-
-    err = native_window_set_usage(surface.get(), GRALLOC_USAGE_SW_WRITE_OFTEN);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to set native window usage flag, error %s (%d).", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    int minUndequeuedBuffers;
-    err = static_cast<ANativeWindow*>(surface.get())->query(surface.get(),
-            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to get native window min undequeued buffers, error %s (%d).",
-                __FUNCTION__, strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    ALOGV("%s: Setting buffer count to %d", __FUNCTION__,
-            maxBufferSlack + 1 + minUndequeuedBuffers);
-    err = native_window_set_buffer_count(surface.get(), maxBufferSlack + 1 + minUndequeuedBuffers);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to set native window buffer count, error %s (%d).", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-/**
- * Produce a frame in the given surface.
- *
- * Args:
- *    anw - a surface to produce a frame in.
- *    pixelBuffer - image buffer to generate a frame from.
- *    width - width of the pixelBuffer in pixels.
- *    height - height of the pixelBuffer in pixels.
- *    pixelFmt - format of the pixelBuffer, one of:
- *               HAL_PIXEL_FORMAT_YCrCb_420_SP,
- *               HAL_PIXEL_FORMAT_YCbCr_420_888,
- *               HAL_PIXEL_FORMAT_BLOB
- *    bufSize - the size of the pixelBuffer in bytes.
- */
-static status_t produceFrame(const sp<ANativeWindow>& anw,
-                             uint8_t* pixelBuffer,
-                             int32_t bufWidth, // Width of the pixelBuffer
-                             int32_t bufHeight, // Height of the pixelBuffer
-                             int32_t pixelFmt, // Format of the pixelBuffer
-                             int32_t bufSize) {
-    ATRACE_CALL();
-    status_t err = NO_ERROR;
-    ANativeWindowBuffer* anb;
-    ALOGV("%s: Dequeue buffer from %p %dx%d (fmt=%x, size=%x)",
-            __FUNCTION__, anw.get(), bufWidth, bufHeight, pixelFmt, bufSize);
-
-    if (anw == 0) {
-        ALOGE("%s: anw must not be NULL", __FUNCTION__);
-        return BAD_VALUE;
-    } else if (pixelBuffer == NULL) {
-        ALOGE("%s: pixelBuffer must not be NULL", __FUNCTION__);
-        return BAD_VALUE;
-    } else if (bufWidth < 0) {
-        ALOGE("%s: width must be non-negative", __FUNCTION__);
-        return BAD_VALUE;
-    } else if (bufHeight < 0) {
-        ALOGE("%s: height must be non-negative", __FUNCTION__);
-        return BAD_VALUE;
-    } else if (bufSize < 0) {
-        ALOGE("%s: bufSize must be non-negative", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    size_t width = static_cast<size_t>(bufWidth);
-    size_t height = static_cast<size_t>(bufHeight);
-    size_t bufferLength = static_cast<size_t>(bufSize);
-
-    // TODO: Switch to using Surface::lock and Surface::unlockAndPost
-    err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to dequeue buffer, error %s (%d).", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
-    uint32_t grallocBufWidth = buf->getWidth();
-    uint32_t grallocBufHeight = buf->getHeight();
-    uint32_t grallocBufStride = buf->getStride();
-    if (grallocBufWidth != width || grallocBufHeight != height) {
-        ALOGE("%s: Received gralloc buffer with bad dimensions %" PRIu32 "x%" PRIu32
-                ", expecting dimensions %zu x %zu",  __FUNCTION__, grallocBufWidth,
-                grallocBufHeight, width, height);
-        return BAD_VALUE;
-    }
-
-    int32_t bufFmt = 0;
-    err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &bufFmt);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    uint64_t tmpSize = (pixelFmt == HAL_PIXEL_FORMAT_BLOB) ? grallocBufWidth :
-            4 * grallocBufHeight * grallocBufWidth;
-    if (bufFmt != pixelFmt) {
-        if (bufFmt == HAL_PIXEL_FORMAT_RGBA_8888 && pixelFmt == HAL_PIXEL_FORMAT_BLOB) {
-            ALOGV("%s: Using BLOB to RGBA format override.", __FUNCTION__);
-            tmpSize = 4 * (grallocBufWidth + grallocBufStride * (grallocBufHeight - 1));
-        } else {
-            ALOGW("%s: Format mismatch in produceFrame: expecting format %#" PRIx32
-                    ", but received buffer with format %#" PRIx32, __FUNCTION__, pixelFmt, bufFmt);
-        }
-    }
-
-    if (tmpSize > SIZE_MAX) {
-        ALOGE("%s: Overflow calculating size, buffer with dimens %zu x %zu is absurdly large...",
-                __FUNCTION__, width, height);
-        return BAD_VALUE;
-    }
-
-    size_t totalSizeBytes = tmpSize;
-
-    ALOGV("%s: Pixel format chosen: %x", __FUNCTION__, pixelFmt);
-    switch(pixelFmt) {
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
-            if (bufferLength < totalSizeBytes) {
-                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
-                        __FUNCTION__, bufferLength);
-                return BAD_VALUE;
-            }
-            uint8_t* img = NULL;
-            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
-            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-            if (err != NO_ERROR) return err;
-
-            uint8_t* yPlane = img;
-            uint8_t* uPlane = img + height * width;
-            uint8_t* vPlane = uPlane + 1;
-            size_t chromaStep = 2;
-            size_t yStride = width;
-            size_t chromaStride = width;
-
-            rgbToYuv420(pixelBuffer, width, height, yPlane,
-                    uPlane, vPlane, chromaStep, yStride, chromaStride);
-            break;
-        }
-        case HAL_PIXEL_FORMAT_YV12: {
-            if (bufferLength < totalSizeBytes) {
-                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
-                        __FUNCTION__, bufferLength);
-                return BAD_VALUE;
-            }
-
-            if ((width & 1) || (height & 1)) {
-                ALOGE("%s: Dimens %zu x %zu are not divisible by 2.", __FUNCTION__, width, height);
-                return BAD_VALUE;
-            }
-
-            uint8_t* img = NULL;
-            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
-            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-            if (err != NO_ERROR) {
-                ALOGE("%s: Error %s (%d) while locking gralloc buffer for write.", __FUNCTION__,
-                        strerror(-err), err);
-                return err;
-            }
-
-            uint32_t stride = buf->getStride();
-            ALOGV("%s: stride is: %" PRIu32, __FUNCTION__, stride);
-            LOG_ALWAYS_FATAL_IF(stride % 16, "Stride is not 16 pixel aligned %d", stride);
-
-            uint32_t cStride = ALIGN(stride / 2, 16);
-            size_t chromaStep = 1;
-
-            uint8_t* yPlane = img;
-            uint8_t* crPlane = img + static_cast<uint32_t>(height) * stride;
-            uint8_t* cbPlane = crPlane + cStride * static_cast<uint32_t>(height) / 2;
-
-            rgbToYuv420(pixelBuffer, width, height, yPlane,
-                    crPlane, cbPlane, chromaStep, stride, cStride);
-            break;
-        }
-        case HAL_PIXEL_FORMAT_YCbCr_420_888: {
-            // Software writes with YCbCr_420_888 format are unsupported
-            // by the gralloc module for now
-            if (bufferLength < totalSizeBytes) {
-                ALOGE("%s: PixelBuffer size %zu too small for given dimensions",
-                        __FUNCTION__, bufferLength);
-                return BAD_VALUE;
-            }
-            android_ycbcr ycbcr = android_ycbcr();
-            ALOGV("%s: Lock buffer from %p for write", __FUNCTION__, anw.get());
-
-            err = buf->lockYCbCr(GRALLOC_USAGE_SW_WRITE_OFTEN, &ycbcr);
-            if (err != NO_ERROR) {
-                ALOGE("%s: Failed to lock ycbcr buffer, error %s (%d).", __FUNCTION__,
-                        strerror(-err), err);
-                return err;
-            }
-            rgbToYuv420(pixelBuffer, width, height, &ycbcr);
-            break;
-        }
-        case HAL_PIXEL_FORMAT_BLOB: {
-            int8_t* img = NULL;
-            struct camera3_jpeg_blob footer = {
-                .jpeg_blob_id = CAMERA3_JPEG_BLOB_ID,
-                .jpeg_size = (uint32_t)bufferLength
-            };
-
-            size_t totalJpegSize = bufferLength + sizeof(footer);
-            totalJpegSize = (totalJpegSize + 3) & ~0x3; // round up to nearest octonibble
-
-            if (totalJpegSize > totalSizeBytes) {
-                ALOGE("%s: Pixel buffer needs size %zu, cannot fit in gralloc buffer of size %zu",
-                        __FUNCTION__, totalJpegSize, totalSizeBytes);
-                return BAD_VALUE;
-            }
-
-            err = buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img));
-            if (err != NO_ERROR) {
-                ALOGE("%s: Failed to lock buffer, error %s (%d).", __FUNCTION__, strerror(-err),
-                        err);
-                return err;
-            }
-
-            memcpy(img, pixelBuffer, bufferLength);
-            memcpy(img + totalSizeBytes - sizeof(footer), &footer, sizeof(footer));
-            break;
-        }
-        default: {
-            ALOGE("%s: Invalid pixel format in produceFrame: %x", __FUNCTION__, pixelFmt);
-            return BAD_VALUE;
-        }
-    }
-
-    ALOGV("%s: Unlock buffer from %p", __FUNCTION__, anw.get());
-    err = buf->unlock();
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to unlock buffer, error %s (%d).", __FUNCTION__, strerror(-err), err);
-        return err;
-    }
-
-    ALOGV("%s: Queue buffer to %p", __FUNCTION__, anw.get());
-    err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), /*fenceFd*/-1);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Failed to queue buffer, error %s (%d).", __FUNCTION__, strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) {
-    sp<ANativeWindow> anw;
-    if (surface) {
-        anw = android_view_Surface_getNativeWindow(env, surface);
-        if (env->ExceptionCheck()) {
-            return NULL;
-        }
-    } else {
-        jniThrowNullPointerException(env, "surface");
-        return NULL;
-    }
-    if (anw == NULL) {
-        ALOGE("%s: Surface had no valid native window.", __FUNCTION__);
-        return NULL;
-    }
-    return anw;
-}
-
-static sp<ANativeWindow> getSurfaceTextureNativeWindow(JNIEnv* env, jobject thiz) {
-    sp<IGraphicBufferProducer> producer(SurfaceTexture_getProducer(env, thiz));
-    sp<Surface> surfaceTextureClient(producer != NULL ? new Surface(producer) : NULL);
-    return surfaceTextureClient;
-}
-
-static sp<ANativeWindow> getNativeWindowFromTexture(JNIEnv* env, jobject surfaceTexture) {
-    sp<ANativeWindow> anw;
-    if (surfaceTexture) {
-        anw = getSurfaceTextureNativeWindow(env, surfaceTexture);
-        if (env->ExceptionCheck()) {
-            return NULL;
-        }
-    } else {
-        jniThrowNullPointerException(env, "surfaceTexture");
-        return NULL;
-    }
-    if (anw == NULL) {
-        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-                "SurfaceTexture had no valid native window.");
-        return NULL;
-    }
-    return anw;
-}
-
-static sp<Surface> getSurface(JNIEnv* env, jobject surface) {
-    sp<Surface> s;
-    if (surface) {
-        s = android_view_Surface_getSurface(env, surface);
-        if (env->ExceptionCheck()) {
-            return NULL;
-        }
-    } else {
-        jniThrowNullPointerException(env, "surface");
-        return NULL;
-    }
-    if (s == NULL) {
-        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
-                "Surface had no valid native Surface.");
-        return NULL;
-    }
-    return s;
-}
-
-extern "C" {
-
-static jint LegacyCameraDevice_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) {
-    ALOGV("nativeDetectSurfaceType");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    int32_t fmt = 0;
-    status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__, strerror(-err),
-                err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return fmt;
-}
-
-static jint LegacyCameraDevice_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) {
-    ALOGV("nativeDetectSurfaceDataspace");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    int32_t fmt = 0;
-    status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying surface dataspace  %s (%d).", __FUNCTION__, strerror(-err),
-                err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return fmt;
-}
-
-static jint LegacyCameraDevice_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz,
-          jobject surface, jintArray dimens) {
-    ALOGV("nativeGetSurfaceDimens");
-
-    if (dimens == NULL) {
-        ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    if (env->GetArrayLength(dimens) < 2) {
-        ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    int32_t dimenBuf[2];
-    status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err),
-                err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err),
-                err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf);
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz,
-          jobject surface) {
-    ALOGV("nativeDetectSurfaceUsageFlags");
-
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        jniThrowException(env, "java/lang/UnsupportedOperationException",
-            "Could not retrieve native window from surface.");
-        return BAD_VALUE;
-    }
-    int32_t usage = 0;
-    status_t err = anw->query(anw.get(), NATIVE_WINDOW_CONSUMER_USAGE_BITS, &usage);
-    if(err != NO_ERROR) {
-        jniThrowException(env, "java/lang/UnsupportedOperationException",
-            "Error while querying surface usage bits");
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return usage;
-}
-
-static jint LegacyCameraDevice_nativeDisconnectSurface(JNIEnv* env, jobject thiz,
-          jobject surface) {
-    ALOGV("nativeDisconnectSurface");
-    if (surface == nullptr) return NO_ERROR;
-
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGV("Buffer queue has already been abandoned.");
-        return NO_ERROR;
-    }
-
-    status_t err = native_window_api_disconnect(anw.get(), NATIVE_WINDOW_API_CAMERA);
-    if(err != NO_ERROR) {
-        jniThrowException(env, "java/lang/UnsupportedOperationException",
-            "Error while disconnecting surface");
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeDetectTextureDimens(JNIEnv* env, jobject thiz,
-        jobject surfaceTexture, jintArray dimens) {
-    ALOGV("nativeDetectTextureDimens");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindowFromTexture(env, surfaceTexture)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from SurfaceTexture.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    int32_t dimenBuf[2];
-    status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying SurfaceTexture width %s (%d)", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1);
-    if(err != NO_ERROR) {
-        ALOGE("%s: Error while querying SurfaceTexture height %s (%d)", __FUNCTION__,
-                strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-
-    env->SetIntArrayRegion(dimens, /*start*/0, /*length*/ARRAY_SIZE(dimenBuf), dimenBuf);
-    if (env->ExceptionCheck()) {
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeConnectSurface(JNIEnv* env, jobject thiz, jobject surface) {
-    ALOGV("nativeConnectSurface");
-    sp<Surface> s;
-    if ((s = getSurface(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    status_t err = connectSurface(s, CAMERA_DEVICE_BUFFER_SLACK);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Error while configuring surface %s (%d).", __FUNCTION__, strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeProduceFrame(JNIEnv* env, jobject thiz, jobject surface,
-        jbyteArray pixelBuffer, jint width, jint height, jint pixelFormat) {
-    ALOGV("nativeProduceFrame");
-    sp<ANativeWindow> anw;
-
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    if (pixelBuffer == NULL) {
-        jniThrowNullPointerException(env, "pixelBuffer");
-        return DONT_CARE;
-    }
-
-    int32_t bufSize = static_cast<int32_t>(env->GetArrayLength(pixelBuffer));
-    jbyte* pixels = env->GetByteArrayElements(pixelBuffer, /*is_copy*/NULL);
-
-    if (pixels == NULL) {
-        jniThrowNullPointerException(env, "pixels");
-        return DONT_CARE;
-    }
-
-    status_t err = produceFrame(anw, reinterpret_cast<uint8_t*>(pixels), width, height,
-            pixelFormat, bufSize);
-    env->ReleaseByteArrayElements(pixelBuffer, pixels, JNI_ABORT);
-
-    if (err != NO_ERROR) {
-        ALOGE("%s: Error while producing frame %s (%d).", __FUNCTION__, strerror(-err), err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeSetSurfaceFormat(JNIEnv* env, jobject thiz, jobject surface,
-        jint pixelFormat) {
-    ALOGV("nativeSetSurfaceType");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    status_t err = native_window_set_buffers_format(anw.get(), pixelFormat);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Error while setting surface format %s (%d).", __FUNCTION__, strerror(-err), err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeSetSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface,
-        jint width, jint height) {
-    ALOGV("nativeSetSurfaceDimens");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    // Set user dimensions only
-    // The producer dimensions are owned by GL
-    status_t err = native_window_set_buffers_user_dimensions(anw.get(), width, height);
-    if (err != NO_ERROR) {
-        ALOGE("%s: Error while setting surface user dimens %s (%d).", __FUNCTION__, strerror(-err),
-                err);
-        OVERRIDE_SURFACE_ERROR(err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jlong LegacyCameraDevice_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) {
-    ALOGV("nativeGetSurfaceId");
-    sp<Surface> s;
-    if ((s = getSurface(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__);
-        return 0;
-    }
-    sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer();
-    if (gbp == NULL) {
-        ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__);
-        return 0;
-    }
-    sp<IBinder> b = IInterface::asBinder(gbp);
-    if (b == NULL) {
-        ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__);
-        return 0;
-    }
-    /*
-     * FIXME: Use better unique ID for surfaces than native IBinder pointer.  Fix also in the camera
-     * service (CameraDeviceClient.h).
-     */
-    return reinterpret_cast<jlong>(b.get());
-}
-
-static jint LegacyCameraDevice_nativeSetSurfaceOrientation(JNIEnv* env, jobject thiz,
-        jobject surface, jint facing, jint orientation) {
-    ALOGV("nativeSetSurfaceOrientation");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    status_t err = NO_ERROR;
-    CameraMetadata staticMetadata;
-
-    int32_t orientVal = static_cast<int32_t>(orientation);
-    uint8_t facingVal = static_cast<uint8_t>(facing);
-    staticMetadata.update(ANDROID_SENSOR_ORIENTATION, &orientVal, 1);
-    staticMetadata.update(ANDROID_LENS_FACING, &facingVal, 1);
-
-    int32_t transform = 0;
-
-    if ((err = CameraUtils::getRotationTransform(staticMetadata, /*out*/&transform)) != NO_ERROR) {
-        ALOGE("%s: Invalid rotation transform %s (%d)", __FUNCTION__, strerror(-err),
-                err);
-        return err;
-    }
-
-    ALOGV("%s: Setting buffer sticky transform to %d", __FUNCTION__, transform);
-
-    if ((err = native_window_set_buffers_sticky_transform(anw.get(), transform)) != NO_ERROR) {
-        ALOGE("%s: Unable to configure surface transform, error %s (%d)", __FUNCTION__,
-                strerror(-err), err);
-        return err;
-    }
-
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeSetNextTimestamp(JNIEnv* env, jobject thiz, jobject surface,
-        jlong timestamp) {
-    ALOGV("nativeSetNextTimestamp");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    status_t err = NO_ERROR;
-
-    if ((err = native_window_set_buffers_timestamp(anw.get(), static_cast<int64_t>(timestamp))) !=
-            NO_ERROR) {
-        ALOGE("%s: Unable to set surface timestamp, error %s (%d)", __FUNCTION__, strerror(-err),
-                err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeSetScalingMode(JNIEnv* env, jobject thiz, jobject surface,
-        jint mode) {
-    ALOGV("nativeSetScalingMode");
-    sp<ANativeWindow> anw;
-    if ((anw = getNativeWindow(env, surface)) == NULL) {
-        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
-        return BAD_VALUE;
-    }
-    status_t err = NO_ERROR;
-    if ((err = native_window_set_scaling_mode(anw.get(), static_cast<int>(mode))) != NO_ERROR) {
-        ALOGE("%s: Unable to set surface scaling mode, error %s (%d)", __FUNCTION__,
-                strerror(-err), err);
-        return err;
-    }
-    return NO_ERROR;
-}
-
-static jint LegacyCameraDevice_nativeGetJpegFooterSize(JNIEnv* env, jobject thiz) {
-    ALOGV("nativeGetJpegFooterSize");
-    return static_cast<jint>(sizeof(struct camera3_jpeg_blob));
-}
-
-} // extern "C"
-
-static const JNINativeMethod gCameraDeviceMethods[] = {
-    { "nativeDetectSurfaceType",
-    "(Landroid/view/Surface;)I",
-    (void *)LegacyCameraDevice_nativeDetectSurfaceType },
-    { "nativeDetectSurfaceDataspace",
-    "(Landroid/view/Surface;)I",
-    (void *)LegacyCameraDevice_nativeDetectSurfaceDataspace },
-    { "nativeDetectSurfaceDimens",
-    "(Landroid/view/Surface;[I)I",
-    (void *)LegacyCameraDevice_nativeDetectSurfaceDimens },
-    { "nativeConnectSurface",
-    "(Landroid/view/Surface;)I",
-    (void *)LegacyCameraDevice_nativeConnectSurface },
-    { "nativeProduceFrame",
-    "(Landroid/view/Surface;[BIII)I",
-    (void *)LegacyCameraDevice_nativeProduceFrame },
-    { "nativeSetSurfaceFormat",
-    "(Landroid/view/Surface;I)I",
-    (void *)LegacyCameraDevice_nativeSetSurfaceFormat },
-    { "nativeSetSurfaceDimens",
-    "(Landroid/view/Surface;II)I",
-    (void *)LegacyCameraDevice_nativeSetSurfaceDimens },
-    { "nativeGetSurfaceId",
-    "(Landroid/view/Surface;)J",
-    (void *)LegacyCameraDevice_nativeGetSurfaceId },
-    { "nativeDetectTextureDimens",
-    "(Landroid/graphics/SurfaceTexture;[I)I",
-    (void *)LegacyCameraDevice_nativeDetectTextureDimens },
-    { "nativeSetSurfaceOrientation",
-    "(Landroid/view/Surface;II)I",
-    (void *)LegacyCameraDevice_nativeSetSurfaceOrientation },
-    { "nativeSetNextTimestamp",
-    "(Landroid/view/Surface;J)I",
-    (void *)LegacyCameraDevice_nativeSetNextTimestamp },
-    { "nativeGetJpegFooterSize",
-    "()I",
-    (void *)LegacyCameraDevice_nativeGetJpegFooterSize },
-    { "nativeDetectSurfaceUsageFlags",
-    "(Landroid/view/Surface;)I",
-    (void *)LegacyCameraDevice_nativeDetectSurfaceUsageFlags },
-    { "nativeSetScalingMode",
-    "(Landroid/view/Surface;I)I",
-    (void *)LegacyCameraDevice_nativeSetScalingMode },
-    { "nativeDisconnectSurface",
-    "(Landroid/view/Surface;)I",
-    (void *)LegacyCameraDevice_nativeDisconnectSurface },
-};
-
-// Get all the required offsets in java class and register native functions
-int register_android_hardware_camera2_legacy_LegacyCameraDevice(JNIEnv* env)
-{
-    // Register native functions
-    return RegisterMethodsOrDie(env,
-            CAMERA_DEVICE_CLASS_NAME,
-            gCameraDeviceMethods,
-            NELEM(gCameraDeviceMethods));
-}
diff --git a/core/jni/android_hardware_camera2_legacy_PerfMeasurement.cpp b/core/jni/android_hardware_camera2_legacy_PerfMeasurement.cpp
deleted file mode 100644
index fac243a..0000000
--- a/core/jni/android_hardware_camera2_legacy_PerfMeasurement.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Camera2-Legacy-PerfMeasurement-JNI"
-#include <utils/Log.h>
-#include <utils/Errors.h>
-#include <utils/Trace.h>
-#include <utils/Vector.h>
-
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include "core_jni_helpers.h"
-
-#include <ui/GraphicBuffer.h>
-#include <system/window.h>
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-using namespace android;
-
-// fully-qualified class name
-#define PERF_MEASUREMENT_CLASS_NAME "android/hardware/camera2/legacy/PerfMeasurement"
-
-/** GL utility methods copied from com_google_android_gles_jni_GLImpl.cpp */
-
-// Check if the extension at the head of pExtensions is pExtension. Note that pExtensions is
-// terminated by either 0 or space, while pExtension is terminated by 0.
-
-static bool
-extensionEqual(const GLubyte* pExtensions, const GLubyte* pExtension) {
-    while (true) {
-        char a = *pExtensions++;
-        char b = *pExtension++;
-        bool aEnd = a == '\0' || a == ' ';
-        bool bEnd = b == '\0';
-        if (aEnd || bEnd) {
-            return aEnd == bEnd;
-        }
-        if (a != b) {
-            return false;
-        }
-    }
-}
-
-static const GLubyte*
-nextExtension(const GLubyte* pExtensions) {
-    while (true) {
-        char a = *pExtensions++;
-        if (a == '\0') {
-            return pExtensions-1;
-        } else if ( a == ' ') {
-            return pExtensions;
-        }
-    }
-}
-
-static bool
-checkForExtension(const GLubyte* pExtensions, const GLubyte* pExtension) {
-    for (; *pExtensions != '\0'; pExtensions = nextExtension(pExtensions)) {
-        if (extensionEqual(pExtensions, pExtension)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-/** End copied GL utility methods */
-
-bool checkGlError(JNIEnv* env) {
-    int error;
-    if ((error = glGetError()) != GL_NO_ERROR) {
-        jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                "GLES20 error: 0x%d", error);
-        return true;
-    }
-    return false;
-}
-
-/**
- * Asynchronous low-overhead GL performance measurement using
- * http://www.khronos.org/registry/gles/extensions/EXT/EXT_disjoint_timer_query.txt
- *
- * Measures the duration of GPU processing for a set of GL commands, delivering
- * the measurement asynchronously once processing completes.
- *
- * All calls must come from a single thread with a valid GL context active.
- **/
-class PerfMeasurementContext {
-  private:
-    Vector<GLuint> mTimingQueries;
-    size_t mTimingStartIndex;
-    size_t mTimingEndIndex;
-    size_t mTimingQueryIndex;
-    size_t mFreeQueries;
-
-    bool mInitDone;
-  public:
-
-    /**
-     * maxQueryCount should be a conservative estimate of how many query objects
-     * will be active at once, which is a function of the GPU's level of
-     * pipelining and the frequency of queries.
-     */
-    explicit PerfMeasurementContext(size_t maxQueryCount):
-            mTimingStartIndex(0),
-            mTimingEndIndex(0),
-            mTimingQueryIndex(0) {
-        mTimingQueries.resize(maxQueryCount);
-        mFreeQueries = maxQueryCount;
-        mInitDone = false;
-    }
-
-    int getMaxQueryCount() {
-        return mTimingQueries.size();
-    }
-
-    /**
-     * Start a measurement period using the next available query object.
-     * Returns INVALID_OPERATION if called multiple times in a row,
-     * and BAD_VALUE if no more query objects are available.
-     */
-    int startGlTimer() {
-        // Lazy init of queries to avoid needing GL context during construction
-        if (!mInitDone) {
-            glGenQueriesEXT(mTimingQueries.size(), mTimingQueries.editArray());
-            mInitDone = true;
-        }
-
-        if (mTimingEndIndex != mTimingStartIndex) {
-            return INVALID_OPERATION;
-        }
-
-        if (mFreeQueries == 0) {
-            return BAD_VALUE;
-        }
-
-        glBeginQueryEXT(GL_TIME_ELAPSED_EXT, mTimingQueries[mTimingStartIndex]);
-
-        mTimingStartIndex = (mTimingStartIndex + 1) % mTimingQueries.size();
-        mFreeQueries--;
-
-        return OK;
-    }
-
-    /**
-     * Finish the current measurement period
-     * Returns INVALID_OPERATION if called before any startGLTimer calls
-     * or if called multiple times in a row.
-     */
-    int stopGlTimer() {
-        size_t nextEndIndex = (mTimingEndIndex + 1) % mTimingQueries.size();
-        if (nextEndIndex != mTimingStartIndex) {
-            return INVALID_OPERATION;
-        }
-        glEndQueryEXT(GL_TIME_ELAPSED_EXT);
-
-        mTimingEndIndex = nextEndIndex;
-
-        return OK;
-    }
-
-    static const nsecs_t NO_DURATION_YET = -1L;
-    static const nsecs_t FAILED_MEASUREMENT = -2L;
-
-    /**
-     * Get the next available duration measurement.
-     *
-     * Returns NO_DURATION_YET if no new measurement is available,
-     * and FAILED_MEASUREMENT if an error occurred during the next
-     * measurement period.
-     *
-     * Otherwise returns a positive number of nanoseconds measuring the
-     * duration of the oldest completed query.
-     */
-    nsecs_t getNextGlDuration() {
-        if (!mInitDone) {
-            // No start/stop called yet
-            return NO_DURATION_YET;
-        }
-
-        GLint available;
-        glGetQueryObjectivEXT(mTimingQueries[mTimingQueryIndex],
-                GL_QUERY_RESULT_AVAILABLE_EXT, &available);
-        if (!available) {
-            return NO_DURATION_YET;
-        }
-
-        GLint64 duration = FAILED_MEASUREMENT;
-        GLint disjointOccurred;
-        glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjointOccurred);
-
-        if (!disjointOccurred) {
-            glGetQueryObjecti64vEXT(mTimingQueries[mTimingQueryIndex],
-                    GL_QUERY_RESULT_EXT,
-                    &duration);
-        }
-
-        mTimingQueryIndex = (mTimingQueryIndex + 1) % mTimingQueries.size();
-        mFreeQueries++;
-
-        return static_cast<nsecs_t>(duration);
-    }
-
-    static bool isMeasurementSupported() {
-        const GLubyte* extensions = glGetString(GL_EXTENSIONS);
-        return checkForExtension(extensions,
-                reinterpret_cast<const GLubyte*>("GL_EXT_disjoint_timer_query"));
-    }
-
-};
-
-PerfMeasurementContext* getContext(jlong context) {
-    return reinterpret_cast<PerfMeasurementContext*>(context);
-}
-
-extern "C" {
-
-static jlong PerfMeasurement_nativeCreateContext(JNIEnv* env, jobject thiz,
-        jint maxQueryCount) {
-    PerfMeasurementContext *context = new PerfMeasurementContext(maxQueryCount);
-    return reinterpret_cast<jlong>(context);
-}
-
-static void PerfMeasurement_nativeDeleteContext(JNIEnv* env, jobject thiz,
-        jlong contextHandle) {
-    PerfMeasurementContext *context = getContext(contextHandle);
-    delete(context);
-}
-
-static jboolean PerfMeasurement_nativeQuerySupport(JNIEnv* env, jobject thiz) {
-    bool supported = PerfMeasurementContext::isMeasurementSupported();
-    checkGlError(env);
-    return static_cast<jboolean>(supported);
-}
-
-static void PerfMeasurement_nativeStartGlTimer(JNIEnv* env, jobject thiz,
-        jlong contextHandle) {
-
-    PerfMeasurementContext *context = getContext(contextHandle);
-    status_t err = context->startGlTimer();
-    if (err != OK) {
-        switch (err) {
-            case INVALID_OPERATION:
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                        "Mismatched start/end GL timing calls");
-                return;
-            case BAD_VALUE:
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                        "Too many timing queries in progress, max %d",
-                        context->getMaxQueryCount());
-                return;
-            default:
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                        "Unknown error starting GL timing");
-                return;
-        }
-    }
-    checkGlError(env);
-}
-
-static void PerfMeasurement_nativeStopGlTimer(JNIEnv* env, jobject thiz,
-            jlong contextHandle) {
-
-    PerfMeasurementContext *context = getContext(contextHandle);
-    status_t err = context->stopGlTimer();
-    if (err != OK) {
-        switch (err) {
-            case INVALID_OPERATION:
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                        "Mismatched start/end GL timing calls");
-                return;
-            default:
-                jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
-                        "Unknown error ending GL timing");
-                return;
-        }
-    }
-    checkGlError(env);
-}
-
-static jlong PerfMeasurement_nativeGetNextGlDuration(JNIEnv* env,
-        jobject thiz, jlong contextHandle) {
-    PerfMeasurementContext *context = getContext(contextHandle);
-    nsecs_t duration = context->getNextGlDuration();
-
-    checkGlError(env);
-    return static_cast<jlong>(duration);
-}
-
-} // extern "C"
-
-static const JNINativeMethod gPerfMeasurementMethods[] = {
-    { "nativeCreateContext",
-      "(I)J",
-      (jlong *)PerfMeasurement_nativeCreateContext },
-    { "nativeDeleteContext",
-      "(J)V",
-      (void *)PerfMeasurement_nativeDeleteContext },
-    { "nativeQuerySupport",
-      "()Z",
-      (jboolean *)PerfMeasurement_nativeQuerySupport },
-    { "nativeStartGlTimer",
-      "(J)V",
-      (void *)PerfMeasurement_nativeStartGlTimer },
-    { "nativeStopGlTimer",
-      "(J)V",
-      (void *)PerfMeasurement_nativeStopGlTimer },
-    { "nativeGetNextGlDuration",
-      "(J)J",
-      (jlong *)PerfMeasurement_nativeGetNextGlDuration }
-};
-
-
-// Get all the required offsets in java class and register native functions
-int register_android_hardware_camera2_legacy_PerfMeasurement(JNIEnv* env)
-{
-    // Register native functions
-    return RegisterMethodsOrDie(env,
-            PERF_MEASUREMENT_CLASS_NAME,
-            gPerfMeasurementMethods,
-            NELEM(gPerfMeasurementMethods));
-}
diff --git a/core/jni/android_hardware_camera2_utils_SurfaceUtils.cpp b/core/jni/android_hardware_camera2_utils_SurfaceUtils.cpp
new file mode 100644
index 0000000..2437a51
--- /dev/null
+++ b/core/jni/android_hardware_camera2_utils_SurfaceUtils.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#define LOG_TAG "Camera-SurfaceUtils-JNI"
+// #define LOG_NDEBUG 0
+#include <camera/CameraUtils.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include <nativehelper/JNIHelp.h>
+#include "android_runtime/android_graphics_SurfaceTexture.h"
+#include "android_runtime/android_view_Surface.h"
+#include "core_jni_helpers.h"
+#include "jni.h"
+
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/IProducerListener.h>
+#include <gui/Surface.h>
+#include <system/window.h>
+#include <ui/GraphicBuffer.h>
+
+#include <inttypes.h>
+#include <stdint.h>
+
+using namespace android;
+
+// fully-qualified class name
+#define CAMERA_UTILS_CLASS_NAME "android/hardware/camera2/utils/SurfaceUtils"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+
+#define OVERRIDE_SURFACE_ERROR(err) \
+    do {                            \
+        if (err == -ENODEV) {       \
+            err = BAD_VALUE;        \
+        }                           \
+    } while (0)
+
+static sp<ANativeWindow> getNativeWindow(JNIEnv* env, jobject surface) {
+    sp<ANativeWindow> anw;
+    if (surface) {
+        anw = android_view_Surface_getNativeWindow(env, surface);
+        if (env->ExceptionCheck()) {
+            return NULL;
+        }
+    } else {
+        jniThrowNullPointerException(env, "surface");
+        return NULL;
+    }
+    if (anw == NULL) {
+        ALOGE("%s: Surface had no valid native window.", __FUNCTION__);
+        return NULL;
+    }
+    return anw;
+}
+
+static sp<Surface> getSurface(JNIEnv* env, jobject surface) {
+    sp<Surface> s;
+    if (surface) {
+        s = android_view_Surface_getSurface(env, surface);
+        if (env->ExceptionCheck()) {
+            return NULL;
+        }
+    } else {
+        jniThrowNullPointerException(env, "surface");
+        return NULL;
+    }
+    if (s == NULL) {
+        jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
+                             "Surface had no valid native Surface.");
+        return NULL;
+    }
+    return s;
+}
+
+extern "C" {
+
+static jint SurfaceUtils_nativeDetectSurfaceType(JNIEnv* env, jobject thiz, jobject surface) {
+    ALOGV("nativeDetectSurfaceType");
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    int32_t fmt = 0;
+    status_t err = anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt);
+    if (err != NO_ERROR) {
+        ALOGE("%s: Error while querying surface pixel format %s (%d).", __FUNCTION__,
+              strerror(-err), err);
+        OVERRIDE_SURFACE_ERROR(err);
+        return err;
+    }
+    return fmt;
+}
+
+static jint SurfaceUtils_nativeDetectSurfaceDataspace(JNIEnv* env, jobject thiz, jobject surface) {
+    ALOGV("nativeDetectSurfaceDataspace");
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    int32_t fmt = 0;
+    status_t err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE, &fmt);
+    if (err != NO_ERROR) {
+        ALOGE("%s: Error while querying surface dataspace  %s (%d).", __FUNCTION__, strerror(-err),
+              err);
+        OVERRIDE_SURFACE_ERROR(err);
+        return err;
+    }
+    return fmt;
+}
+
+static jint SurfaceUtils_nativeDetectSurfaceDimens(JNIEnv* env, jobject thiz, jobject surface,
+                                                   jintArray dimens) {
+    ALOGV("nativeGetSurfaceDimens");
+
+    if (dimens == NULL) {
+        ALOGE("%s: Null dimens argument passed to nativeDetectSurfaceDimens", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    if (env->GetArrayLength(dimens) < 2) {
+        ALOGE("%s: Invalid length of dimens argument in nativeDetectSurfaceDimens", __FUNCTION__);
+        return BAD_VALUE;
+    }
+
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        ALOGE("%s: Could not retrieve native window from surface.", __FUNCTION__);
+        return BAD_VALUE;
+    }
+    int32_t dimenBuf[2];
+    status_t err = anw->query(anw.get(), NATIVE_WINDOW_WIDTH, dimenBuf);
+    if (err != NO_ERROR) {
+        ALOGE("%s: Error while querying surface width %s (%d).", __FUNCTION__, strerror(-err), err);
+        OVERRIDE_SURFACE_ERROR(err);
+        return err;
+    }
+    err = anw->query(anw.get(), NATIVE_WINDOW_HEIGHT, dimenBuf + 1);
+    if (err != NO_ERROR) {
+        ALOGE("%s: Error while querying surface height %s (%d).", __FUNCTION__, strerror(-err),
+              err);
+        OVERRIDE_SURFACE_ERROR(err);
+        return err;
+    }
+    env->SetIntArrayRegion(dimens, /*start*/ 0, /*length*/ ARRAY_SIZE(dimenBuf), dimenBuf);
+    return NO_ERROR;
+}
+
+static jlong SurfaceUtils_nativeDetectSurfaceUsageFlags(JNIEnv* env, jobject thiz,
+                                                        jobject surface) {
+    ALOGV("nativeDetectSurfaceUsageFlags");
+
+    sp<ANativeWindow> anw;
+    if ((anw = getNativeWindow(env, surface)) == NULL) {
+        jniThrowException(env, "java/lang/UnsupportedOperationException",
+                          "Could not retrieve native window from surface.");
+        return BAD_VALUE;
+    }
+    uint64_t usage = 0;
+    status_t err = native_window_get_consumer_usage(anw.get(), &usage);
+    if (err != NO_ERROR) {
+        jniThrowException(env, "java/lang/UnsupportedOperationException",
+                          "Error while querying surface usage bits");
+        OVERRIDE_SURFACE_ERROR(err);
+        return err;
+    }
+    return usage;
+}
+
+static jlong SurfaceUtils_nativeGetSurfaceId(JNIEnv* env, jobject thiz, jobject surface) {
+    ALOGV("nativeGetSurfaceId");
+    sp<Surface> s;
+    if ((s = getSurface(env, surface)) == NULL) {
+        ALOGE("%s: Could not retrieve native Surface from surface.", __FUNCTION__);
+        return 0;
+    }
+    sp<IGraphicBufferProducer> gbp = s->getIGraphicBufferProducer();
+    if (gbp == NULL) {
+        ALOGE("%s: Could not retrieve IGraphicBufferProducer from surface.", __FUNCTION__);
+        return 0;
+    }
+    sp<IBinder> b = IInterface::asBinder(gbp);
+    if (b == NULL) {
+        ALOGE("%s: Could not retrieve IBinder from surface.", __FUNCTION__);
+        return 0;
+    }
+    /*
+     * FIXME: Use better unique ID for surfaces than native IBinder pointer.  Fix also in the camera
+     * service (CameraDeviceClient.h).
+     */
+    return reinterpret_cast<jlong>(b.get());
+}
+
+} // extern "C"
+
+static const JNINativeMethod gCameraSurfaceUtilsMethods[] = {
+        {"nativeDetectSurfaceType", "(Landroid/view/Surface;)I",
+         (void*)SurfaceUtils_nativeDetectSurfaceType},
+        {"nativeDetectSurfaceDataspace", "(Landroid/view/Surface;)I",
+         (void*)SurfaceUtils_nativeDetectSurfaceDataspace},
+        {"nativeDetectSurfaceDimens", "(Landroid/view/Surface;[I)I",
+         (void*)SurfaceUtils_nativeDetectSurfaceDimens},
+        {"nativeDetectSurfaceUsageFlags", "(Landroid/view/Surface;)J",
+         (void*)SurfaceUtils_nativeDetectSurfaceUsageFlags},
+        {"nativeGetSurfaceId", "(Landroid/view/Surface;)J", (void*)SurfaceUtils_nativeGetSurfaceId},
+};
+
+// Get all the required offsets in java class and register native functions
+int register_android_hardware_camera2_utils_SurfaceUtils(JNIEnv* env) {
+    // Register native functions
+    return RegisterMethodsOrDie(env, CAMERA_UTILS_CLASS_NAME, gCameraSurfaceUtilsMethods,
+                                NELEM(gCameraSurfaceUtilsMethods));
+}
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 6fd0c13..8153166 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -180,7 +180,8 @@
     if (parcel) {
         bool isInitialized = parcel->readInt32();
         if (isInitialized) {
-            sp<InputChannel> inputChannel = InputChannel::read(*parcel);
+            sp<InputChannel> inputChannel = new InputChannel();
+            inputChannel->readFromParcel(parcel);
             NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel);
             return reinterpret_cast<jlong>(nativeInputChannel);
         }
@@ -203,7 +204,7 @@
         return;
     }
     parcel->writeInt32(1); // initialized
-    nativeInputChannel->getInputChannel()->write(*parcel);
+    nativeInputChannel->getInputChannel()->writeToParcel(parcel);
 }
 
 static jstring android_view_InputChannel_nativeGetName(JNIEnv* env, jobject obj, jlong channel) {
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index ec99684..f2f20e3a 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -236,6 +236,8 @@
     optional int64 api_quota_schedule_window_ms = 33;
     // Whether or not to throw an exception when an app hits its schedule quota limit.
     optional bool api_quota_schedule_throw_exception = 34;
+    // Whether or not to return a failure result when an app hits its schedule quota limit.
+    optional bool api_quota_schedule_return_failure_result = 35;
 
     message QuotaController {
         option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -335,7 +337,7 @@
     // In this time after screen turns on, we increase job concurrency.
     optional int32 screen_off_job_concurrency_increase_delay_ms = 28;
 
-    // Next tag: 35
+    // Next tag: 36
 }
 
 // Next tag: 4
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 485f5bf..506069c 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -424,9 +424,9 @@
     <string name="permlab_accessLocationExtraCommands" msgid="5162339812057983988">"atzitu kokapen-hornitzaileen komando gehigarriak"</string>
     <string name="permdesc_accessLocationExtraCommands" msgid="355369611979907967">"Kokapen-hornitzailearen agindu gehigarriak atzitzeko baimena ematen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
     <string name="permlab_accessFineLocation" msgid="6426318438195622966">"lortu kokapen zehatza aurreko planoan bakarrik"</string>
-    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Erabiltzen ari zarenean, aplikazioak kokapen zehatza lor dezake kokapen-zerbitzuen bidez. Aplikazioak kokapena lortu ahal izateko, kokapen-zerbitzuek aktibatuta egon behar dute gailuan. Bateria-erabilera areagotzen du horrek."</string>
+    <string name="permdesc_accessFineLocation" msgid="6732174080240016335">"Abian denean, aplikazioak kokapen zehatza lor dezake kokapen-zerbitzuen bidez. Aplikazioak kokapena lortu ahal izateko, kokapen-zerbitzuek aktibatuta egon behar dute gailuan. Bateria-erabilera areagotzen du horrek."</string>
     <string name="permlab_accessCoarseLocation" msgid="1561042925407799741">"atzitu gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Erabiltzen ari zarenean, aplikazioak gutxi gorabeherako kokapena lor dezake kokapen-zerbitzuen bidez. Aplikazioak kokapena lortu ahal izateko, kokapen-zerbitzuek aktibatuta egon behar dute gailuan."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="778521847873199160">"Abian denean, aplikazioak gutxi gorabeherako kokapena lor dezake kokapen-zerbitzuen bidez. Aplikazioak kokapena lortu ahal izateko, kokapen-zerbitzuek aktibatuta egon behar dute gailuan."</string>
     <string name="permlab_accessBackgroundLocation" msgid="1721164702777366138">"atzitu kokapena atzeko planoan"</string>
     <string name="permdesc_accessBackgroundLocation" msgid="8264885066095638105">"Aplikazioak kokapena atzi dezake, baita aplikazioa erabiltzen ari ez zarenean ere."</string>
     <string name="permlab_modifyAudioSettings" msgid="6129039778010031815">"aldatu audio-ezarpenak"</string>
diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml
index 3ecb1dd..0382dd3 100644
--- a/core/res/res/values-television/config.xml
+++ b/core/res/res/values-television/config.xml
@@ -42,4 +42,13 @@
 
     <!-- Allow SystemUI to show the shutdown dialog -->
     <bool name="config_showSysuiShutdown">true</bool>
+
+    <!-- Control the behavior when the user long presses the power button.
+        0 - Nothing
+        1 - Global actions menu
+        2 - Power off (with confirmation)
+        3 - Power off (without confirmation)
+        4 - Go to voice assist
+        5 - Go to assistant (Settings.Secure.ASSISTANT -->
+    <integer name="config_longPressOnPowerBehavior">3</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 367cff9..12275dc 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4828,10 +4828,10 @@
     <string name="confirm_battery_saver">OK</string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
-    <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n\n\u2022Turns on Dark theme\n\u2022Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
+    <string name="battery_saver_description_with_learn_more">To extend battery life, Battery Saver:\n\n\u2022 Turns on Dark theme\n\u2022 Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d\n\n<annotation id="url">Learn more</annotation></string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
-    <string name="battery_saver_description">To extend battery life, Battery Saver:\n\n\u2022Turns on Dark theme\n\u2022Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string>
+    <string name="battery_saver_description">To extend battery life, Battery Saver:\n\n\u2022 Turns on Dark theme\n\u2022 Turns off or restricts background activity, some visual effects, and other features like \u201cHey Google\u201d</string>
 
     <!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
     <string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string>
diff --git a/core/tests/coretests/src/android/text/format/DateFormatTest.java b/core/tests/coretests/src/android/text/format/DateFormatTest.java
index 5a0a84d..fa1d56f 100644
--- a/core/tests/coretests/src/android/text/format/DateFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateFormatTest.java
@@ -16,8 +16,10 @@
 
 package android.text.format;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.platform.test.annotations.Presubmit;
 
@@ -27,6 +29,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Arrays;
 import java.util.Locale;
 
 @Presubmit
@@ -55,4 +58,71 @@
         assertFalse(DateFormat.is24HourLocale(Locale.US));
         assertTrue(DateFormat.is24HourLocale(Locale.GERMANY));
     }
+
+    @Test
+    public void testGetDateFormatOrder() {
+        // lv and fa use differing orders depending on whether you're using numeric or
+        // textual months.
+        Locale lv = new Locale("lv");
+        assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(lv, "yyyy-M-dd"))));
+        assertEquals("[y, d, M]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(lv, "yyyy-MMM-dd"))));
+        assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(lv, "MMM-dd"))));
+        Locale fa = new Locale("fa");
+        assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(fa, "yyyy-M-dd"))));
+        assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(fa, "yyyy-MMM-dd"))));
+        assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(fa, "MMM-dd"))));
+
+        // English differs on each side of the Atlantic.
+        Locale enUS = Locale.US;
+        assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enUS, "yyyy-M-dd"))));
+        assertEquals("[M, d, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enUS, "yyyy-MMM-dd"))));
+        assertEquals("[M, d, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enUS, "MMM-dd"))));
+        Locale enGB = Locale.UK;
+        assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enGB, "yyyy-M-dd"))));
+        assertEquals("[d, M, y]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enGB, "yyyy-MMM-dd"))));
+        assertEquals("[d, M, \u0000]", Arrays.toString(DateFormat.getDateFormatOrder(
+                best(enGB, "MMM-dd"))));
+
+        assertEquals("[y, M, d]", Arrays.toString(DateFormat.getDateFormatOrder(
+                "yyyy - 'why' '' 'ddd' MMM-dd")));
+
+        try {
+            DateFormat.getDateFormatOrder("the quick brown fox jumped over the lazy dog");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            DateFormat.getDateFormatOrder("'");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            DateFormat.getDateFormatOrder("yyyy'");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+
+        try {
+            DateFormat.getDateFormatOrder("yyyy'MMM");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    private static String best(Locale l, String skeleton) {
+        return DateFormat.getBestDateTimePattern(l, skeleton);
+    }
 }
diff --git a/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java
new file mode 100644
index 0000000..d9ba8fb
--- /dev/null
+++ b/core/tests/coretests/src/android/text/format/RelativeDateTimeFormatterTest.java
@@ -0,0 +1,762 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import static android.text.format.DateUtilsBridge.FORMAT_ABBREV_ALL;
+import static android.text.format.DateUtilsBridge.FORMAT_ABBREV_RELATIVE;
+import static android.text.format.DateUtilsBridge.FORMAT_NO_YEAR;
+import static android.text.format.DateUtilsBridge.FORMAT_NUMERIC_DATE;
+import static android.text.format.DateUtilsBridge.FORMAT_SHOW_YEAR;
+import static android.text.format.RelativeDateTimeFormatter.DAY_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.HOUR_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.MINUTE_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.SECOND_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.WEEK_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.YEAR_IN_MILLIS;
+import static android.text.format.RelativeDateTimeFormatter.getRelativeDateTimeString;
+import static android.text.format.RelativeDateTimeFormatter.getRelativeTimeSpanString;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Calendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class RelativeDateTimeFormatterTest {
+
+    // Tests adopted from CTS tests for DateUtils.getRelativeTimeSpanString.
+    @Test
+    public void test_getRelativeTimeSpanStringCTS() throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("GMT");
+        Calendar cal = Calendar.getInstance(tz, en_US);
+        // Feb 5, 2015 at 10:50 GMT
+        cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+        final long baseTime = cal.getTimeInMillis();
+
+        assertEquals("0 minutes ago",
+                getRelativeTimeSpanString(en_US, tz, baseTime - SECOND_IN_MILLIS, baseTime,
+                        MINUTE_IN_MILLIS, 0));
+        assertEquals("In 0 minutes",
+                getRelativeTimeSpanString(en_US, tz, baseTime + SECOND_IN_MILLIS, baseTime,
+                        MINUTE_IN_MILLIS, 0));
+
+        assertEquals("1 minute ago",
+                getRelativeTimeSpanString(en_US, tz, 0, MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 0));
+        assertEquals("In 1 minute",
+                getRelativeTimeSpanString(en_US, tz, MINUTE_IN_MILLIS, 0, MINUTE_IN_MILLIS, 0));
+
+        assertEquals("42 minutes ago",
+                getRelativeTimeSpanString(en_US, tz, baseTime - 42 * MINUTE_IN_MILLIS, baseTime,
+                        MINUTE_IN_MILLIS, 0));
+        assertEquals("In 42 minutes",
+                getRelativeTimeSpanString(en_US, tz, baseTime + 42 * MINUTE_IN_MILLIS, baseTime,
+                        MINUTE_IN_MILLIS, 0));
+
+        final long TWO_HOURS_IN_MS = 2 * HOUR_IN_MILLIS;
+        assertEquals("2 hours ago",
+                getRelativeTimeSpanString(en_US, tz, baseTime - TWO_HOURS_IN_MS, baseTime,
+                        MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE));
+        assertEquals("In 2 hours",
+                getRelativeTimeSpanString(en_US, tz, baseTime + TWO_HOURS_IN_MS, baseTime,
+                        MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE));
+
+        assertEquals("In 42 min.",
+                getRelativeTimeSpanString(en_US, tz, baseTime + (42 * MINUTE_IN_MILLIS), baseTime,
+                        MINUTE_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+
+        assertEquals("Tomorrow",
+                getRelativeTimeSpanString(en_US, tz, DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0));
+        assertEquals("In 2 days",
+                getRelativeTimeSpanString(en_US, tz, 2 * DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0));
+        assertEquals("Yesterday",
+                getRelativeTimeSpanString(en_US, tz, 0, DAY_IN_MILLIS, DAY_IN_MILLIS, 0));
+        assertEquals("2 days ago",
+                getRelativeTimeSpanString(en_US, tz, 0, 2 * DAY_IN_MILLIS, DAY_IN_MILLIS, 0));
+
+        final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
+        assertEquals("5 days ago",
+                getRelativeTimeSpanString(en_US, tz, baseTime - DAY_DURATION, baseTime,
+                        DAY_IN_MILLIS, 0));
+    }
+
+    private void test_getRelativeTimeSpanString_helper(long delta, long minResolution, int flags,
+            String expectedInPast,
+            String expectedInFuture) throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+        Calendar cal = Calendar.getInstance(tz, en_US);
+        // Feb 5, 2015 at 10:50 PST
+        cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+        final long base = cal.getTimeInMillis();
+
+        assertEquals(expectedInPast,
+                getRelativeTimeSpanString(en_US, tz, base - delta, base, minResolution, flags));
+        assertEquals(expectedInFuture,
+                getRelativeTimeSpanString(en_US, tz, base + delta, base, minResolution, flags));
+    }
+
+    private void test_getRelativeTimeSpanString_helper(long delta, long minResolution,
+            String expectedInPast,
+            String expectedInFuture) throws Exception {
+        test_getRelativeTimeSpanString_helper(delta, minResolution, 0, expectedInPast,
+                expectedInFuture);
+    }
+
+    @Test
+    public void test_getRelativeTimeSpanString() throws Exception {
+
+        test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, "0 seconds ago",
+                "0 seconds ago");
+        test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago",
+                "In 1 minute");
+        test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago",
+                "In 1 minute");
+        test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, "5 days ago", "In 5 days");
+
+        test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "0 seconds ago",
+                "0 seconds ago");
+        test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "1 second ago",
+                "In 1 second");
+        test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "2 seconds ago",
+                "In 2 seconds");
+        test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "25 seconds ago",
+                "In 25 seconds");
+        test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "1 minute ago",
+                "In 1 minute");
+        test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS,
+                "1 hour ago",
+                "In 1 hour");
+
+        test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "0 minutes ago",
+                "0 minutes ago");
+        test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "1 minute ago",
+                "In 1 minute");
+        test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "2 minutes ago",
+                "In 2 minutes");
+        test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "25 minutes ago",
+                "In 25 minutes");
+        test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "1 hour ago",
+                "In 1 hour");
+        test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "12 hours ago",
+                "In 12 hours");
+
+        test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago",
+                "0 hours ago");
+        test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago",
+                "In 1 hour");
+        test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "2 hours ago",
+                "In 2 hours");
+        test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "5 hours ago",
+                "In 5 hours");
+        test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "20 hours ago",
+                "In 20 hours");
+
+        test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today");
+        test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
+                "Tomorrow");
+        test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
+                "Tomorrow");
+        test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
+                "In 2 days");
+        test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, "January 11",
+                "March 2");
+
+        test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago",
+                "0 weeks ago");
+        test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago",
+                "In 1 week");
+        test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "2 weeks ago",
+                "In 2 weeks");
+        test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "25 weeks ago",
+                "In 25 weeks");
+
+        // duration >= minResolution
+        test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, "30 seconds ago",
+                "In 30 seconds");
+        test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
+                "30 minutes ago", "In 30 minutes");
+        test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, "Yesterday",
+                "Tomorrow");
+        test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, "5 days ago",
+                "In 5 days");
+        test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS,
+                "July 10, 2014",
+                "September 3");
+        test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS,
+                "February 6, 2010", "February 4, 2020");
+
+        test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS,
+                "1 minute ago",
+                "In 1 minute");
+        test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS,
+                "1 minute ago", "In 1 minute");
+        test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago",
+                "In 1 hour");
+        test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS,
+                "1 hour ago",
+                "In 1 hour");
+        test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today");
+        test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
+                "Today");
+        test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
+                "Tomorrow");
+        test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
+                "In 2 days");
+        test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
+                "In 2 days");
+        test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago",
+                "In 1 week");
+        test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, "1 week ago",
+                "In 1 week");
+
+        // duration < minResolution
+        test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS,
+                "0 minutes ago",
+                "In 0 minutes");
+        test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago",
+                "In 0 hours");
+        test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, "0 hours ago",
+                "In 0 hours");
+        test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, "Yesterday",
+                "Tomorrow");
+        test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago",
+                "In 0 weeks");
+        test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, "0 weeks ago",
+                "In 0 weeks");
+    }
+
+    @Test
+    public void test_getRelativeTimeSpanStringAbbrev() throws Exception {
+        int flags = FORMAT_ABBREV_RELATIVE;
+
+        test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, flags, "0 sec. ago",
+                "0 sec. ago");
+        test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, flags, "1 min. ago",
+                "In 1 min.");
+        test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, flags, "5 days ago",
+                "In 5 days");
+
+        test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "0 sec. ago", "0 sec. ago");
+        test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "1 sec. ago", "In 1 sec.");
+        test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "2 sec. ago", "In 2 sec.");
+        test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "25 sec. ago", "In 25 sec.");
+        test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "1 min. ago", "In 1 min.");
+        test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
+                "1 hr. ago", "In 1 hr.");
+
+        test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "0 min. ago", "0 min. ago");
+        test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "1 min. ago", "In 1 min.");
+        test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "2 min. ago", "In 2 min.");
+        test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "25 min. ago", "In 25 min.");
+        test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "1 hr. ago", "In 1 hr.");
+        test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "12 hr. ago", "In 12 hr.");
+
+        test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "0 hr. ago", "0 hr. ago");
+        test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "1 hr. ago", "In 1 hr.");
+        test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "2 hr. ago", "In 2 hr.");
+        test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "5 hr. ago", "In 5 hr.");
+        test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "20 hr. ago", "In 20 hr.");
+
+        test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags, "Today",
+                "Today");
+        test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "Yesterday", "Tomorrow");
+        test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "Yesterday", "Tomorrow");
+        test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "2 days ago", "In 2 days");
+        test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "January 11", "March 2");
+
+        test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "0 wk. ago", "0 wk. ago");
+        test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "1 wk. ago", "In 1 wk.");
+        test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "2 wk. ago", "In 2 wk.");
+        test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "25 wk. ago", "In 25 wk.");
+
+        // duration >= minResolution
+        test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, flags, "30 sec. ago",
+                "In 30 sec.");
+        test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "30 min. ago", "In 30 min.");
+        test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "Yesterday", "Tomorrow");
+        test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "5 days ago", "In 5 days");
+        test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "July 10, 2014", "September 3");
+        test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "February 6, 2010", "February 4, 2020");
+
+        test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "1 min. ago", "In 1 min.");
+        test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS, flags,
+                "1 min. ago", "In 1 min.");
+        test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "1 hr. ago", "In 1 hr.");
+        test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS, flags,
+                "1 hr. ago", "In 1 hr.");
+        test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, "Today",
+                "Today");
+        test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "Yesterday", "Today");
+        test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "Yesterday", "Tomorrow");
+        test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "2 days ago", "In 2 days");
+        test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
+                "2 days ago", "In 2 days");
+        test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "1 wk. ago", "In 1 wk.");
+        test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, flags,
+                "1 wk. ago", "In 1 wk.");
+
+        // duration < minResolution
+        test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags,
+                "0 min. ago", "In 0 min.");
+        test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags,
+                "0 hr. ago", "In 0 hr.");
+        test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, flags,
+                "0 hr. ago", "In 0 hr.");
+        test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, flags,
+                "Yesterday", "Tomorrow");
+        test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, flags,
+                "0 wk. ago", "In 0 wk.");
+        test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, flags,
+                "0 wk. ago", "In 0 wk.");
+
+    }
+
+    @Test
+    public void test_getRelativeTimeSpanStringGerman() throws Exception {
+        // Bug: 19744876
+        // We need to specify the timezone and the time explicitly. Otherwise it
+        // may not always give a correct answer of "tomorrow" by using
+        // (now + DAY_IN_MILLIS).
+        Locale de_DE = new Locale("de", "DE");
+        TimeZone tz = TimeZone.getTimeZone("Europe/Berlin");
+        Calendar cal = Calendar.getInstance(tz, de_DE);
+        // Feb 5, 2015 at 10:50 CET
+        cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+        final long now = cal.getTimeInMillis();
+
+        // 42 minutes ago
+        assertEquals("Vor 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
+                now - 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
+        // In 42 minutes
+        assertEquals("In 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
+                now + 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
+        // Yesterday
+        assertEquals("Gestern", getRelativeTimeSpanString(de_DE, tz,
+                now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // The day before yesterday
+        assertEquals("Vorgestern", getRelativeTimeSpanString(de_DE, tz,
+                now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // Tomorrow
+        assertEquals("Morgen", getRelativeTimeSpanString(de_DE, tz,
+                now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // The day after tomorrow
+        assertEquals("Übermorgen", getRelativeTimeSpanString(de_DE, tz,
+                now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+    }
+
+    @Test
+    public void test_getRelativeTimeSpanStringFrench() throws Exception {
+        Locale fr_FR = new Locale("fr", "FR");
+        TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
+        Calendar cal = Calendar.getInstance(tz, fr_FR);
+        // Feb 5, 2015 at 10:50 CET
+        cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+        final long now = cal.getTimeInMillis();
+
+        // 42 minutes ago
+        assertEquals("Il y a 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
+                now - (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
+        // In 42 minutes
+        assertEquals("Dans 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
+                now + (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
+        // Yesterday
+        assertEquals("Hier", getRelativeTimeSpanString(fr_FR, tz,
+                now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // The day before yesterday
+        assertEquals("Avant-hier", getRelativeTimeSpanString(fr_FR, tz,
+                now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // Tomorrow
+        assertEquals("Demain", getRelativeTimeSpanString(fr_FR, tz,
+                now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+        // The day after tomorrow
+        assertEquals("Après-demain", getRelativeTimeSpanString(fr_FR, tz,
+                now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
+    }
+
+    // Tests adopted from CTS tests for DateUtils.getRelativeDateTimeString.
+    @Test
+    public void test_getRelativeDateTimeStringCTS() throws Exception {
+        Locale en_US = Locale.getDefault();
+        TimeZone tz = TimeZone.getDefault();
+        final long baseTime = System.currentTimeMillis();
+
+        final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
+        assertNotNull(getRelativeDateTimeString(en_US, tz, baseTime - DAY_DURATION, baseTime,
+                MINUTE_IN_MILLIS, DAY_IN_MILLIS,
+                FORMAT_NUMERIC_DATE));
+    }
+
+    @Test
+    public void test_getRelativeDateTimeString() throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+        Calendar cal = Calendar.getInstance(tz, en_US);
+        // Feb 5, 2015 at 10:50 PST
+        cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
+        final long base = cal.getTimeInMillis();
+
+        assertEquals("5 seconds ago, 10:49 AM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * SECOND_IN_MILLIS, base, 0,
+                        MINUTE_IN_MILLIS, 0));
+        assertEquals("5 min. ago, 10:45 AM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base, 0,
+                        HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("0 hr. ago, 10:45 AM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base,
+                        HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("5 hours ago, 5:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base,
+                        HOUR_IN_MILLIS, DAY_IN_MILLIS, 0));
+        assertEquals("Yesterday, 7:50 PM",
+                getRelativeDateTimeString(en_US, tz, base - 15 * HOUR_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("5 days ago, 10:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * DAY_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+        assertEquals("Jan 29, 10:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 7 * DAY_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+        assertEquals("11/27/2014, 10:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+        assertEquals("11/27/2014, 10:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
+                        YEAR_IN_MILLIS, 0));
+
+        // User-supplied flags should be ignored when formatting the date clause.
+        final int FORMAT_SHOW_WEEKDAY = 0x00002;
+        assertEquals("11/27/2014, 10:50 AM",
+                getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS,
+                        FORMAT_ABBREV_ALL | FORMAT_SHOW_WEEKDAY));
+    }
+
+    @Test
+    public void test_getRelativeDateTimeStringDST() throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+        Calendar cal = Calendar.getInstance(tz, en_US);
+
+        // DST starts on Mar 9, 2014 at 2:00 AM.
+        // So 5 hours before 3:15 AM should be formatted as 'Yesterday, 9:15 PM'.
+        cal.set(2014, Calendar.MARCH, 9, 3, 15, 0);
+        long base = cal.getTimeInMillis();
+        assertEquals("Yesterday, 9:15 PM",
+                getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+
+        // 1 hour after 2:00 AM should be formatted as 'In 1 hour, 4:00 AM'.
+        cal.set(2014, Calendar.MARCH, 9, 2, 0, 0);
+        base = cal.getTimeInMillis();
+        assertEquals("In 1 hour, 4:00 AM",
+                getRelativeDateTimeString(en_US, tz, base + 1 * HOUR_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+
+        // DST ends on Nov 2, 2014 at 2:00 AM. Clocks are turned backward 1 hour to
+        // 1:00 AM. 8 hours before 5:20 AM should be 'Yesterday, 10:20 PM'.
+        cal.set(2014, Calendar.NOVEMBER, 2, 5, 20, 0);
+        base = cal.getTimeInMillis();
+        assertEquals("Yesterday, 10:20 PM",
+                getRelativeDateTimeString(en_US, tz, base - 8 * HOUR_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+
+        cal.set(2014, Calendar.NOVEMBER, 2, 0, 45, 0);
+        base = cal.getTimeInMillis();
+        // 45 minutes after 0:45 AM should be 'In 45 minutes, 1:30 AM'.
+        assertEquals("In 45 minutes, 1:30 AM",
+                getRelativeDateTimeString(en_US, tz, base + 45 * MINUTE_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+        // 45 minutes later, it should be 'In 45 minutes, 1:15 AM'.
+        assertEquals("In 45 minutes, 1:15 AM",
+                getRelativeDateTimeString(en_US, tz, base + 90 * MINUTE_IN_MILLIS,
+                        base + 45 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0));
+        // Another 45 minutes later, it should be 'In 45 minutes, 2:00 AM'.
+        assertEquals("In 45 minutes, 2:00 AM",
+                getRelativeDateTimeString(en_US, tz, base + 135 * MINUTE_IN_MILLIS,
+                        base + 90 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0));
+    }
+
+    @Test
+    public void test_getRelativeDateTimeStringItalian() throws Exception {
+        Locale it_IT = new Locale("it", "IT");
+        TimeZone tz = TimeZone.getTimeZone("Europe/Rome");
+        Calendar cal = Calendar.getInstance(tz, it_IT);
+        // 05 febbraio 2015 20:15
+        cal.set(2015, Calendar.FEBRUARY, 5, 20, 15, 0);
+        final long base = cal.getTimeInMillis();
+
+        assertEquals("5 secondi fa, 20:14",
+                getRelativeDateTimeString(it_IT, tz, base - 5 * SECOND_IN_MILLIS, base, 0,
+                        MINUTE_IN_MILLIS, 0));
+        assertEquals("5 min fa, 20:10",
+                getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base, 0,
+                        HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("0 h fa, 20:10",
+                getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base,
+                        HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("Ieri, 22:15",
+                getRelativeDateTimeString(it_IT, tz, base - 22 * HOUR_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+        assertEquals("5 giorni fa, 20:15",
+                getRelativeDateTimeString(it_IT, tz, base - 5 * DAY_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+        assertEquals("27/11/2014, 20:15",
+                getRelativeDateTimeString(it_IT, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
+                        WEEK_IN_MILLIS, 0));
+    }
+
+    // http://b/5252772: detect the actual date difference
+    @Test
+    public void test5252772() throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+
+        // Now is Sep 2, 2011, 10:23 AM PDT.
+        Calendar nowCalendar = Calendar.getInstance(tz, en_US);
+        nowCalendar.set(2011, Calendar.SEPTEMBER, 2, 10, 23, 0);
+        final long now = nowCalendar.getTimeInMillis();
+
+        // Sep 1, 2011, 10:24 AM
+        Calendar yesterdayCalendar1 = Calendar.getInstance(tz, en_US);
+        yesterdayCalendar1.set(2011, Calendar.SEPTEMBER, 1, 10, 24, 0);
+        long yesterday1 = yesterdayCalendar1.getTimeInMillis();
+        assertEquals("Yesterday, 10:24 AM",
+                getRelativeDateTimeString(en_US, tz, yesterday1, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Sep 1, 2011, 10:22 AM
+        Calendar yesterdayCalendar2 = Calendar.getInstance(tz, en_US);
+        yesterdayCalendar2.set(2011, Calendar.SEPTEMBER, 1, 10, 22, 0);
+        long yesterday2 = yesterdayCalendar2.getTimeInMillis();
+        assertEquals("Yesterday, 10:22 AM",
+                getRelativeDateTimeString(en_US, tz, yesterday2, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Aug 31, 2011, 10:24 AM
+        Calendar twoDaysAgoCalendar1 = Calendar.getInstance(tz, en_US);
+        twoDaysAgoCalendar1.set(2011, Calendar.AUGUST, 31, 10, 24, 0);
+        long twoDaysAgo1 = twoDaysAgoCalendar1.getTimeInMillis();
+        assertEquals("2 days ago, 10:24 AM",
+                getRelativeDateTimeString(en_US, tz, twoDaysAgo1, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Aug 31, 2011, 10:22 AM
+        Calendar twoDaysAgoCalendar2 = Calendar.getInstance(tz, en_US);
+        twoDaysAgoCalendar2.set(2011, Calendar.AUGUST, 31, 10, 22, 0);
+        long twoDaysAgo2 = twoDaysAgoCalendar2.getTimeInMillis();
+        assertEquals("2 days ago, 10:22 AM",
+                getRelativeDateTimeString(en_US, tz, twoDaysAgo2, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Sep 3, 2011, 10:22 AM
+        Calendar tomorrowCalendar1 = Calendar.getInstance(tz, en_US);
+        tomorrowCalendar1.set(2011, Calendar.SEPTEMBER, 3, 10, 22, 0);
+        long tomorrow1 = tomorrowCalendar1.getTimeInMillis();
+        assertEquals("Tomorrow, 10:22 AM",
+                getRelativeDateTimeString(en_US, tz, tomorrow1, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Sep 3, 2011, 10:24 AM
+        Calendar tomorrowCalendar2 = Calendar.getInstance(tz, en_US);
+        tomorrowCalendar2.set(2011, Calendar.SEPTEMBER, 3, 10, 24, 0);
+        long tomorrow2 = tomorrowCalendar2.getTimeInMillis();
+        assertEquals("Tomorrow, 10:24 AM",
+                getRelativeDateTimeString(en_US, tz, tomorrow2, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Sep 4, 2011, 10:22 AM
+        Calendar twoDaysLaterCalendar1 = Calendar.getInstance(tz, en_US);
+        twoDaysLaterCalendar1.set(2011, Calendar.SEPTEMBER, 4, 10, 22, 0);
+        long twoDaysLater1 = twoDaysLaterCalendar1.getTimeInMillis();
+        assertEquals("In 2 days, 10:22 AM",
+                getRelativeDateTimeString(en_US, tz, twoDaysLater1, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+
+        // Sep 4, 2011, 10:24 AM
+        Calendar twoDaysLaterCalendar2 = Calendar.getInstance(tz, en_US);
+        twoDaysLaterCalendar2.set(2011, Calendar.SEPTEMBER, 4, 10, 24, 0);
+        long twoDaysLater2 = twoDaysLaterCalendar2.getTimeInMillis();
+        assertEquals("In 2 days, 10:24 AM",
+                getRelativeDateTimeString(en_US, tz, twoDaysLater2, now, MINUTE_IN_MILLIS,
+                        WEEK_IN_MILLIS, 0));
+    }
+
+    // b/19822016: show / hide the year based on the dates in the arguments.
+    @Test
+    public void test_bug19822016() throws Exception {
+        Locale en_US = new Locale("en", "US");
+        TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+        Calendar cal = Calendar.getInstance(tz, en_US);
+        // Feb 5, 2012 at 10:50 PST
+        cal.set(2012, Calendar.FEBRUARY, 5, 10, 50, 0);
+        long base = cal.getTimeInMillis();
+
+        assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0));
+        assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
+        assertEquals("11/27/2011, 10:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
+
+        assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
+        assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
+        assertEquals("January 6, 2012", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
+        assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
+        assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
+        assertEquals("December 7", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
+
+        // Feb 5, 2018 at 10:50 PST
+        cal.set(2018, Calendar.FEBRUARY, 5, 10, 50, 0);
+        base = cal.getTimeInMillis();
+        assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0));
+        assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
+        assertEquals("11/27/2017, 10:50 AM", getRelativeDateTimeString(en_US, tz,
+                base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
+
+        assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
+        assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
+        assertEquals("January 6, 2018", getRelativeTimeSpanString(en_US, tz,
+                base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
+        assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
+        assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
+        assertEquals("December 7", getRelativeTimeSpanString(en_US, tz,
+                base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
+    }
+
+    // Check for missing ICU data. http://b/25821045
+    @Test
+    public void test_bug25821045() {
+        final TimeZone tz = TimeZone.getDefault();
+        final long now = System.currentTimeMillis();
+        final long time = now + 1000;
+        final int minResolution = 1000 * 60;
+        final int transitionResolution = minResolution;
+        final int flags = FORMAT_ABBREV_RELATIVE;
+        // Exercise all available locales, forcing the ICU implementation to pre-cache the data.
+        // This
+        // highlights data issues. It can take a while.
+        for (Locale locale : Locale.getAvailableLocales()) {
+            // In (e.g.) ICU56 an exception is thrown on the first use for a locale if required
+            // data for
+            // the "other" plural is missing. It doesn't matter what is actually formatted.
+            try {
+                RelativeDateTimeFormatter.getRelativeDateTimeString(
+                        locale, tz, time, now, minResolution, transitionResolution, flags);
+            } catch (IllegalStateException e) {
+                fail("Failed to format for " + locale);
+            }
+        }
+    }
+
+    // Check for ICU data lookup fallback failure. http://b/25883157
+    @Test
+    public void test_bug25883157() {
+        final Locale locale = new Locale("en", "GB");
+        final TimeZone tz = TimeZone.getTimeZone("GMT");
+
+        final Calendar cal = Calendar.getInstance(tz, locale);
+        cal.set(2015, Calendar.JUNE, 19, 12, 0, 0);
+
+        final long base = cal.getTimeInMillis();
+        final long time = base + 2 * WEEK_IN_MILLIS;
+
+        assertEquals("In 2 wk", getRelativeTimeSpanString(
+                locale, tz, time, base, WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+    }
+
+    // http://b/63745717
+    @Test
+    public void test_combineDateAndTime_apostrophe() {
+        final Locale locale = new Locale("fr");
+        android.icu.text.RelativeDateTimeFormatter icuFormatter =
+                android.icu.text.RelativeDateTimeFormatter.getInstance(locale);
+        assertEquals("D à T", icuFormatter.combineDateAndTime("D", "T"));
+        // Ensure single quote ' and curly braces {} are not interpreted in input values.
+        assertEquals("D'x' à T{0}", icuFormatter.combineDateAndTime("D'x'", "T{0}"));
+    }
+}
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 702f2fa..c36f106 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -691,18 +691,57 @@
     @Test
     public void testRequestedState() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+
+            // The modified state can be controlled when we have control.
             mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
             mController.hide(statusBars());
             assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
-            mController.onControlsChanged(new InsetsSourceControl[0]);
+
+            // The modified state won't be changed while losing control.
+            mController.onControlsChanged(null /* activeControls */);
             assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+            // The modified state won't be changed while state changed while we don't have control.
             InsetsState newState = new InsetsState(mController.getState(), true /* copySource */);
             mController.onStateChanged(newState);
             assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+            // The modified state won't be changed while controlling an insets without having the
+            // control.
             mController.show(statusBars());
             assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+            // The modified state can be updated while gaining control.
             mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
             assertTrue(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+            // The modified state can still be updated if the local state and the requested state
+            // are the same.
+            mController.onControlsChanged(null /* activeControls */);
+            mController.hide(statusBars());
+            newState = new InsetsState(mController.getState(), true /* copySource */);
+            newState.getSource(ITYPE_STATUS_BAR).setVisible(false);
+            mController.onStateChanged(newState);
+            mController.onControlsChanged(createSingletonControl(ITYPE_STATUS_BAR));
+            assertFalse(mTestHost.getModifiedState().peekSource(ITYPE_STATUS_BAR).isVisible());
+
+            // The modified state will always be updated while receiving IME control if IME is
+            // requested visible.
+            mController.getSourceConsumer(ITYPE_IME).show(false /* fromIme */);
+            newState = new InsetsState(mController.getState(), true /* copySource */);
+            newState.getSource(ITYPE_IME).setVisible(true);
+            newState.getSource(ITYPE_IME).setFrame(1, 2, 3, 4);
+            mController.onStateChanged(newState);
+            mController.onControlsChanged(createSingletonControl(ITYPE_IME));
+            assertEquals(newState.getSource(ITYPE_IME),
+                    mTestHost.getModifiedState().peekSource(ITYPE_IME));
+            newState = new InsetsState(mController.getState(), true /* copySource */);
+            newState.getSource(ITYPE_IME).setVisible(true);
+            newState.getSource(ITYPE_IME).setFrame(5, 6, 7, 8);
+            mController.onStateChanged(newState);
+            mController.onControlsChanged(createSingletonControl(ITYPE_IME));
+            assertEquals(newState.getSource(ITYPE_IME),
+                    mTestHost.getModifiedState().peekSource(ITYPE_IME));
         });
     }
 
diff --git a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
index 76aa93f..edf473e 100644
--- a/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/StateMachineTest.java
@@ -16,27 +16,25 @@
 
 package com.android.internal.util;
 
-import java.util.Collection;
-import java.util.Iterator;
-
 import android.os.Debug;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
 import android.os.test.TestLooper;
-
-import android.test.suitebuilder.annotation.Suppress;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.internal.util.StateMachine.LogRec;
-
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import com.android.internal.util.StateMachine.LogRec;
+
 import junit.framework.TestCase;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.Iterator;
+
 /**
  * Test for StateMachine.
  */
@@ -2013,4 +2011,12 @@
     private static void tloge(String s) {
         Log.e(TAG, s);
     }
+
+    public void testDumpDoesNotThrowNpeAfterQuit() {
+        final Hsm1 sm = Hsm1.makeHsm1();
+        sm.quitNow();
+        final StringWriter stringWriter = new StringWriter();
+        final PrintWriter printWriter = new PrintWriter(stringWriter);
+        sm.dump(null, printWriter, new String[0]);
+    }
 }
diff --git a/data/etc/preinstalled-packages-platform-overlays.xml b/data/etc/preinstalled-packages-platform-overlays.xml
index ecd7d40..84c1897a2 100644
--- a/data/etc/preinstalled-packages-platform-overlays.xml
+++ b/data/etc/preinstalled-packages-platform-overlays.xml
@@ -19,32 +19,250 @@
 <config>
     <install-in-user-type package="com.android.internal.display.cutout.emulation.corner">
         <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
     <install-in-user-type package="com.android.internal.display.cutout.emulation.double">
         <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.display.cutout.emulation.hole">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
     <install-in-user-type package="com.android.internal.display.cutout.emulation.tall">
         <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
-    <install-in-user-type package="com.android.internal.systemui.navbar.gestural">
+    <install-in-user-type package="com.android.internal.display.cutout.emulation.waterfall">
         <install-in user-type="FULL" />
-    </install-in-user-type>
-    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_extra_wide_back">
-        <install-in user-type="FULL" />
-    </install-in-user-type>
-    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_narrow_back">
-        <install-in user-type="FULL" />
-    </install-in-user-type>
-    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_wide_back">
-        <install-in user-type="FULL" />
-    </install-in-user-type>
-    <install-in-user-type package="com.android.internal.systemui.navbar.threebutton">
-        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
     <install-in-user-type package="com.android.internal.systemui.navbar.twobutton">
         <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.systemui.navbar.threebutton">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.systemui.navbar.gestural">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_extra_wide_back">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_narrow_back">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.internal.systemui.navbar.gestural_wide_back">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
     <install-in-user-type package="com.android.internal.systemui.onehanded.gestural">
         <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+     <install-in-user-type package="com.android.theme.color.amethyst">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.aquamarine">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.black">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.carbon">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.cinnamon">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.green">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.ocean">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.orchid">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.palette">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.purple">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.sand">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.space">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.color.tangerine">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.font.notoserifsource">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.circular.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.circular.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.circular.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.circular.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.circular.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.filled.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.filled.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.filled.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.filled.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.filled.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.kai.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.kai.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.kai.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.kai.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.kai.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.rounded.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.rounded.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.rounded.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.rounded.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.rounded.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.sam.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.sam.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.sam.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.sam.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.sam.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.victor.android">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.victor.launcher">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.victor.settings">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.victor.systemui">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon_pack.victor.themepicker">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.pebble">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.roundedrect">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.squircle">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.taperedrect">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.teardrop">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
+    </install-in-user-type>
+    <install-in-user-type package="com.android.theme.icon.vessel">
+        <install-in user-type="FULL" />
+        <install-in user-type="PROFILE" />
     </install-in-user-type>
 </config>
diff --git a/diff b/diff
new file mode 100644
index 0000000..5c75d88
--- /dev/null
+++ b/diff
@@ -0,0 +1,25 @@
+diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+index fc43882..832dc91 100644
+--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
++++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+@@ -67,6 +67,7 @@ import java.util.Arrays;
+ import java.util.HashSet;
+ import java.util.List;
+ import java.util.Set;
++import java.util.NoSuchElementException;
+ 
+ /**
+  * This class represents an accessibility client - either an AccessibilityService or a UiAutomation.
+@@ -978,7 +979,11 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
+                 /* ignore */
+         }
+         if (mService != null) {
+-            mService.unlinkToDeath(this, 0);
++            try {
++                mService.unlinkToDeath(this, 0);
++            }catch(NoSuchElementException e) {
++                Slog.e(LOG_TAG, "Failed unregistering death link");
++            }
+             mService = null;
+         }
+ 
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index f502fc3..14a297f 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -39,29 +39,20 @@
     glScissor(clip.fLeft, y, clip.width(), height);
 }
 
-static bool GetFboDetails(SkCanvas* canvas, GLuint* outFboID, SkISize* outFboSize) {
+static void GetFboDetails(SkCanvas* canvas, GLuint* outFboID, SkISize* outFboSize) {
     GrRenderTargetContext* renderTargetContext =
             canvas->internal_private_accessTopLayerRenderTargetContext();
-    if (!renderTargetContext) {
-        ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw");
-        return false;
-    }
+    LOG_ALWAYS_FATAL_IF(!renderTargetContext, "Failed to retrieve GrRenderTargetContext");
 
     GrRenderTarget* renderTarget = renderTargetContext->accessRenderTarget();
-    if (!renderTarget) {
-        ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw");
-        return false;
-    }
+    LOG_ALWAYS_FATAL_IF(!renderTarget, "accessRenderTarget failed");
 
     GrGLFramebufferInfo fboInfo;
-    if (!renderTarget->getBackendRenderTarget().getGLFramebufferInfo(&fboInfo)) {
-        ALOGW("Unable to extract renderTarget info from canvas; aborting GLFunctor draw");
-        return false;
-    }
+    LOG_ALWAYS_FATAL_IF(!renderTarget->getBackendRenderTarget().getGLFramebufferInfo(&fboInfo),
+        "getGLFrameBufferInfo failed");
 
     *outFboID = fboInfo.fFBOID;
     *outFboSize = SkISize::Make(renderTargetContext->width(), renderTargetContext->height());
-    return true;
 }
 
 void GLFunctorDrawable::onDraw(SkCanvas* canvas) {
@@ -76,11 +67,12 @@
         return;
     }
 
+    // flush will create a GrRenderTarget if not already present.
+    canvas->flush();
+
     GLuint fboID = 0;
     SkISize fboSize;
-    if (!GetFboDetails(canvas, &fboID, &fboSize)) {
-        return;
-    }
+    GetFboDetails(canvas, &fboID, &fboSize);
 
     SkIRect surfaceBounds = canvas->internal_private_getTopLayerBounds();
     SkIRect clipBounds = canvas->getDeviceClipBounds();
@@ -134,7 +126,6 @@
 
     // ensure that the framebuffer that the webview will render into is bound before we clear
     // the stencil and/or draw the functor.
-    canvas->flush();
     glViewport(0, 0, info.width, info.height);
     glBindFramebuffer(GL_FRAMEBUFFER, fboID);
 
diff --git a/location/java/android/location/package.html b/location/java/android/location/package.html
index 2355e72..20c5c54 100644
--- a/location/java/android/location/package.html
+++ b/location/java/android/location/package.html
@@ -6,7 +6,7 @@
 <p class="warning">
 <strong>This API is not the recommended method for accessing Android location.</strong><br>
 The
-<a href="{@docRoot}reference/com/google/android/gms/location/package-summary.html">Google Location Services API</a>,
+<a href="https://developers.google.com/android/reference/com/google/android/gms/location/package-summary">Google Location Services API</a>,
 part of Google Play services, is the preferred way to add location-awareness to
 your app. It offers a simpler API, higher accuracy, low-power geofencing, and
 more. If you are currently using the android.location API, you are strongly
diff --git a/location/java/com/android/internal/location/ILocationProviderManager.aidl b/location/java/com/android/internal/location/ILocationProviderManager.aidl
index 4036d63..2a6cef8 100644
--- a/location/java/com/android/internal/location/ILocationProviderManager.aidl
+++ b/location/java/com/android/internal/location/ILocationProviderManager.aidl
@@ -25,15 +25,8 @@
  * @hide
  */
 interface ILocationProviderManager {
-
-    void onSetAttributionTag(String attributionTag);
-
-    @UnsupportedAppUsage
+    void onSetIdentity(@nullable String packageName, @nullable String attributionTag);
     void onSetAllowed(boolean allowed);
-
-    @UnsupportedAppUsage
     void onSetProperties(in ProviderProperties properties);
-
-    @UnsupportedAppUsage
     void onReportLocation(in Location location);
 }
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 25b4090..7a3a4b2 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -79,7 +79,8 @@
     public static final String FUSED_PROVIDER = LocationManager.FUSED_PROVIDER;
 
     final String mTag;
-    final String mAttributionTag;
+    @Nullable final String mPackageName;
+    @Nullable final String mAttributionTag;
     final IBinder mBinder;
 
     /**
@@ -93,8 +94,7 @@
     protected final ILocationManager mLocationManager;
 
     // write locked on mBinder, read lock is optional depending on atomicity requirements
-    @Nullable
-    volatile ILocationProviderManager mManager;
+    @Nullable volatile ILocationProviderManager mManager;
     volatile ProviderProperties mProperties;
     volatile boolean mAllowed;
 
@@ -116,6 +116,7 @@
     public LocationProviderBase(Context context, String tag,
             ProviderPropertiesUnbundled properties) {
         mTag = tag;
+        mPackageName = context != null ? context.getPackageName() : null;
         mAttributionTag = context != null ? context.getAttributionTag() : null;
         mBinder = new Service();
 
@@ -332,8 +333,8 @@
         public void setLocationProviderManager(ILocationProviderManager manager) {
             synchronized (mBinder) {
                 try {
-                    if (mAttributionTag != null) {
-                        manager.onSetAttributionTag(mAttributionTag);
+                    if (mPackageName != null || mAttributionTag != null) {
+                        manager.onSetIdentity(mPackageName, mAttributionTag);
                     }
                     manager.onSetProperties(mProperties);
                     manager.onSetAllowed(mAllowed);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
index ebd7658..942f908 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraBinderTest.java
@@ -167,34 +167,6 @@
         }
     }
 
-    @SmallTest
-    public void testConnectLegacy() throws Exception {
-        final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
-        for (int cameraId = 0; cameraId < mUtils.getGuessedNumCameras(); ++cameraId) {
-            ICamera cameraUser = null;
-            ICameraClient dummyCallbacks = new DummyCameraClient();
-
-            String clientPackageName = getContext().getPackageName();
-
-            try {
-                cameraUser = mUtils.getCameraService()
-                        .connectLegacy(dummyCallbacks, cameraId, CAMERA_HAL_API_VERSION_1_0,
-                                clientPackageName,
-                                ICameraService.USE_CALLING_UID);
-                assertNotNull(String.format("Camera %s was null", cameraId), cameraUser);
-
-                Log.v(TAG, String.format("Camera %s connected as HAL1 legacy device", cameraId));
-            } catch (RuntimeException e) {
-                // Not all camera device support openLegacy.
-                Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e);
-            } finally {
-                if (cameraUser != null) {
-                    cameraUser.disconnect();
-                }
-            }
-        }
-    }
-
     static class DummyCameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
 
         /*
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraOpenTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraOpenTest.java
deleted file mode 100644
index 14bbe44..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraOpenTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.mediaframeworktest.unit;
-
-import android.hardware.Camera;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-/**
- * <pre>
- * adb shell am instrument \
- *      -e class 'com.android.mediaframeworktest.unit.CameraOpenTest' \
- *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
- * </pre>
- */
-public class CameraOpenTest extends junit.framework.TestCase {
-    private static String TAG = "CameraOpenTest";
-
-    private Camera mCamera;
-
-    /**
-     * Test @hide android.hardware.Camera#openLegacy API that cannot be tested in CTS.
-     */
-    @SmallTest
-    public void testOpenLegacy() {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            try {
-                mCamera.openLegacy(id, Camera.CAMERA_HAL_API_VERSION_1_0);
-            } catch (RuntimeException e) {
-                Log.i(TAG, "Unable to open camera as HAL1 legacy camera device " + e);
-            } finally {
-                if (mCamera != null) {
-                    mCamera.release();
-                }
-            }
-        }
-    }
-}
diff --git a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingBenchmark.java b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingBenchmark.java
index ee06720..de5ed54 100644
--- a/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingBenchmark.java
+++ b/media/tests/MediaTranscodingTest/src/com/android/mediatranscodingtest/MediaTranscodingBenchmark.java
@@ -62,7 +62,7 @@
     // TODO(hkuang): Change this to query from MediaCodecInfo.CodecCapabilities for different
     // resolution.
     private static final int MINIMUM_TRANSCODING_FPS = 80;
-    private static final int LOOP_COUNT = 10;
+    private static final int LOOP_COUNT = 3;
     // Default Setting for transcoding to H.264.
     private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static final int BIT_RATE = 20000000;            // 20Mbps
@@ -109,6 +109,7 @@
 
         MediaTranscodingTestUtil.VideoFileInfo info =
                 MediaTranscodingTestUtil.extractVideoFileInfo(mContext, getUri(sourceFileName));
+
         int timeoutSeconds = calMaxTranscodingWaitTimeSeconds(info.mNumVideoFrames,
                 MINIMUM_TRANSCODING_FPS);
         Log.d(TAG, "Start Transcoding " + info.toString() + " " + timeoutSeconds);
@@ -151,8 +152,9 @@
 
     // Calculate the maximum wait time based on minimum transcoding throughput and frame number.
     private int calMaxTranscodingWaitTimeSeconds(int numberFrames, int minTranscodingFps) {
-        int waitTimeSeconds =  numberFrames / minTranscodingFps;
-        // If waitTimeSeconds is 0, wait for 1 seconds at least.
+        float waitTime =  (float) numberFrames / (float) minTranscodingFps;
+        // If waitTimeSeconds is 0, wait for 1 second at least.
+        int waitTimeSeconds = (int) Math.ceil(waitTime);
         return waitTimeSeconds == 0 ? 1 : waitTimeSeconds;
     }
 
@@ -171,6 +173,9 @@
         transcode(testVideoName, transcodedVideoName);
     }
 
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+    /*
     @Test
     public void testBenchmarkingAVCToAVCWith66FramesWithAudio() throws Exception {
         String videoNameWithoutExtension = "video_1920x1080_66frame_h264_22Mbps_30fps_aac";
@@ -178,5 +183,105 @@
         String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
 
         transcode(testVideoName, transcodedVideoName);
+    }*/
+
+    @Test
+    public void testBenchmarkingAVCToAVCWith361FramesWithoutAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_361frame_h264_22Mbps_30fps";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
     }
+
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+    /*@Test
+    public void testBenchmarkingAVCToAVCWith361FramesWithAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_361frame_h264_22Mbps_30fps_aac";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }*/
+
+    @Test
+    public void testBenchmarkingAVCToAVCWith943FramesWithoutAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_943frame_h264_22Mbps_30fps";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }
+
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+   /* @Test
+    public void testBenchmarkingAVCToAVCWith943FramesWithAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_943frame_h264_22Mbps_30fps_aac";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }*/
+
+    @Test
+    public void testBenchmarkingAVCToAVCWith1822FramesWithoutAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_1822frame_h264_22Mbps_30fps";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }
+
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+    /*@Test
+    public void testBenchmarkingAVCToAVCWith1822FramesWithAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_1822frame_h264_22Mbps_30fps_aac";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }*/
+
+    @Test
+    public void testBenchmarkingAVCToAVCWith3648FramesWithoutAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_3648frame_h264_22Mbps_30fps";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }
+
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+    /*@Test
+    public void testBenchmarkingAVCToAVCWith3648FramesWithAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_3648frame_h264_22Mbps_30fps_aac";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }*/
+
+    @Test
+    public void testBenchmarkingAVCToAVCWith11042FramesWithoutAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_11042frame_h264_22Mbps_30fps";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }
+
+    // TODO(hkuang): Enable this after b/160268606 is fixed. Transcoding video with audio takes way
+    //  more long time that leads to timeout failure.
+    /*@Test
+    public void testBenchmarkingAVCToAVCWith11042FramesWithAudio() throws Exception {
+        String videoNameWithoutExtension = "video_1920x1080_11042frame_h264_22Mbps_30fps_aac";
+        String testVideoName = videoNameWithoutExtension + ".mp4";
+        String transcodedVideoName = videoNameWithoutExtension + "_transcode.mp4";
+
+        transcode(testVideoName, transcodedVideoName);
+    }*/
 }
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index 34f16f8..c14f23f 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -45194,7 +45194,7 @@
   public abstract class CellLocation {
     ctor public CellLocation();
     method public static android.telephony.CellLocation getEmpty();
-    method public static void requestLocationUpdate();
+    method @Deprecated public static void requestLocationUpdate();
   }
 
   public abstract class CellSignalStrength {
@@ -47256,6 +47256,7 @@
   }
 
   public static class MmTelFeature.MmTelCapabilities {
+    method public final boolean isCapable(int);
     field public static final int CAPABILITY_TYPE_SMS = 8; // 0x8
     field public static final int CAPABILITY_TYPE_UT = 4; // 0x4
     field public static final int CAPABILITY_TYPE_VIDEO = 2; // 0x2
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index b693b0e..b41ab93 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -11118,7 +11118,6 @@
     ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
-    method public final boolean isCapable(int);
     method public final void removeCapabilities(int);
   }
 
diff --git a/non-updatable-api/system-removed.txt b/non-updatable-api/system-removed.txt
index ab4c6d1..0c02c43 100644
--- a/non-updatable-api/system-removed.txt
+++ b/non-updatable-api/system-removed.txt
@@ -165,11 +165,6 @@
 
 package android.telephony {
 
-  public final class PreciseDataConnectionState implements android.os.Parcelable {
-    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
-    method @Deprecated public int getDataConnectionNetworkType();
-  }
-
   public class TelephonyManager {
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall();
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall();
diff --git a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
index ed7f3df..8efbad6 100644
--- a/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
+++ b/packages/FusedLocation/test/src/com/android/location/fused/tests/FusedLocationServiceTest.java
@@ -199,7 +199,7 @@
         }
 
         @Override
-        public void onSetAttributionTag(String attributionTag) {
+        public void onSetIdentity(String packageName, String attributionTag) {
 
         }
 
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 376c2e7..0042321 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -37,7 +37,7 @@
     <string name="wifi_no_internet" msgid="1774198889176926299">"Ezin da konektatu Internetera"</string>
     <string name="saved_network" msgid="7143698034077223645">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioak gorde du"</string>
     <string name="connected_via_network_scorer" msgid="7665725527352893558">"%1$s bidez automatikoki konektatuta"</string>
-    <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sareen balorazioen hornitzailearen bidez"</string>
+    <string name="connected_via_network_scorer_default" msgid="7973529709744526285">"Automatikoki konektatuta sare-balorazioen hornitzailearen bidez"</string>
     <string name="connected_via_passpoint" msgid="7735442932429075684">"%1$s bidez konektatuta"</string>
     <string name="connected_via_app" msgid="3532267661404276584">"<xliff:g id="NAME">%1$s</xliff:g> bidez konektatuta"</string>
     <string name="available_via_passpoint" msgid="1716000261192603682">"%1$s bidez erabilgarri"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 8968340..c5e66be 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -1117,14 +1117,16 @@
      * Returns the display title for the AccessPoint, such as for an AccessPointPreference's title.
      */
     public String getTitle() {
-        if (isPasspoint()) {
+        if (isPasspoint() && !TextUtils.isEmpty(mConfig.providerFriendlyName)) {
             return mConfig.providerFriendlyName;
-        } else if (isPasspointConfig()) {
+        } else if (isPasspointConfig() && !TextUtils.isEmpty(mProviderFriendlyName)) {
             return mProviderFriendlyName;
-        } else if (isOsuProvider()) {
+        } else if (isOsuProvider() && !TextUtils.isEmpty(mOsuProvider.getFriendlyName())) {
             return mOsuProvider.getFriendlyName();
-        } else {
+        } else if (!TextUtils.isEmpty(getSsidStr())) {
             return getSsidStr();
+        } else {
+            return "";
         }
     }
 
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index bcabec8..46ecbd4 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -148,6 +148,17 @@
     }
 
     @Test
+    public void testCompareTo_GivesNull() {
+        WifiConfiguration spyConfig = spy(new WifiConfiguration());
+
+        when(spyConfig.isPasspoint()).thenReturn(true);
+        spyConfig.providerFriendlyName = null;
+        AccessPoint passpointAp = new AccessPoint(mContext, spyConfig);
+
+        assertThat(passpointAp.getTitle()).isEqualTo("");
+    }
+
+    @Test
     public void testCompareTo_GivesActiveBeforeInactive() {
         AccessPoint activeAp = new TestAccessPointBuilder(mContext).setActive(true).build();
         AccessPoint inactiveAp = new TestAccessPointBuilder(mContext).setActive(false).build();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index 94d95f06..68f162e 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -27,7 +27,9 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -36,6 +38,7 @@
 import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
 import android.media.RoutingSessionInfo;
+import android.media.session.MediaSessionManager;
 
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
@@ -68,6 +71,8 @@
     private LocalBluetoothManager mLocalBluetoothManager;
     @Mock
     private MediaManager.MediaDeviceCallback mCallback;
+    @Mock
+    private MediaSessionManager mMediaSessionManager;
 
     private InfoMediaManager mInfoMediaManager;
     private Context mContext;
@@ -76,8 +81,10 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = spy(RuntimeEnvironment.application);
 
+        doReturn(mMediaSessionManager).when(mContext).getSystemService(
+                Context.MEDIA_SESSION_SERVICE);
         mInfoMediaManager =
                 new InfoMediaManager(mContext, TEST_PACKAGE_NAME, null, mLocalBluetoothManager);
         mShadowRouter2Manager = ShadowRouter2Manager.getShadow();
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 780c19b..d52e247 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -28,15 +28,15 @@
     <string name="battery_low_percent_format" msgid="4276661262843170964">"僅剩 <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid" msgid="3985614339605686167">"電力剩餘 <xliff:g id="PERCENTAGE">%1$s</xliff:g>，根據你的使用情形，剩餘時間大約還有 <xliff:g id="TIME">%2$s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid_short" msgid="5917433188456218857">"電力剩餘 <xliff:g id="PERCENTAGE">%1$s</xliff:g>，剩餘時間大約還有 <xliff:g id="TIME">%2$s</xliff:g>"</string>
-    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"僅剩 <xliff:g id="PERCENTAGE">%s</xliff:g>。節約耗電量模式已開啟。"</string>
+    <string name="battery_low_percent_format_saver_started" msgid="4968468824040940688">"僅剩 <xliff:g id="PERCENTAGE">%s</xliff:g>。省電模式已開啟。"</string>
     <string name="invalid_charger" msgid="4370074072117767416">"無法透過 USB 充電，請使用裝置隨附的充電器。"</string>
     <string name="invalid_charger_title" msgid="938685362320735167">"無法透過 USB 充電"</string>
     <string name="invalid_charger_text" msgid="2339310107232691577">"使用裝置隨附的充電器"</string>
     <string name="battery_low_why" msgid="2056750982959359863">"設定"</string>
-    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"要開啟節約耗電量模式嗎？"</string>
-    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"關於節約耗電量功能"</string>
+    <string name="battery_saver_confirmation_title" msgid="1234998463717398453">"要開啟省電模式嗎？"</string>
+    <string name="battery_saver_confirmation_title_generic" msgid="2299231884234959849">"關於省電模式"</string>
     <string name="battery_saver_confirmation_ok" msgid="5042136476802816494">"開啟"</string>
-    <string name="battery_saver_start_action" msgid="4553256017945469937">"開啟節約耗電量模式"</string>
+    <string name="battery_saver_start_action" msgid="4553256017945469937">"開啟省電模式"</string>
     <string name="status_bar_settings_settings_button" msgid="534331565185171556">"設定"</string>
     <string name="status_bar_settings_wifi_button" msgid="7243072479837270946">"Wi-Fi"</string>
     <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"自動旋轉螢幕"</string>
@@ -421,7 +421,7 @@
     <string name="quick_settings_night_secondary_label_on_at" msgid="3584738542293528235">"<xliff:g id="TIME">%s</xliff:g> 開啟"</string>
     <string name="quick_settings_secondary_label_until" msgid="1883981263191927372">"<xliff:g id="TIME">%s</xliff:g> 關閉"</string>
     <string name="quick_settings_ui_mode_night_label" msgid="1398928270610780470">"深色主題"</string>
-    <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"節約耗電量"</string>
+    <string name="quick_settings_dark_mode_secondary_label_battery_saver" msgid="4990712734503013251">"省電模式"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at_sunset" msgid="6017379738102015710">"於日落時開啟"</string>
     <string name="quick_settings_dark_mode_secondary_label_until_sunrise" msgid="4404885070316716472">"於日出時關閉"</string>
     <string name="quick_settings_dark_mode_secondary_label_on_at" msgid="5128758823486361279">"開啟時間：<xliff:g id="TIME">%s</xliff:g>"</string>
@@ -499,9 +499,9 @@
     <string name="user_remove_user_title" msgid="9124124694835811874">"要移除使用者嗎？"</string>
     <string name="user_remove_user_message" msgid="6702834122128031833">"系統將刪除這個使用者的所有應用程式和資料。"</string>
     <string name="user_remove_user_remove" msgid="8387386066949061256">"移除"</string>
-    <string name="battery_saver_notification_title" msgid="8419266546034372562">"節約耗電量模式已開啟"</string>
+    <string name="battery_saver_notification_title" msgid="8419266546034372562">"省電模式已開啟"</string>
     <string name="battery_saver_notification_text" msgid="2617841636449016951">"降低效能並限制背景數據傳輸"</string>
-    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"關閉節約耗電量模式"</string>
+    <string name="battery_saver_notification_action_text" msgid="6022091913807026887">"關閉省電模式"</string>
     <string name="media_projection_dialog_text" msgid="1755705274910034772">"在錄製或投放內容時，「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取畫面上顯示的任何資訊或裝置播放的任何內容，包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
     <string name="media_projection_dialog_service_text" msgid="958000992162214611">"在錄製或投放內容時，提供這項功能的服務可存取畫面上顯示的任何資訊或裝置播放的任何內容，包括密碼、付款詳情、相片、訊息和你播放的音訊。"</string>
     <string name="media_projection_dialog_service_title" msgid="2888507074107884040">"要開始錄製或投放內容嗎？"</string>
@@ -775,8 +775,8 @@
       <item quantity="one">%d 分鐘</item>
     </plurals>
     <string name="battery_panel_title" msgid="5931157246673665963">"電池用量"</string>
-    <string name="battery_detail_charging_summary" msgid="8821202155297559706">"充電時無法使用節約耗電量模式"</string>
-    <string name="battery_detail_switch_title" msgid="6940976502957380405">"節約耗電量"</string>
+    <string name="battery_detail_charging_summary" msgid="8821202155297559706">"充電時無法使用省電模式"</string>
+    <string name="battery_detail_switch_title" msgid="6940976502957380405">"省電模式"</string>
     <string name="battery_detail_switch_summary" msgid="3668748557848025990">"降低效能並限制背景資料傳輸"</string>
     <string name="keyboard_key_button_template" msgid="8005673627272051429">"<xliff:g id="NAME">%1$s</xliff:g> 按鈕"</string>
     <string name="keyboard_key_home" msgid="3734400625170020657">"Home 鍵"</string>
@@ -988,11 +988,11 @@
     <string name="slice_permission_checkbox" msgid="4242888137592298523">"允許「<xliff:g id="APP">%1$s</xliff:g>」顯示任何應用程式的區塊"</string>
     <string name="slice_permission_allow" msgid="6340449521277951123">"允許"</string>
     <string name="slice_permission_deny" msgid="6870256451658176895">"拒絕"</string>
-    <string name="auto_saver_title" msgid="6873691178754086596">"輕觸即可排定節約耗電量模式自動開啟的情況"</string>
+    <string name="auto_saver_title" msgid="6873691178754086596">"輕觸即可排定省電模式自動開啟的情況"</string>
     <string name="auto_saver_text" msgid="3214960308353838764">"在電池電量即將耗盡時開啟"</string>
     <string name="no_auto_saver_action" msgid="7467924389609773835">"不用了，謝謝"</string>
-    <string name="auto_saver_enabled_title" msgid="4294726198280286333">"已按照排定開啟節約耗電量模式"</string>
-    <string name="auto_saver_enabled_text" msgid="7889491183116752719">"節約耗電量模式會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
+    <string name="auto_saver_enabled_title" msgid="4294726198280286333">"已按照排定開啟省電模式"</string>
+    <string name="auto_saver_enabled_text" msgid="7889491183116752719">"省電模式會在電量低於 <xliff:g id="PERCENTAGE">%d</xliff:g>%% 時自動開啟。"</string>
     <string name="open_saver_setting_action" msgid="2111461909782935190">"設定"</string>
     <string name="auto_saver_okay_action" msgid="7815925750741935386">"我知道了"</string>
     <string name="heap_dump_tile_name" msgid="2464189856478823046">"傾印 SysUI 記憶體快照"</string>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 8212d61..a56f6f5 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -92,6 +92,8 @@
 
     <item type="id" name="requires_remeasuring"/>
 
+    <item type="id" name="secondary_home_handle" />
+
     <!-- Whether the icon is from a notification for which targetSdk < L -->
     <item type="id" name="icon_is_pre_L"/>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 82c111f..454ffc8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2422,17 +2422,26 @@
 
     <!-- Title for notification & dialog that the user's phone last shut down because it got too hot. [CHAR LIMIT=40] -->
     <string name="thermal_shutdown_title">Phone turned off due to heat</string>
-    <!-- Message body for notification that user's phone last shut down because it got too hot. [CHAR LIMIT=100] -->
-    <string name="thermal_shutdown_message">Your phone is now running normally</string>
-    <!-- Text body for dialog alerting user that their phone last shut down because it got too hot. [CHAR LIMIT=450] -->
+    <!-- Message body for notification that user's phone last shut down because it got too hot. [CHAR LIMIT=120] -->
+    <string name="thermal_shutdown_message">Your phone is now running normally.\nTap for more info</string>
+    <!-- Text body for dialog alerting user that their phone last shut down because it got too hot. [CHAR LIMIT=500] -->
     <string name="thermal_shutdown_dialog_message">Your phone was too hot, so it turned off to cool down. Your phone is now running normally.\n\nYour phone may get too hot if you:\n\t&#8226; Use resource-intensive apps (such as gaming, video, or navigation apps)\n\t&#8226; Download or upload large files\n\t&#8226; Use your phone in high temperatures</string>
+    <!-- Text help link for care instructions for overheating devices [CHAR LIMIT=40] -->
+    <string name="thermal_shutdown_dialog_help_text">See care steps</string>
+    <!-- URL for care instructions for overheating devices -->
+    <string name="thermal_shutdown_dialog_help_url" translatable="false"></string>
 
     <!-- Title for notification (and dialog) that user's phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=30] -->
     <string name="high_temp_title">Phone is getting warm</string>
-    <!-- Message body for notification that user's phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=100] -->
-    <string name="high_temp_notif_message">Some features limited while phone cools down</string>
-    <!-- Text body for dialog alerting user that their phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=300] -->
+    <!-- Message body for notification that user's phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=120] -->
+    <string name="high_temp_notif_message">Some features limited while phone cools down.\nTap for more info</string>
+    <!-- Text body for dialog alerting user that their phone has reached a certain temperature and may start to slow down in order to cool down. [CHAR LIMIT=350] -->
     <string name="high_temp_dialog_message">Your phone will automatically try to cool down. You can still use your phone, but it may run slower.\n\nOnce your phone has cooled down, it will run normally.</string>
+    <!-- Text help link for care instructions for overheating devices [CHAR LIMIT=40] -->
+    <string name="high_temp_dialog_help_text">See care steps</string>
+    <!-- URL for care instructions for overheating devices -->
+    <string name="high_temp_dialog_help_url" translatable="false"></string>
+
     <!-- Title for alarm dialog alerting user the usb adapter has reached a certain temperature that should disconnect charging cable immediately. [CHAR LIMIT=30] -->
     <string name="high_temp_alarm_title">Unplug charger</string>
     <!-- Text body for dialog alerting user the usb adapter has reached a certain temperature that should disconnect charging cable immediately. [CHAR LIMIT=300] -->
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
index 82e6251..2985a61 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SyncRtSurfaceTransactionApplierCompat.java
@@ -46,6 +46,7 @@
     public static final int FLAG_CORNER_RADIUS = 1 << 4;
     public static final int FLAG_BACKGROUND_BLUR_RADIUS = 1 << 5;
     public static final int FLAG_VISIBILITY = 1 << 6;
+    public static final int FLAG_RELATIVE_LAYER = 1 << 7;
 
     private static final int MSG_UPDATE_SEQUENCE_NUMBER = 0;
 
@@ -192,6 +193,8 @@
             Matrix matrix;
             Rect windowCrop;
             int layer;
+            SurfaceControl relativeTo;
+            int relativeLayer;
             boolean visible;
 
             /**
@@ -249,6 +252,18 @@
             }
 
             /**
+             * @param relativeTo The surface that's set relative layer to.
+             * @param relativeLayer The relative layer.
+             * @return this Builder
+             */
+            public Builder withRelativeLayerTo(SurfaceControl relativeTo, int relativeLayer) {
+                this.relativeTo = relativeTo;
+                this.relativeLayer = relativeLayer;
+                flags |= FLAG_RELATIVE_LAYER;
+                return this;
+            }
+
+            /**
              * @param radius the Radius for rounded corners to apply to the surface.
              * @return this Builder
              */
@@ -283,7 +298,7 @@
              */
             public SurfaceParams build() {
                 return new SurfaceParams(surface, flags, alpha, matrix, windowCrop, layer,
-                        cornerRadius, backgroundBlurRadius, visible);
+                        relativeTo, relativeLayer, cornerRadius, backgroundBlurRadius, visible);
             }
         }
 
@@ -297,21 +312,25 @@
          * @param windowCrop Crop to apply, only applied if not {@code null}
          */
         public SurfaceParams(SurfaceControlCompat surface, float alpha, Matrix matrix,
-                Rect windowCrop, int layer, float cornerRadius) {
+                Rect windowCrop, int layer, SurfaceControl relativeTo, int relativeLayer,
+                float cornerRadius) {
             this(surface.mSurfaceControl,
                     FLAG_ALL & ~(FLAG_VISIBILITY | FLAG_BACKGROUND_BLUR_RADIUS), alpha,
-                    matrix, windowCrop, layer, cornerRadius, 0 /* backgroundBlurRadius */, true);
+                    matrix, windowCrop, layer, relativeTo, relativeLayer, cornerRadius,
+                    0 /* backgroundBlurRadius */, true);
         }
 
         private SurfaceParams(SurfaceControl surface, int flags, float alpha, Matrix matrix,
-                Rect windowCrop, int layer, float cornerRadius, int backgroundBlurRadius,
-                boolean visible) {
+                Rect windowCrop, int layer, SurfaceControl relativeTo, int relativeLayer,
+                float cornerRadius, int backgroundBlurRadius, boolean visible) {
             this.flags = flags;
             this.surface = surface;
             this.alpha = alpha;
             this.matrix = new Matrix(matrix);
             this.windowCrop = windowCrop != null ? new Rect(windowCrop) : null;
             this.layer = layer;
+            this.relativeTo = relativeTo;
+            this.relativeLayer = relativeLayer;
             this.cornerRadius = cornerRadius;
             this.backgroundBlurRadius = backgroundBlurRadius;
             this.visible = visible;
@@ -327,6 +346,8 @@
         public final Matrix matrix;
         public final Rect windowCrop;
         public final int layer;
+        public final SurfaceControl relativeTo;
+        public final int relativeLayer;
         public final boolean visible;
 
         public void applyTo(SurfaceControl.Transaction t) {
@@ -355,6 +376,9 @@
                     t.hide(surface);
                 }
             }
+            if ((flags & FLAG_RELATIVE_LAYER) != 0) {
+                t.setRelativeLayer(surface, relativeTo, relativeLayer);
+            }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index e45cfe2..71969e0 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -228,6 +228,7 @@
 
     private final Context mContext;
     private final boolean mIsPrimaryUser;
+    private final boolean mIsAutomotive;
     private final StatusBarStateController mStatusBarStateController;
     HashMap<Integer, SimData> mSimDatas = new HashMap<>();
     HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
@@ -295,7 +296,7 @@
     private int mHardwareFingerprintUnavailableRetryCount = 0;
     private int mHardwareFaceUnavailableRetryCount = 0;
     private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms
-    private static final int HAL_ERROR_RETRY_MAX = 10;
+    private static final int HAL_ERROR_RETRY_MAX = 20;
 
     private final Runnable mCancelNotReceived = new Runnable() {
         @Override
@@ -682,7 +683,12 @@
         public void run() {
             Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
                     mHardwareFingerprintUnavailableRetryCount);
-            updateFingerprintListeningState();
+            if (mFpm.isHardwareDetected()) {
+                updateFingerprintListeningState();
+            } else if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
+                mHardwareFingerprintUnavailableRetryCount++;
+                mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
+            }
         }
     };
 
@@ -704,11 +710,7 @@
         }
 
         if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
-            if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
-                mHardwareFingerprintUnavailableRetryCount++;
-                mHandler.removeCallbacks(mRetryFingerprintAuthentication);
-                mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
-            }
+            mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
         }
 
         if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
@@ -1234,7 +1236,7 @@
     private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
             = new FingerprintManager.LockoutResetCallback() {
         @Override
-        public void onLockoutReset() {
+        public void onLockoutReset(int sensorId) {
             handleFingerprintLockoutReset();
         }
     };
@@ -1242,7 +1244,7 @@
     private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
             = new FaceManager.LockoutResetCallback() {
         @Override
-        public void onLockoutReset() {
+        public void onLockoutReset(int sensorId) {
             handleFaceLockoutReset();
         }
     };
@@ -1770,6 +1772,8 @@
             mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
         }
 
+        mIsAutomotive = isAutomotive();
+
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
         mUserManager = context.getSystemService(UserManager.class);
         mIsPrimaryUser = mUserManager.isPrimaryUser();
@@ -1838,7 +1842,7 @@
         if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
             return;
         }
-        mHandler.removeCallbacks(mRetryFingerprintAuthentication);
+
         boolean shouldListenForFingerprint = shouldListenForFingerprint();
         boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
                 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
@@ -2484,6 +2488,14 @@
                 .addCategory(Intent.CATEGORY_HOME);
         ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
                 0 /* flags */);
+
+        // TODO(b/160971249): Replace in the future by resolving activity as user.
+        if (resolveInfo == null && mIsAutomotive) {
+            Log.w(TAG, "resolveNeedsSlowUnlockTransition: returning false since activity "
+                    + "could not be resolved.");
+            return false;
+        }
+
         return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
     }
 
@@ -2554,6 +2566,10 @@
         return false;
     }
 
+    private boolean isAutomotive() {
+        return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+    }
+
     /**
      * Remove the given observer's callback.
      *
@@ -2990,5 +3006,8 @@
                 pw.println("    " + time + " " + model.toString());
             }
         }
+        if (mIsAutomotive) {
+            pw.println("  Running on Automotive build");
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
index 332a00d..398a2c9 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/MagnificationModeSwitch.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.accessibility;
 
+import android.annotation.NonNull;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.provider.Settings;
@@ -23,6 +24,7 @@
 import android.view.WindowManager;
 import android.widget.ImageView;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.R;
 
 /**
@@ -42,23 +44,36 @@
     private boolean mIsVisible = false;
 
     MagnificationModeSwitch(Context context) {
+        this(context, createView(context));
+    }
+
+    @VisibleForTesting
+    MagnificationModeSwitch(Context context, @NonNull ImageView imageView) {
         mContext = context;
         mWindowManager = (WindowManager) mContext.getSystemService(
                 Context.WINDOW_SERVICE);
         mParams = createLayoutParams();
-        mImageView = createView(mContext, mMagnificationMode);
+        mImageView = imageView;
+        applyResourcesValues();
         mImageView.setOnClickListener(
                 view -> {
                     removeButton();
                     toggleMagnificationMode();
                 });
+        mImageView.setImageResource(getIconResId(mMagnificationMode));
+    }
+
+    private void applyResourcesValues() {
+        final int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.magnification_switch_button_padding);
+        mImageView.setPadding(padding, padding, padding, padding);
     }
 
     void removeButton() {
-        mImageView.animate().cancel();
         if (!mIsVisible) {
             return;
         }
+        mImageView.animate().cancel();
         mWindowManager.removeView(mImageView);
         mIsVisible = false;
     }
@@ -72,7 +87,7 @@
             mWindowManager.addView(mImageView, mParams);
             mIsVisible = true;
         }
-
+        mImageView.setAlpha(1.0f);
         // TODO(b/143852371): use accessibility timeout as a delay.
         // Dismiss the magnification switch button after the button is displayed for a period of
         // time.
@@ -82,30 +97,29 @@
                 .setStartDelay(START_DELAY_MS)
                 .setDuration(DURATION_MS)
                 .withEndAction(
-                        () -> removeButton());
+                        () -> removeButton())
+                .start();
     }
 
     private void toggleMagnificationMode() {
         final int newMode =
                 mMagnificationMode ^ Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_ALL;
         mMagnificationMode = newMode;
+        mImageView.setImageResource(getIconResId(newMode));
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, newMode);
     }
 
-    private static ImageView createView(Context context, int mode) {
-        final int padding = context.getResources().getDimensionPixelSize(
-                R.dimen.magnification_switch_button_padding);
+    private static ImageView createView(Context context) {
         ImageView imageView  = new ImageView(context);
-        imageView.setImageResource(getIconResId(mode));
         imageView.setClickable(true);
         imageView.setFocusable(true);
-        imageView.setPadding(padding, padding, padding, padding);
         imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
         return imageView;
     }
 
-    private static int getIconResId(int mode) {
+    @VisibleForTesting
+    static int getIconResId(int mode) {
         return (mode == Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN)
                 ? R.drawable.ic_open_in_new_window
                 : R.drawable.ic_open_in_new_fullscreen;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index 97e97ff..04f2892 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -156,6 +156,7 @@
     }
 
     private void hideUdfpsOverlay() {
+        onFingerUp();
         mHandler.post(() -> {
             Log.v(TAG, "hideUdfpsOverlay | removing window");
             if (mIsOverlayShowing) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index dfc7d53..8190550 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -143,12 +143,12 @@
     void onFingerDown() {
         mIsFingerDown = true;
         mSensorPaint.setStyle(Paint.Style.FILL);
-        invalidate();
+        postInvalidate();
     }
 
     void onFingerUp() {
         mIsFingerDown = false;
         mSensorPaint.setStyle(Paint.Style.STROKE);
-        invalidate();
+        postInvalidate();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 76370a9..b328f62 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -1586,6 +1586,11 @@
             Log.d(TAG, "setSelectedBubble: " + bubbleToSelect);
         }
 
+        if (bubbleToSelect == null) {
+            mBubbleData.setShowingOverflow(false);
+            return;
+        }
+
         // Ignore this new bubble only if it is the exact same bubble object. Otherwise, we'll want
         // to re-render it even if it has the same key (equals() returns true). If the currently
         // expanded bubble is removed and instantly re-added, we'll get back a new Bubble instance
@@ -1594,10 +1599,11 @@
         if (mExpandedBubble == bubbleToSelect) {
             return;
         }
-        if (bubbleToSelect == null || bubbleToSelect.getKey() != BubbleOverflow.KEY) {
-            mBubbleData.setShowingOverflow(false);
-        } else {
+
+        if (bubbleToSelect.getKey() == BubbleOverflow.KEY) {
             mBubbleData.setShowingOverflow(true);
+        } else {
+            mBubbleData.setShowingOverflow(false);
         }
 
         if (mIsExpanded && mIsExpansionAnimating) {
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
index 78d7087..e8dba8f 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
@@ -217,10 +217,10 @@
     private fun dumpMessage(message: LogMessage, pw: PrintWriter) {
         pw.print(DATE_FORMAT.format(message.timestamp))
         pw.print(" ")
-        pw.print(message.level)
+        pw.print(message.level.shortString)
         pw.print(" ")
         pw.print(message.tag)
-        pw.print(" ")
+        pw.print(": ")
         pw.println(message.printer(message))
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/log/LogLevel.kt b/packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
index 7b9af0f..53f231c 100644
--- a/packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
+++ b/packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
@@ -21,11 +21,14 @@
 /**
  * Enum version of @Log.Level
  */
-enum class LogLevel(@Log.Level val nativeLevel: Int) {
-    VERBOSE(Log.VERBOSE),
-    DEBUG(Log.DEBUG),
-    INFO(Log.INFO),
-    WARNING(Log.WARN),
-    ERROR(Log.ERROR),
-    WTF(Log.ASSERT)
+enum class LogLevel(
+    @Log.Level val nativeLevel: Int,
+    val shortString: String
+) {
+    VERBOSE(Log.VERBOSE, "V"),
+    DEBUG(Log.DEBUG, "D"),
+    INFO(Log.INFO, "I"),
+    WARNING(Log.WARN, "W"),
+    ERROR(Log.ERROR, "E"),
+    WTF(Log.ASSERT, "WTF")
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 87df544..2802702 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -356,17 +356,8 @@
     @Override
     public void onPipTransitionStarted(ComponentName activity, int direction) {
         if (isOutPipDirection(direction)) {
-            // On phones, the expansion animation that happens on pip tap before restoring
-            // to fullscreen makes it so that the bounds received here are the expanded
-            // bounds. We want to restore to the unexpanded bounds when re-entering pip,
-            // so we save the bounds before expansion (normal) instead of the current
-            // bounds.
-            mReentryBounds.set(mTouchHandler.getNormalBounds());
-            // Apply the snap fraction of the current bounds to the normal bounds.
-            final Rect bounds = mPipTaskOrganizer.getLastReportedBounds();
-            float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
-            mPipBoundsHandler.applySnapFraction(mReentryBounds, snapFraction);
-            // Save reentry bounds (normal non-expand bounds with current position applied).
+            // Exiting PIP, save the reentry bounds to restore to when re-entering.
+            updateReentryBounds();
             mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds);
         }
         // Disable touches while the animation is running
@@ -380,6 +371,23 @@
         }
     }
 
+    /**
+     * Update the bounds used to save the re-entry size and snap fraction when exiting PIP.
+     */
+    public void updateReentryBounds() {
+        // On phones, the expansion animation that happens on pip tap before restoring
+        // to fullscreen makes it so that the last reported bounds are the expanded
+        // bounds. We want to restore to the unexpanded bounds when re-entering pip,
+        // so we use the bounds before expansion (normal) instead of the reported
+        // bounds.
+        Rect reentryBounds = mTouchHandler.getNormalBounds();
+        // Apply the snap fraction of the current bounds to the normal bounds.
+        final Rect bounds = mPipTaskOrganizer.getLastReportedBounds();
+        float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
+        mPipBoundsHandler.applySnapFraction(reentryBounds, snapFraction);
+        mReentryBounds.set(reentryBounds);
+    }
+
     @Override
     public void onPipTransitionFinished(ComponentName activity, int direction) {
         onPipTransitionFinishedOrCanceled(direction);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 442b43e..89df372 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -104,6 +104,8 @@
     private static final int INITIAL_DISMISS_DELAY = 3500;
     private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
     private static final long MENU_FADE_DURATION = 125;
+    private static final long MENU_SLOW_FADE_DURATION = 175;
+    private static final long MENU_SHOW_ON_EXPAND_START_DELAY = 30;
 
     private static final float MENU_BACKGROUND_ALPHA = 0.3f;
     private static final float DISMISS_BACKGROUND_ALPHA = 0.6f;
@@ -183,6 +185,7 @@
                     break;
                 }
                 case MESSAGE_MENU_EXPANDED : {
+                    mMenuContainerAnimator.setStartDelay(MENU_SHOW_ON_EXPAND_START_DELAY);
                     mMenuContainerAnimator.start();
                     break;
                 }
@@ -401,7 +404,9 @@
                 mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
             }
             mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
-            mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
+            mMenuContainerAnimator.setDuration(menuState == MENU_STATE_CLOSE
+                    ? MENU_FADE_DURATION
+                    : MENU_SLOW_FADE_DURATION);
             if (allowMenuTimeout) {
                 mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
                     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 10b04c0..6abbbbe 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -24,6 +24,7 @@
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.media.AudioAttributes;
@@ -376,13 +377,15 @@
             return;
         }
         mHighTempWarning = true;
+        final String message = mContext.getString(R.string.high_temp_notif_message);
         final Notification.Builder nb =
                 new Notification.Builder(mContext, NotificationChannels.ALERTS)
                         .setSmallIcon(R.drawable.ic_device_thermostat_24)
                         .setWhen(0)
                         .setShowWhen(false)
                         .setContentTitle(mContext.getString(R.string.high_temp_title))
-                        .setContentText(mContext.getString(R.string.high_temp_notif_message))
+                        .setContentText(message)
+                        .setStyle(new Notification.BigTextStyle().bigText(message))
                         .setVisibility(Notification.VISIBILITY_PUBLIC)
                         .setContentIntent(pendingBroadcast(ACTION_CLICKED_TEMP_WARNING))
                         .setDeleteIntent(pendingBroadcast(ACTION_DISMISSED_TEMP_WARNING))
@@ -402,6 +405,23 @@
         d.setPositiveButton(com.android.internal.R.string.ok, null);
         d.setShowForAllUsers(true);
         d.setOnDismissListener(dialog -> mHighTempDialog = null);
+        final String url = mContext.getString(R.string.high_temp_dialog_help_url);
+        if (!url.isEmpty()) {
+            d.setNeutralButton(R.string.high_temp_dialog_help_text,
+                    new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            final Intent helpIntent =
+                                    new Intent(Intent.ACTION_VIEW)
+                                            .setData(Uri.parse(url))
+                                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            Dependency.get(ActivityStarter.class).startActivity(helpIntent,
+                                    true /* dismissShade */, resultCode -> {
+                                        mHighTempDialog = null;
+                                    });
+                        }
+                    });
+        }
         d.show();
         mHighTempDialog = d;
     }
@@ -420,19 +440,38 @@
         d.setPositiveButton(com.android.internal.R.string.ok, null);
         d.setShowForAllUsers(true);
         d.setOnDismissListener(dialog -> mThermalShutdownDialog = null);
+        final String url = mContext.getString(R.string.thermal_shutdown_dialog_help_url);
+        if (!url.isEmpty()) {
+            d.setNeutralButton(R.string.thermal_shutdown_dialog_help_text,
+                    new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            final Intent helpIntent =
+                                    new Intent(Intent.ACTION_VIEW)
+                                            .setData(Uri.parse(url))
+                                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                            Dependency.get(ActivityStarter.class).startActivity(helpIntent,
+                                    true /* dismissShade */, resultCode -> {
+                                        mThermalShutdownDialog = null;
+                                    });
+                        }
+                    });
+        }
         d.show();
         mThermalShutdownDialog = d;
     }
 
     @Override
     public void showThermalShutdownWarning() {
+        final String message = mContext.getString(R.string.thermal_shutdown_message);
         final Notification.Builder nb =
                 new Notification.Builder(mContext, NotificationChannels.ALERTS)
                         .setSmallIcon(R.drawable.ic_device_thermostat_24)
                         .setWhen(0)
                         .setShowWhen(false)
                         .setContentTitle(mContext.getString(R.string.thermal_shutdown_title))
-                        .setContentText(mContext.getString(R.string.thermal_shutdown_message))
+                        .setContentText(message)
+                        .setStyle(new Notification.BigTextStyle().bigText(message))
                         .setVisibility(Notification.VISIBILITY_PUBLIC)
                         .setContentIntent(pendingBroadcast(ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING))
                         .setDeleteIntent(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
index 2ef6934..201ed9c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UserDetailView.java
@@ -100,7 +100,8 @@
             if (item.picture == null) {
                 v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
             } else {
-                int avatarSize = (int) v.getResources().getDimension(R.dimen.qs_framed_avatar_size);
+                int avatarSize =
+                        (int) mContext.getResources().getDimension(R.dimen.qs_framed_avatar_size);
                 Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize);
                 drawable.setColorFilter(
                         item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
index 8a38199..370f9a7 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java
@@ -193,10 +193,11 @@
 
             @Override
             public void onKeyguardShowingChanged() {
-                if (!isDividerVisible() || mView == null) {
+                if (!isSplitActive() || mView == null) {
                     return;
                 }
                 mView.setHidden(mKeyguardStateController.isShowing());
+                mImePositionProcessor.updateAdjustForIme();
             }
 
             @Override
@@ -285,8 +286,9 @@
      * while this only cares if some things are (eg. while entering/exiting as well).
      */
     private boolean isSplitActive() {
-        return mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
-                || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED;
+        return mSplits.mPrimary != null && mSplits.mSecondary != null
+                && (mSplits.mPrimary.topActivityType != ACTIVITY_TYPE_UNDEFINED
+                        || mSplits.mSecondary.topActivityType != ACTIVITY_TYPE_UNDEFINED);
     }
 
     private void addDivider(Configuration configuration) {
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
index 47c8c0a..9db389e 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerImeController.java
@@ -91,6 +91,7 @@
 
     private boolean mPaused = true;
     private boolean mPausedTargetAdjusted = false;
+    private boolean mAdjustedWhileHidden = false;
 
     DividerImeController(SplitScreenTaskOrganizer splits, TransactionPool pool, Handler handler) {
         mSplits = splits;
@@ -170,11 +171,17 @@
             // If split is hidden, we don't want to trigger any relayouts that would cause the
             // divider to show again.
             updateImeAdjustState();
+        } else {
+            mAdjustedWhileHidden = true;
         }
     }
 
     private void updateImeAdjustState() {
-        if (mAdjusted != mTargetAdjusted) {
+        updateImeAdjustState(false /* force */);
+    }
+
+    private void updateImeAdjustState(boolean force) {
+        if (mAdjusted != mTargetAdjusted || force) {
             // Reposition the server's secondary split position so that it evaluates
             // insets properly.
             WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -231,6 +238,11 @@
         mSplits.mDivider.setAdjustedForIme(mTargetShown && !mPaused);
     }
 
+    public void updateAdjustForIme() {
+        updateImeAdjustState(mAdjustedWhileHidden);
+        mAdjustedWhileHidden = false;
+    }
+
     @Override
     public void onImePositionChanged(int displayId, int imeTop,
             SurfaceControl.Transaction t) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 27daf86..837543c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -591,6 +591,7 @@
                 .registerDisplayListener(this, new Handler(Looper.getMainLooper()));
 
         mOrientationHandle = new QuickswitchOrientedNavHandle(getContext());
+        mOrientationHandle.setId(R.id.secondary_home_handle);
 
         getBarTransitions().addDarkIntensityListener(mOrientationHandleIntensityListener);
         mOrientationParams = new WindowManager.LayoutParams(0, 0,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
index 5ec5ec6..f52a6e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java
@@ -288,7 +288,8 @@
             if (item.picture == null) {
                 v.bind(name, getDrawable(mContext, item).mutate(), item.resolveId());
             } else {
-                int avatarSize = (int) v.getResources().getDimension(R.dimen.kg_framed_avatar_size);
+                int avatarSize =
+                        (int) mContext.getResources().getDimension(R.dimen.kg_framed_avatar_size);
                 Drawable drawable = new CircleFramedDrawable(item.picture, avatarSize);
                 drawable.setColorFilter(
                         item.isSwitchToEnabled ? null : getDisabledUserAvatarColorFilter());
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
index 38b20c0..3402a52 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayImeController.java
@@ -278,10 +278,8 @@
             if (imeSource == null || mImeSourceControl == null) {
                 return;
             }
-            // Set frame, but only if the new frame isn't empty -- this maintains continuity
             final Rect newFrame = imeSource.getFrame();
-            mImeFrame.set(newFrame);
-            final boolean isFloating = newFrame.height() == 0;
+            final boolean isFloating = newFrame.height() == 0 && show;
             if (isFloating) {
                 // This is likely a "floating" or "expanded" IME, so to get animations, just
                 // pretend the ime has some size just below the screen.
@@ -290,6 +288,9 @@
                         mSystemWindows.mDisplayController.getDisplayLayout(mDisplayId).density()
                                 * FLOATING_IME_BOTTOM_INSET);
                 mImeFrame.bottom -= floatingInset;
+            } else if (newFrame.height() != 0) {
+                // Don't set a new frame if it's empty and hiding -- this maintains continuity
+                mImeFrame.set(newFrame);
             }
             if (DEBUG) {
                 Slog.d(TAG, "Run startAnim  show:" + show + "  was:"
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
new file mode 100644
index 0000000..71f3d5b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/MagnificationModeSwitchTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility;
+
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN;
+import static android.provider.Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW;
+
+import static com.android.systemui.accessibility.MagnificationModeSwitch.getIconResId;
+
+import static junit.framework.Assert.assertEquals;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.provider.Settings;
+import android.testing.AndroidTestingRunner;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.WindowManager;
+import android.widget.ImageView;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class MagnificationModeSwitchTest extends SysuiTestCase {
+
+    @Mock
+    private ImageView mMockImageView;
+    @Mock
+    private WindowManager mWindowManager;
+    @Mock
+    private ViewPropertyAnimator mViewPropertyAnimator;
+    private MagnificationModeSwitch mMagnificationModeSwitch;
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
+
+        when(mViewPropertyAnimator.setDuration(anyLong())).thenReturn(mViewPropertyAnimator);
+        when(mViewPropertyAnimator.alpha(anyFloat())).thenReturn(mViewPropertyAnimator);
+        when(mViewPropertyAnimator.setStartDelay(anyLong())).thenReturn(mViewPropertyAnimator);
+        when(mViewPropertyAnimator.withEndAction(any(Runnable.class))).thenReturn(
+                mViewPropertyAnimator);
+
+        when(mMockImageView.animate()).thenReturn(mViewPropertyAnimator);
+
+        mMagnificationModeSwitch = new MagnificationModeSwitch(mContext, mMockImageView);
+    }
+
+    @Test
+    public void removeButton_removeView() {
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        mMagnificationModeSwitch.removeButton();
+
+        verify(mWindowManager).removeView(mMockImageView);
+        // First invocation is in showButton.
+        verify(mViewPropertyAnimator, times(2)).cancel();
+    }
+
+    @Test
+    public void showWindowModeButton_fullscreenMode_addViewAndSetImageResource() {
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW);
+
+        verify(mMockImageView).setAlpha(1.0f);
+        verify(mMockImageView).setImageResource(
+                getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+        verify(mViewPropertyAnimator).cancel();
+        verify(mViewPropertyAnimator).setDuration(anyLong());
+        verify(mViewPropertyAnimator).setStartDelay(anyLong());
+        verify(mViewPropertyAnimator).alpha(anyFloat());
+        ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
+        verify(mViewPropertyAnimator).withEndAction(captor.capture());
+        verify(mWindowManager).addView(eq(mMockImageView), any(WindowManager.LayoutParams.class));
+
+        captor.getValue().run();
+
+        // First invocation is in showButton.
+        verify(mViewPropertyAnimator, times(2)).cancel();
+        verify(mWindowManager).removeView(mMockImageView);
+    }
+
+    @Test
+    public void performClick_fullscreenMode_removeViewAndChangeSettingsValue() {
+        ArgumentCaptor<View.OnClickListener> captor = ArgumentCaptor.forClass(
+                View.OnClickListener.class);
+        verify(mMockImageView).setOnClickListener(captor.capture());
+        mMagnificationModeSwitch.showButton(ACCESSIBILITY_MAGNIFICATION_MODE_FULLSCREEN);
+
+        captor.getValue().onClick(mMockImageView);
+
+        // First invocation is in showButton.
+        verify(mViewPropertyAnimator, times(2)).cancel();
+        verify(mMockImageView).setImageResource(
+                getIconResId(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW));
+        verify(mWindowManager).removeView(mMockImageView);
+        final int actualMode = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE, 0);
+        assertEquals(ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW, actualMode);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
index 6d6a4d8..f48b3fc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
@@ -25,6 +25,8 @@
 import android.view.ViewGroup
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.testing.UiEventLoggerFake
+import com.android.internal.util.UserIcons
+import com.android.systemui.R
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.QSUserSwitcherEvent
 import com.android.systemui.statusbar.policy.UserSwitcherController
@@ -50,10 +52,10 @@
     @Mock private lateinit var mOtherView: View
     @Mock private lateinit var mInflatedUserDetailItemView: UserDetailItemView
     @Mock private lateinit var mUserInfo: UserInfo
-    @Mock private lateinit var mPicture: Bitmap
     @Mock private lateinit var mLayoutInflater: LayoutInflater
     private lateinit var adapter: UserDetailView.Adapter
     private lateinit var uiEventLogger: UiEventLoggerFake
+    private lateinit var mPicture: Bitmap
 
     @Before
     fun setUp() {
@@ -64,6 +66,7 @@
         `when`(mLayoutInflater.inflate(anyInt(), any(ViewGroup::class.java), anyBoolean()))
                 .thenReturn(mInflatedUserDetailItemView)
         adapter = UserDetailView.Adapter(mContext, mUserSwitcherController, uiEventLogger)
+        mPicture = UserIcons.convertToBitmap(mContext.getDrawable(R.drawable.ic_avatar_user))
     }
 
     private fun clickableTest(
@@ -141,4 +144,4 @@
                     false /* isAddUser */,
                     false /* isRestricted */,
                     true /* isSwitchToEnabled */)
-}
\ No newline at end of file
+}
diff --git a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index e10bab4..9bb01ae 100644
--- a/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/packages/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -102,17 +102,21 @@
 
     private UiAutomation mUiAutomation =
             InstrumentationRegistry.getInstrumentation().getUiAutomation();
+    private boolean mRunTests;
 
     @Before
     public void setUp() throws Exception {
-        mHandlerThread = new HandlerThread(getClass().getSimpleName());
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
         // Needed to create a TestNetworkInterface, to call requestTetheredInterface, and to receive
         // tethered client callbacks.
         mUiAutomation.adoptShellPermissionIdentity(
                 MANAGE_TEST_NETWORKS, NETWORK_SETTINGS, TETHER_PRIVILEGED);
+        mRunTests = mTm.isTetheringSupported() && mEm != null;
+        assumeTrue(mRunTests);
+
+        mHandlerThread = new HandlerThread(getClass().getSimpleName());
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mTetheredInterfaceRequester = new TetheredInterfaceRequester(mHandler, mEm);
     }
 
     private void cleanUp() throws Exception {
@@ -136,7 +140,7 @@
     @After
     public void tearDown() throws Exception {
         try {
-            cleanUp();
+            if (mRunTests) cleanUp();
         } finally {
             mUiAutomation.dropShellPermissionIdentity();
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index a4c5a23..9ad808a 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -79,6 +79,7 @@
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -89,6 +90,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Set;
 
 /**
@@ -205,7 +207,8 @@
         /**
          * @return The magnification controller
          */
-        @NonNull MagnificationController getMagnificationController();
+        @NonNull
+        FullScreenMagnificationController getFullScreenMagnificationController();
 
         /**
          * Called back to notify system that the client has changed
@@ -831,7 +834,7 @@
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            return mSystemSupport.getMagnificationController().getScale(displayId);
+            return mSystemSupport.getFullScreenMagnificationController().getScale(displayId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -844,8 +847,8 @@
             if (!hasRightsToCurrentUserLocked()) {
                 return region;
             }
-            MagnificationController magnificationController =
-                    mSystemSupport.getMagnificationController();
+            FullScreenMagnificationController magnificationController =
+                    mSystemSupport.getFullScreenMagnificationController();
             boolean registeredJustForThisCall =
                     registerMagnificationIfNeeded(displayId, magnificationController);
             final long identity = Binder.clearCallingIdentity();
@@ -867,8 +870,8 @@
             if (!hasRightsToCurrentUserLocked()) {
                 return 0.0f;
             }
-            MagnificationController magnificationController =
-                    mSystemSupport.getMagnificationController();
+            FullScreenMagnificationController magnificationController =
+                    mSystemSupport.getFullScreenMagnificationController();
             boolean registeredJustForThisCall =
                     registerMagnificationIfNeeded(displayId, magnificationController);
             final long identity = Binder.clearCallingIdentity();
@@ -889,8 +892,8 @@
             if (!hasRightsToCurrentUserLocked()) {
                 return 0.0f;
             }
-            MagnificationController magnificationController =
-                    mSystemSupport.getMagnificationController();
+            FullScreenMagnificationController magnificationController =
+                    mSystemSupport.getFullScreenMagnificationController();
             boolean registeredJustForThisCall =
                     registerMagnificationIfNeeded(displayId, magnificationController);
             final long identity = Binder.clearCallingIdentity();
@@ -906,7 +909,7 @@
     }
 
     private boolean registerMagnificationIfNeeded(int displayId,
-            MagnificationController magnificationController) {
+            FullScreenMagnificationController magnificationController) {
         if (!magnificationController.isRegistered(displayId)
                 && mSecurityPolicy.canControlMagnification(this)) {
             magnificationController.register(displayId);
@@ -927,8 +930,8 @@
         }
         final long identity = Binder.clearCallingIdentity();
         try {
-            MagnificationController magnificationController =
-                    mSystemSupport.getMagnificationController();
+            FullScreenMagnificationController magnificationController =
+                    mSystemSupport.getFullScreenMagnificationController();
             return (magnificationController.reset(displayId, animate)
                     || !magnificationController.isMagnifying(displayId));
         } finally {
@@ -948,8 +951,8 @@
             }
             final long identity = Binder.clearCallingIdentity();
             try {
-                MagnificationController magnificationController =
-                        mSystemSupport.getMagnificationController();
+                FullScreenMagnificationController magnificationController =
+                        mSystemSupport.getFullScreenMagnificationController();
                 if (!magnificationController.isRegistered(displayId)) {
                     magnificationController.register(displayId);
                 }
@@ -1176,7 +1179,11 @@
                 /* ignore */
         }
         if (mService != null) {
-            mService.unlinkToDeath(this, 0);
+            try {
+                mService.unlinkToDeath(this, 0);
+            } catch (NoSuchElementException e) {
+                Slog.e(LOG_TAG, "Failed unregistering death link");
+            }
             mService = null;
         }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index be470b1..8b40f61 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -34,6 +34,7 @@
 
 import com.android.server.LocalServices;
 import com.android.server.accessibility.gestures.TouchExplorer;
+import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler;
 import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler;
 import com.android.server.policy.WindowManagerPolicy;
@@ -539,7 +540,7 @@
                     detectControlGestures, triggerable, displayId);
         } else {
             magnificationGestureHandler = new FullScreenMagnificationGestureHandler(displayContext,
-                    mAms.getMagnificationController(), mAms::onMagnificationScaleChanged,
+                    mAms.getFullScreenMagnificationController(), mAms::onMagnificationScaleChanged,
                     detectControlGestures, triggerable, displayId);
         }
         return magnificationGestureHandler;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9f9ceb0..c92571c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -116,6 +116,7 @@
 import com.android.internal.util.IntPair;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
 import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 import com.android.server.accessibility.magnification.WindowMagnificationManager;
 import com.android.server.wm.ActivityTaskManagerInternal;
@@ -212,7 +213,7 @@
     // Lazily initialized - access through getSystemActionPerfomer()
     private SystemActionPerformer mSystemActionPerformer;
 
-    private MagnificationController mMagnificationController;
+    private FullScreenMagnificationController mFullScreenMagnificationController;
 
     private InteractionBridge mInteractionBridge;
 
@@ -2191,13 +2192,13 @@
             return;
         }
 
-        if (mMagnificationController != null) {
-            mMagnificationController.setUserId(userState.mUserId);
+        if (mFullScreenMagnificationController != null) {
+            mFullScreenMagnificationController.setUserId(userState.mUserId);
         }
 
         if (mUiAutomationManager.suppressingAccessibilityServicesLocked()
-                && mMagnificationController != null) {
-            mMagnificationController.unregisterAll();
+                && mFullScreenMagnificationController != null) {
+            mFullScreenMagnificationController.unregisterAll();
             return;
         }
 
@@ -2209,7 +2210,7 @@
                 || userState.isShortcutMagnificationEnabledLocked()) {
             for (int i = 0; i < displays.size(); i++) {
                 final Display display = displays.get(i);
-                getMagnificationController().register(display.getDisplayId());
+                getFullScreenMagnificationController().register(display.getDisplayId());
             }
             return;
         }
@@ -2219,9 +2220,9 @@
             final Display display = displays.get(i);
             final int displayId = display.getDisplayId();
             if (userHasListeningMagnificationServicesLocked(userState, displayId)) {
-                getMagnificationController().register(displayId);
-            } else if (mMagnificationController != null) {
-                mMagnificationController.unregister(displayId);
+                getFullScreenMagnificationController().register(displayId);
+            } else if (mFullScreenMagnificationController != null) {
+                mFullScreenMagnificationController.unregister(displayId);
             }
         }
     }
@@ -2568,7 +2569,7 @@
         }
         // In case user assigned magnification to the given shortcut.
         if (targetName.equals(MAGNIFICATION_CONTROLLER_NAME)) {
-            final boolean enabled = !getMagnificationController().isMagnifying(displayId);
+            final boolean enabled = !getFullScreenMagnificationController().isMagnifying(displayId);
             logAccessibilityShortcutActivated(MAGNIFICATION_COMPONENT_NAME, shortcutType, enabled);
             sendAccessibilityButtonToInputFilter(displayId);
             return;
@@ -2928,13 +2929,14 @@
     }
 
     @Override
-    public MagnificationController getMagnificationController() {
+    public FullScreenMagnificationController getFullScreenMagnificationController() {
         synchronized (mLock) {
-            if (mMagnificationController == null) {
-                mMagnificationController = new MagnificationController(mContext, this, mLock);
-                mMagnificationController.setUserId(mCurrentUserId);
+            if (mFullScreenMagnificationController == null) {
+                mFullScreenMagnificationController = new FullScreenMagnificationController(mContext,
+                        this, mLock);
+                mFullScreenMagnificationController.setUserId(mCurrentUserId);
             }
-            return mMagnificationController;
+            return mFullScreenMagnificationController;
         }
     }
 
@@ -3126,8 +3128,8 @@
                     }
                 }
             }
-            if (mMagnificationController != null) {
-                mMagnificationController.onDisplayRemoved(displayId);
+            if (mFullScreenMagnificationController != null) {
+                mFullScreenMagnificationController.onDisplayRemoved(displayId);
             }
             mA11yWindowManager.stopTrackingWindows(displayId);
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index fea2e7b..e48d11d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -120,7 +120,7 @@
         AccessibilityUserState userState = mUserStateWeakReference.get();
         if (userState == null) return;
         userState.removeServiceLocked(this);
-        mSystemSupport.getMagnificationController().resetAllIfNeeded(mId);
+        mSystemSupport.getFullScreenMagnificationController().resetAllIfNeeded(mId);
         mActivityTaskManagerService.setAllowAppSwitches(mComponentName.flattenToString(), -1,
                 userState.mUserId);
         resetLocked();
@@ -312,7 +312,7 @@
                 userState.serviceDisconnectedLocked(this);
             }
             resetLocked();
-            mSystemSupport.getMagnificationController().resetAllIfNeeded(mId);
+            mSystemSupport.getFullScreenMagnificationController().resetAllIfNeeded(mId);
             mSystemSupport.onClientChangeLocked(false);
         }
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
similarity index 94%
rename from services/accessibility/java/com/android/server/accessibility/MagnificationController.java
rename to services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
index e784056..44c4bf4 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.accessibility;
+package com.android.server.accessibility.magnification;
 
 import android.animation.ValueAnimator;
 import android.annotation.NonNull;
@@ -42,6 +42,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
+import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.wm.WindowManagerInternal;
 
 import java.util.Locale;
@@ -56,9 +57,9 @@
  * magnification region. If a value is out of bounds, it will be adjusted to guarantee these
  * constraints.
  */
-public class MagnificationController {
+public class FullScreenMagnificationController {
     private static final boolean DEBUG = false;
-    private static final String LOG_TAG = "MagnificationController";
+    private static final String LOG_TAG = "FullScreenMagnificationController";
 
     public static final float MIN_SCALE = 1.0f;
     public static final float MAX_SCALE = 8.0f;
@@ -140,11 +141,12 @@
 
         /**
          * Unregisters magnification callback from window manager. Callbacks to
-         * {@link MagnificationController#unregisterCallbackLocked(int, boolean)} after
+         * {@link FullScreenMagnificationController#unregisterCallbackLocked(int, boolean)} after
          * unregistered.
          *
          * @param delete true if this instance should be removed from the SparseArray in
-         *               MagnificationController after unregistered, for example, display removed.
+         *               FullScreenMagnificationController after unregistered, for example,
+         *               display removed.
          */
         @GuardedBy("mLock")
         void unregister(boolean delete) {
@@ -164,7 +166,8 @@
          * called after animation finished.
          *
          * @param delete true if this instance should be removed from the SparseArray in
-         *               MagnificationController after unregistered, for example, display removed.
+         *               FullScreenMagnificationController after unregistered, for example,
+         *               display removed.
          */
         @GuardedBy("mLock")
         void unregisterPending(boolean delete) {
@@ -257,15 +260,17 @@
         @Override
         public void onRotationChanged(int rotation) {
             // Treat as context change and reset
-            final Message m = PooledLambda.obtainMessage(MagnificationController::resetIfNeeded,
-                    MagnificationController.this, mDisplayId, true);
+            final Message m = PooledLambda.obtainMessage(
+                    FullScreenMagnificationController::resetIfNeeded,
+                    FullScreenMagnificationController.this, mDisplayId, true);
             mControllerCtx.getHandler().sendMessage(m);
         }
 
         @Override
         public void onUserContextChanged() {
-            final Message m = PooledLambda.obtainMessage(MagnificationController::resetIfNeeded,
-                    MagnificationController.this, mDisplayId, true);
+            final Message m = PooledLambda.obtainMessage(
+                    FullScreenMagnificationController::resetIfNeeded,
+                    FullScreenMagnificationController.this, mDisplayId, true);
             mControllerCtx.getHandler().sendMessage(m);
         }
 
@@ -554,25 +559,25 @@
         float getMinOffsetXLocked() {
             final float viewportWidth = mMagnificationBounds.width();
             final float viewportLeft = mMagnificationBounds.left;
-            return (viewportLeft + viewportWidth) -
-                    (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
+            return (viewportLeft + viewportWidth)
+                    - (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
         }
 
         float getMaxOffsetXLocked() {
-            return mMagnificationBounds.left -
-                    mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
+            return mMagnificationBounds.left
+                    - mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
         }
 
         float getMinOffsetYLocked() {
             final float viewportHeight = mMagnificationBounds.height();
             final float viewportTop = mMagnificationBounds.top;
-            return (viewportTop + viewportHeight) -
-                    (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
+            return (viewportTop + viewportHeight)
+                    - (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
         }
 
         float getMaxOffsetYLocked() {
-            return mMagnificationBounds.top -
-                    mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
+            return mMagnificationBounds.top
+                    - mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
         }
 
         @Override
@@ -590,9 +595,9 @@
     }
 
     /**
-     * MagnificationController Constructor
+     * FullScreenMagnificationController Constructor
      */
-    public MagnificationController(@NonNull Context context,
+    public FullScreenMagnificationController(@NonNull Context context,
             @NonNull AccessibilityManagerService ams, @NonNull Object lock) {
         this(new ControllerContext(context, ams,
                 LocalServices.getService(WindowManagerInternal.class),
@@ -604,7 +609,7 @@
      * Constructor for tests
      */
     @VisibleForTesting
-    public MagnificationController(@NonNull ControllerContext ctx, @NonNull Object lock) {
+    public FullScreenMagnificationController(@NonNull ControllerContext ctx, @NonNull Object lock) {
         mControllerCtx = ctx;
         mLock = lock;
         mMainThreadId = mControllerCtx.getContext().getMainLooper().getThread().getId();
@@ -1088,7 +1093,7 @@
 
     private void onScreenTurnedOff() {
         final Message m = PooledLambda.obtainMessage(
-                MagnificationController::resetAllIfNeeded, this, false);
+                FullScreenMagnificationController::resetAllIfNeeded, this, false);
         mControllerCtx.getHandler().sendMessage(m);
     }
 
@@ -1253,14 +1258,14 @@
             synchronized (mLock) {
                 if (mEnabled) {
                     float fract = animation.getAnimatedFraction();
-                    mTmpMagnificationSpec.scale = mStartMagnificationSpec.scale +
-                            (mEndMagnificationSpec.scale - mStartMagnificationSpec.scale) * fract;
-                    mTmpMagnificationSpec.offsetX = mStartMagnificationSpec.offsetX +
-                            (mEndMagnificationSpec.offsetX - mStartMagnificationSpec.offsetX)
-                                    * fract;
-                    mTmpMagnificationSpec.offsetY = mStartMagnificationSpec.offsetY +
-                            (mEndMagnificationSpec.offsetY - mStartMagnificationSpec.offsetY)
-                                    * fract;
+                    mTmpMagnificationSpec.scale = mStartMagnificationSpec.scale
+                            + (mEndMagnificationSpec.scale - mStartMagnificationSpec.scale) * fract;
+                    mTmpMagnificationSpec.offsetX = mStartMagnificationSpec.offsetX
+                            + (mEndMagnificationSpec.offsetX - mStartMagnificationSpec.offsetX)
+                            * fract;
+                    mTmpMagnificationSpec.offsetY = mStartMagnificationSpec.offsetY
+                            + (mEndMagnificationSpec.offsetY - mStartMagnificationSpec.offsetY)
+                            * fract;
                     setMagnificationSpecLocked(mTmpMagnificationSpec);
                 }
             }
@@ -1269,10 +1274,10 @@
 
     private static class ScreenStateObserver extends BroadcastReceiver {
         private final Context mContext;
-        private final MagnificationController mController;
+        private final FullScreenMagnificationController mController;
         private boolean mRegistered = false;
 
-        public ScreenStateObserver(Context context, MagnificationController controller) {
+        ScreenStateObserver(Context context, FullScreenMagnificationController controller) {
             mContext = context;
             mController = controller;
         }
diff --git a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
similarity index 94%
rename from services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
rename to services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 058a293..d50e9d7 100644
--- a/services/accessibility/java/com/android/server/accessibility/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.accessibility;
+package com.android.server.accessibility.magnification;
 
 import static android.view.InputDevice.SOURCE_TOUCHSCREEN;
 import static android.view.MotionEvent.ACTION_CANCEL;
@@ -59,8 +59,8 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accessibility.gestures.GestureUtils;
-import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 
 import java.util.ArrayDeque;
 import java.util.Queue;
@@ -114,7 +114,7 @@
  * 7. The magnification scale will be persisted in settings and in the cloud.
  */
 @SuppressWarnings("WeakerAccess")
-class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler {
+public class FullScreenMagnificationGestureHandler extends MagnificationGestureHandler {
     private static final String LOG_TAG = "FullScreenMagnificationGestureHandler";
 
     private static final boolean DEBUG_ALL = false;
@@ -127,9 +127,9 @@
     // to AccessibilityService.MagnificationController#setScale() has
     // different scale range
     private static final float MIN_SCALE = 2.0f;
-    private static final float MAX_SCALE = MagnificationController.MAX_SCALE;
+    private static final float MAX_SCALE = FullScreenMagnificationController.MAX_SCALE;
 
-    @VisibleForTesting final MagnificationController mMagnificationController;
+    @VisibleForTesting final FullScreenMagnificationController mFullScreenMagnificationController;
 
     @VisibleForTesting final DelegatingState mDelegatingState;
     @VisibleForTesting final DetectingState mDetectingState;
@@ -163,7 +163,7 @@
 
     /**
      * @param context Context for resolving various magnification-related resources
-     * @param magnificationController the {@link MagnificationController}
+     * @param fullScreenMagnificationController the {@link FullScreenMagnificationController}
      *
      * @param detectTripleTap {@code true} if this detector should detect and respond to triple-tap
      *                                gestures for engaging and disengaging magnification,
@@ -173,9 +173,9 @@
      *                           {@code false} if it should ignore such triggers.
      * @param displayId The logical display id.
      */
-    FullScreenMagnificationGestureHandler(Context context,
-            MagnificationController magnificationController,
-            MagnificationGestureHandler.ScaleChangedListener listener,
+    public FullScreenMagnificationGestureHandler(Context context,
+            FullScreenMagnificationController fullScreenMagnificationController,
+            ScaleChangedListener listener,
             boolean detectTripleTap,
             boolean detectShortcutTrigger,
             int displayId) {
@@ -185,7 +185,7 @@
                     "FullScreenMagnificationGestureHandler(detectTripleTap = " + detectTripleTap
                             + ", detectShortcutTrigger = " + detectShortcutTrigger + ")");
         }
-        mMagnificationController = magnificationController;
+        mFullScreenMagnificationController = fullScreenMagnificationController;
         mDisplayId = displayId;
 
         mDelegatingState = new DelegatingState();
@@ -265,7 +265,7 @@
             mScreenStateReceiver.unregister();
         }
         // Check if need to reset when MagnificationGestureHandler is the last magnifying service.
-        mMagnificationController.resetAllIfNeeded(
+        mFullScreenMagnificationController.resetAllIfNeeded(
                 AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
         clearAndTransitionToStateDetecting();
     }
@@ -273,7 +273,7 @@
     @Override
     public void notifyShortcutTriggered() {
         if (mDetectShortcutTrigger) {
-            boolean wasMagnifying = mMagnificationController.resetIfNeeded(mDisplayId,
+            boolean wasMagnifying = mFullScreenMagnificationController.resetIfNeeded(mDisplayId,
                     /* animate */ true);
             if (wasMagnifying) {
                 clearAndTransitionToStateDetecting();
@@ -424,7 +424,7 @@
         }
 
         public void persistScaleAndTransitionTo(State state) {
-            mMagnificationController.persistScale();
+            mFullScreenMagnificationController.persistScale();
             clear();
             transitionTo(state);
         }
@@ -439,7 +439,7 @@
                 Slog.i(LOG_TAG, "Panned content by scrollX: " + distanceX
                         + " scrollY: " + distanceY);
             }
-            mMagnificationController.offsetMagnifiedRegion(mDisplayId, distanceX,
+            mFullScreenMagnificationController.offsetMagnifiedRegion(mDisplayId, distanceX,
                     distanceY, AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
             return /* event consumed: */ true;
         }
@@ -455,7 +455,7 @@
                 mScaling = abs(deltaScale) > mScalingThreshold;
                 return mScaling;
             }
-            final float initialScale = mMagnificationController.getScale(mDisplayId);
+            final float initialScale = mFullScreenMagnificationController.getScale(mDisplayId);
             final float targetScale = initialScale * detector.getScaleFactor();
 
             // Don't allow a gesture to move the user further outside the
@@ -477,7 +477,7 @@
             final float pivotX = detector.getFocusX();
             final float pivotY = detector.getFocusY();
             if (DEBUG_PANNING_SCALING) Slog.i(LOG_TAG, "Scaled content to: " + scale + "x");
-            mMagnificationController.setScale(mDisplayId, scale, pivotX, pivotY, false,
+            mFullScreenMagnificationController.setScale(mDisplayId, scale, pivotX, pivotY, false,
                     AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
             mListener.onMagnificationScaleChanged(mDisplayId, getMode());
             return /* handled: */ true;
@@ -537,9 +537,9 @@
                     }
                     final float eventX = event.getX();
                     final float eventY = event.getY();
-                    if (mMagnificationController.magnificationRegionContains(
+                    if (mFullScreenMagnificationController.magnificationRegionContains(
                             mDisplayId, eventX, eventY)) {
-                        mMagnificationController.setCenter(mDisplayId, eventX, eventY,
+                        mFullScreenMagnificationController.setCenter(mDisplayId, eventX, eventY,
                                 /* animate */ mLastMoveOutsideMagnifiedRegion,
                                 AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
                         mLastMoveOutsideMagnifiedRegion = false;
@@ -687,7 +687,7 @@
                     mLastDetectingDownEventTime = event.getDownTime();
                     mHandler.removeMessages(MESSAGE_TRANSITION_TO_DELEGATING_STATE);
 
-                    if (!mMagnificationController.magnificationRegionContains(
+                    if (!mFullScreenMagnificationController.magnificationRegionContains(
                             mDisplayId, event.getX(), event.getY())) {
 
                         transitionToDelegatingStateAndClear();
@@ -705,7 +705,7 @@
                             // If magnified, delay an ACTION_DOWN for mMultiTapMaxDelay
                             // to ensure reachability of
                             // STATE_PANNING_SCALING(triggerable with ACTION_POINTER_DOWN)
-                            || mMagnificationController.isMagnifying(mDisplayId)) {
+                            || mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
 
                         afterMultiTapTimeoutTransitionToDelegatingState();
 
@@ -717,7 +717,7 @@
                 }
                 break;
                 case ACTION_POINTER_DOWN: {
-                    if (mMagnificationController.isMagnifying(mDisplayId)
+                    if (mFullScreenMagnificationController.isMagnifying(mDisplayId)
                             && event.getPointerCount() == 2) {
                         storeSecondPointerDownLocation(event);
                         mHandler.sendEmptyMessageDelayed(MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE,
@@ -760,7 +760,7 @@
 
                     mHandler.removeMessages(MESSAGE_ON_TRIPLE_TAP_AND_HOLD);
 
-                    if (!mMagnificationController.magnificationRegionContains(
+                    if (!mFullScreenMagnificationController.magnificationRegionContains(
                             mDisplayId, event.getX(), event.getY())) {
 
                         transitionToDelegatingStateAndClear();
@@ -811,7 +811,7 @@
 
             // Only log the triple tap event, use numTaps to filter.
             if (multitapTriggered && numTaps > 2) {
-                final boolean enabled = mMagnificationController.isMagnifying(mDisplayId);
+                final boolean enabled = mFullScreenMagnificationController.isMagnifying(mDisplayId);
                 logMagnificationTripleTap(enabled);
             }
             return multitapTriggered;
@@ -947,7 +947,7 @@
             clear();
 
             // Toggle zoom
-            if (mMagnificationController.isMagnifying(mDisplayId)) {
+            if (mFullScreenMagnificationController.isMagnifying(mDisplayId)) {
                 zoomOff();
             } else {
                 zoomOn(up.getX(), up.getY());
@@ -955,7 +955,7 @@
         }
 
         private boolean isMagnifying() {
-            return mMagnificationController.isMagnifying(mDisplayId);
+            return mFullScreenMagnificationController.isMagnifying(mDisplayId);
         }
 
         void transitionToViewportDraggingStateAndClear(MotionEvent down) {
@@ -964,7 +964,7 @@
             clear();
 
             mViewportDraggingState.mZoomedInBeforeDrag =
-                    mMagnificationController.isMagnifying(mDisplayId);
+                    mFullScreenMagnificationController.isMagnifying(mDisplayId);
 
             // Triple tap and hold also belongs to triple tap event.
             final boolean enabled = !mViewportDraggingState.mZoomedInBeforeDrag;
@@ -995,7 +995,7 @@
             if (DEBUG_DETECTING) Slog.i(LOG_TAG, "setShortcutTriggered(" + state + ")");
 
             mShortcutTriggered = state;
-            mMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
+            mFullScreenMagnificationController.setForceShowMagnifiableBounds(mDisplayId, state);
         }
 
         /**
@@ -1028,9 +1028,9 @@
         if (DEBUG_DETECTING) Slog.i(LOG_TAG, "zoomOn(" + centerX + ", " + centerY + ")");
 
         final float scale = MathUtils.constrain(
-                mMagnificationController.getPersistedScale(),
+                mFullScreenMagnificationController.getPersistedScale(),
                 MIN_SCALE, MAX_SCALE);
-        mMagnificationController.setScaleAndCenter(mDisplayId,
+        mFullScreenMagnificationController.setScaleAndCenter(mDisplayId,
                 scale, centerX, centerY,
                 /* animate */ true,
                 AccessibilityManagerService.MAGNIFICATION_GESTURE_HANDLER_ID);
@@ -1038,7 +1038,7 @@
 
     private void zoomOff() {
         if (DEBUG_DETECTING) Slog.i(LOG_TAG, "zoomOff()");
-        mMagnificationController.reset(mDisplayId, /* animate */ true);
+        mFullScreenMagnificationController.reset(mDisplayId, /* animate */ true);
     }
 
     private static MotionEvent recycleAndNullify(@Nullable MotionEvent event) {
@@ -1059,7 +1059,7 @@
                 + ", mDetectShortcutTrigger=" + mDetectShortcutTrigger
                 + ", mCurrentState=" + State.nameOf(mCurrentState)
                 + ", mPreviousState=" + State.nameOf(mPreviousState)
-                + ", mMagnificationController=" + mMagnificationController
+                + ", mMagnificationController=" + mFullScreenMagnificationController
                 + ", mDisplayId=" + mDisplayId
                 + '}';
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
index f38c38f..d6f53d2 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/MagnificationGestureHandler.java
@@ -23,7 +23,7 @@
  */
 public abstract class MagnificationGestureHandler extends BaseEventStreamTransformation {
 
-    protected final MagnificationGestureHandler.ScaleChangedListener mListener;
+    protected final ScaleChangedListener mListener;
 
     protected MagnificationGestureHandler(ScaleChangedListener listener) {
         mListener = listener;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index 56c0519..bd25f2b 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -100,7 +100,7 @@
      */
     public WindowMagnificationGestureHandler(Context context,
             WindowMagnificationManager windowMagnificationMgr,
-            MagnificationGestureHandler.ScaleChangedListener listener, boolean detectTripleTap,
+            ScaleChangedListener listener, boolean detectTripleTap,
             boolean detectShortcutTrigger, int displayId) {
         super(listener);
         if (DEBUG_ALL) {
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
index b5ea01a..a08c2dd 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationManager.java
@@ -17,7 +17,10 @@
 package com.android.server.accessibility.magnification;
 
 import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.graphics.Rect;
 import android.os.Binder;
 import android.os.IBinder;
@@ -34,7 +37,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.BackgroundThread;
 import com.android.server.LocalServices;
-import com.android.server.accessibility.MagnificationController;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
 /**
@@ -50,20 +52,31 @@
     private static final String TAG = "WindowMagnificationMgr";
 
     //Ensure the range has consistency with full screen.
-    static final float MAX_SCALE = MagnificationController.MAX_SCALE;
-    static final float MIN_SCALE = MagnificationController.MIN_SCALE;
+    static final float MAX_SCALE = FullScreenMagnificationController.MAX_SCALE;
+    static final float MIN_SCALE = FullScreenMagnificationController.MIN_SCALE;
 
-    private final Object mLock = new Object();;
+    private final Object mLock = new Object();
     private final Context mContext;
     @VisibleForTesting
     @GuardedBy("mLock")
-    @Nullable WindowMagnificationConnectionWrapper mConnectionWrapper;
+    @Nullable
+    WindowMagnificationConnectionWrapper mConnectionWrapper;
     @GuardedBy("mLock")
     private ConnectionCallback mConnectionCallback;
     @GuardedBy("mLock")
     private SparseArray<WindowMagnifier> mWindowMagnifiers = new SparseArray<>();
     private int mUserId;
 
+    @VisibleForTesting
+    protected final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final int displayId = context.getDisplayId();
+            removeMagnificationButton(displayId);
+            disableWindowMagnification(displayId);
+        }
+    };
+
     public WindowMagnificationManager(Context context, int userId) {
         mContext = context;
         mUserId = userId;
@@ -134,8 +147,12 @@
             if (connect == isConnected()) {
                 return false;
             }
-            if (!connect) {
+            if (connect) {
+                final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
+                mContext.registerReceiver(mScreenStateReceiver, intentFilter);
+            } else {
                 disableAllWindowMagnifiers();
+                mContext.unregisterReceiver(mScreenStateReceiver);
             }
         }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index b13bef2..c839ce94 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -24,6 +24,7 @@
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
 import android.app.backup.BackupManager;
+import android.app.backup.BackupManager.OperationType;
 import android.app.backup.IBackupManager;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
@@ -1338,14 +1339,15 @@
         if (!isUserReadyForBackup(userId)) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
-        return requestBackup(userId, packages, observer, monitor, flags);
+        return requestBackup(userId, packages, observer, monitor, flags, OperationType.BACKUP);
     }
 
     @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
-            IBackupManagerMonitor monitor, int flags) throws RemoteException {
-        return requestBackupForUser(binderGetCallingUserId(), packages,
-                observer, monitor, flags);
+            IBackupManagerMonitor monitor, int flags, @OperationType int operationType)
+            throws RemoteException {
+        return requestBackup(binderGetCallingUserId(), packages,
+                observer, monitor, flags, operationType);
     }
 
     /**
@@ -1357,13 +1359,15 @@
             String[] packages,
             IBackupObserver observer,
             IBackupManagerMonitor monitor,
-            int flags) {
+            int flags,
+            @OperationType int operationType) {
         UserBackupManagerService userBackupManagerService =
                 getServiceForUserIfCallerHasPermission(userId, "requestBackup()");
 
         return userBackupManagerService == null
                 ? BackupManager.ERROR_BACKUP_NOT_ALLOWED
-                : userBackupManagerService.requestBackup(packages, observer, monitor, flags);
+                : userBackupManagerService.requestBackup(packages, observer, monitor, flags,
+                        operationType);
     }
 
     @Override
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index b7f775b..d6a075f 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -47,6 +47,7 @@
 import android.app.PendingIntent;
 import android.app.backup.BackupAgent;
 import android.app.backup.BackupManager;
+import android.app.backup.BackupManager.OperationType;
 import android.app.backup.BackupManagerMonitor;
 import android.app.backup.FullBackup;
 import android.app.backup.IBackupManager;
@@ -535,11 +536,12 @@
     }
 
     @VisibleForTesting
-    UserBackupManagerService(Context context) {
+    UserBackupManagerService(Context context, PackageManager packageManager) {
         mContext = context;
 
         mUserId = 0;
         mRegisterTransportsRequestedTime = 0;
+        mPackageManager = packageManager;
 
         mBaseStateDir = null;
         mDataDir = null;
@@ -550,7 +552,6 @@
         mRunInitIntent = null;
         mAgentTimeoutParameters = null;
         mTransportManager = null;
-        mPackageManager = null;
         mActivityManagerInternal = null;
         mAlarmManager = null;
         mConstants = null;
@@ -1825,6 +1826,15 @@
      */
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) {
+        return requestBackup(packages, observer, monitor, flags, OperationType.BACKUP);
+    }
+
+    /**
+     * Requests a backup for the inputted {@code packages} with a specified {@link
+     * IBackupManagerMonitor} and {@link OperationType}.
+     */
+    public int requestBackup(String[] packages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, int flags, @OperationType int operationType) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
 
         if (packages == null || packages.length < 1) {
@@ -1872,6 +1882,18 @@
         OnTaskFinishedListener listener =
                 caller -> mTransportManager.disposeOfTransportClient(transportClient, caller);
 
+        Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP);
+        msg.obj = getRequestBackupParams(packages, observer, monitor, flags, operationType,
+                transportClient, transportDirName, listener);
+        mBackupHandler.sendMessage(msg);
+        return BackupManager.SUCCESS;
+    }
+
+    @VisibleForTesting
+    BackupParams getRequestBackupParams(String[] packages, IBackupObserver observer,
+            IBackupManagerMonitor monitor, int flags, @OperationType int operationType,
+            TransportClient transportClient, String transportDirName,
+            OnTaskFinishedListener listener) {
         ArrayList<String> fullBackupList = new ArrayList<>();
         ArrayList<String> kvBackupList = new ArrayList<>();
         for (String packageName : packages) {
@@ -1882,12 +1904,13 @@
             try {
                 PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageName,
                         PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
-                if (!AppBackupUtils.appIsEligibleForBackup(packageInfo.applicationInfo, mUserId)) {
+                if (!appIsEligibleForBackup(packageInfo.applicationInfo, mUserId,
+                        operationType)) {
                     BackupObserverUtils.sendBackupOnPackageResult(observer, packageName,
                             BackupManager.ERROR_BACKUP_NOT_ALLOWED);
                     continue;
                 }
-                if (AppBackupUtils.appGetsFullBackup(packageInfo)) {
+                if (appGetsFullBackup(packageInfo, operationType)) {
                     fullBackupList.add(packageInfo.packageName);
                 } else {
                     kvBackupList.add(packageInfo.packageName);
@@ -1897,6 +1920,7 @@
                         BackupManager.ERROR_PACKAGE_NOT_FOUND);
             }
         }
+
         EventLog.writeEvent(EventLogTags.BACKUP_REQUESTED, packages.length, kvBackupList.size(),
                 fullBackupList.size());
         if (MORE_DEBUG) {
@@ -1915,11 +1939,20 @@
 
         boolean nonIncrementalBackup = (flags & BackupManager.FLAG_NON_INCREMENTAL_BACKUP) != 0;
 
-        Message msg = mBackupHandler.obtainMessage(MSG_REQUEST_BACKUP);
-        msg.obj = new BackupParams(transportClient, transportDirName, kvBackupList, fullBackupList,
-                observer, monitor, listener, true, nonIncrementalBackup);
-        mBackupHandler.sendMessage(msg);
-        return BackupManager.SUCCESS;
+        return new BackupParams(transportClient, transportDirName, kvBackupList, fullBackupList,
+                observer, monitor, listener, /* userInitiated */ true, nonIncrementalBackup,
+                operationType);
+    }
+
+    @VisibleForTesting
+    boolean appIsEligibleForBackup(ApplicationInfo applicationInfo, int userId,
+            @OperationType int operationType) {
+        return AppBackupUtils.appIsEligibleForBackup(applicationInfo, userId, operationType);
+    }
+
+    @VisibleForTesting
+    boolean appGetsFullBackup(PackageInfo packageInfo, @OperationType int operationType) {
+        return AppBackupUtils.appGetsFullBackup(packageInfo, operationType);
     }
 
     /** Cancel all running backups. */
diff --git a/services/backup/java/com/android/server/backup/params/BackupParams.java b/services/backup/java/com/android/server/backup/params/BackupParams.java
index 2ba8ec1..514434e 100644
--- a/services/backup/java/com/android/server/backup/params/BackupParams.java
+++ b/services/backup/java/com/android/server/backup/params/BackupParams.java
@@ -16,6 +16,7 @@
 
 package com.android.server.backup.params;
 
+import android.app.backup.BackupManager.OperationType;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
 
@@ -35,11 +36,12 @@
     public OnTaskFinishedListener listener;
     public boolean userInitiated;
     public boolean nonIncrementalBackup;
+    @OperationType public int operationType;
 
     public BackupParams(TransportClient transportClient, String dirName,
             ArrayList<String> kvPackages, ArrayList<String> fullPackages, IBackupObserver observer,
             IBackupManagerMonitor monitor, OnTaskFinishedListener listener, boolean userInitiated,
-            boolean nonIncrementalBackup) {
+            boolean nonIncrementalBackup, int operationType) {
         this.transportClient = transportClient;
         this.dirName = dirName;
         this.kvPackages = kvPackages;
@@ -49,5 +51,6 @@
         this.listener = listener;
         this.userInitiated = userInitiated;
         this.nonIncrementalBackup = nonIncrementalBackup;
+        this.operationType = operationType;
     }
 }
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 35dfccf..a616e0e 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -23,6 +23,7 @@
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.Nullable;
+import android.app.backup.BackupManager.OperationType;
 import android.app.backup.BackupTransport;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -66,14 +67,23 @@
      */
     public static boolean appIsEligibleForBackup(ApplicationInfo app, int userId) {
         return appIsEligibleForBackup(
-                app, LocalServices.getService(PackageManagerInternal.class), userId);
+                app, LocalServices.getService(PackageManagerInternal.class), userId,
+                OperationType.BACKUP);
+    }
+
+    public static boolean appIsEligibleForBackup(ApplicationInfo app, int userId,
+            @OperationType int operationType) {
+        return appIsEligibleForBackup(
+                app, LocalServices.getService(PackageManagerInternal.class), userId, operationType);
     }
 
     @VisibleForTesting
     static boolean appIsEligibleForBackup(
-            ApplicationInfo app, PackageManagerInternal packageManager, int userId) {
+            ApplicationInfo app, PackageManagerInternal packageManager, int userId,
+            @OperationType int operationType) {
         // 1. their manifest states android:allowBackup="false"
-        if ((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
+        boolean appAllowsBackup = (app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0;
+        if (!appAllowsBackup && !forceFullBackup(app.uid, operationType)) {
             return false;
         }
 
@@ -189,6 +199,16 @@
      * policy!
      */
     public static boolean appGetsFullBackup(PackageInfo pkg) {
+        return appGetsFullBackup(pkg, OperationType.BACKUP);
+    }
+
+    @VisibleForTesting
+    public static boolean appGetsFullBackup(PackageInfo pkg, @OperationType int operationType) {
+        if (forceFullBackup(pkg.applicationInfo.uid, operationType)) {
+            // If this is a migration, all non-system packages get full backup.
+            return true;
+        }
+
         if (pkg.applicationInfo.backupAgentName != null) {
             // If it has an agent, it gets full backups only if it says so
             return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FULL_BACKUP_ONLY) != 0;
@@ -198,6 +218,16 @@
         return true;
     }
 
+    public static boolean appIgnoresIncludeExcludeRules(ApplicationInfo app,
+            @OperationType int operationType) {
+        return forceFullBackup(app.uid, operationType);
+    }
+
+    private static boolean forceFullBackup(int appUid, @OperationType int operationType) {
+        return operationType == OperationType.MIGRATION &&
+                !UserHandle.isCore(appUid);
+    }
+
     /**
      * Returns whether the app is only capable of doing key/value. We say it's not if it allows full
      * backup, and it is otherwise.
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index a91f2f6..e5d0021 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -56,8 +56,7 @@
 
 /**
  * Maintains a binding to the best service that matches the given intent information. Bind and
- * unbind callbacks, as well as all binder operations, will all be run on a single thread, but the
- * exact thread is left undefined.
+ * unbind callbacks, as well as all binder operations, will all be run on a single thread.
  */
 public class ServiceWatcher implements ServiceConnection {
 
@@ -73,7 +72,11 @@
     public interface BinderRunner {
         /** Called to run client code with the binder. */
         void run(IBinder binder) throws RemoteException;
-        /** Called if an error occurred and the function could not be run. */
+        /**
+         * Called if an error occurred and the function could not be run. This callback is only
+         * intended for resource deallocation and cleanup in response to a single binder operation,
+         * it should not be used to propagate errors further.
+         */
         default void onError() {}
     }
 
@@ -189,8 +192,15 @@
     public ServiceWatcher(Context context, String action,
             @Nullable BinderRunner onBind, @Nullable Runnable onUnbind,
             @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
+        this(context, FgThread.getHandler(), action, onBind, onUnbind, enableOverlayResId,
+                nonOverlayPackageResId);
+    }
+
+    public ServiceWatcher(Context context, Handler handler, String action,
+            @Nullable BinderRunner onBind, @Nullable Runnable onUnbind,
+            @BoolRes int enableOverlayResId, @StringRes int nonOverlayPackageResId) {
         mContext = context;
-        mHandler = FgThread.getHandler();
+        mHandler = handler;
         mIntent = new Intent(Objects.requireNonNull(action));
 
         Resources resources = context.getResources();
@@ -278,13 +288,6 @@
         return true;
     }
 
-    /**
-     * Returns information on the currently selected service.
-     */
-    public ServiceInfo getBoundService() {
-        return mServiceInfo;
-    }
-
     private void onBestServiceChanged(boolean forceRebind) {
         Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
 
@@ -380,7 +383,7 @@
     }
 
     @Override
-    public void onBindingDied(ComponentName component) {
+    public final void onBindingDied(ComponentName component) {
         Preconditions.checkState(Looper.myLooper() == mHandler.getLooper());
 
         if (D) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 84bd59b..816d663 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -4532,9 +4532,10 @@
                         ServiceManager.getServiceOrThrow("vold"));
                 for (String pkg : packageList) {
                     final String packageObbDir =
-                            String.format("/storage/emulated/%d/Android/obb/%s/", userId, pkg);
+                            String.format(Locale.US, "/storage/emulated/%d/Android/obb/%s/",
+                                    userId, pkg);
                     final String packageDataDir =
-                            String.format("/storage/emulated/%d/Android/data/%s/",
+                            String.format(Locale.US, "/storage/emulated/%d/Android/data/%s/",
                                     userId, pkg);
 
                     // Create package obb and data dir if it doesn't exist.
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 3d1691d..676b767 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1707,7 +1707,7 @@
             apn = preciseState.getDataConnectionApn();
             state = preciseState.getState();
             networkType = preciseState.getNetworkType();
-            linkProps = preciseState.getDataConnectionLinkProperties();
+            linkProps = preciseState.getLinkProperties();
         }
         if (VDBG) {
             log("notifyDataConnectionForSubscriber: subId=" + subId
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 5124c4a..a2eea13 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -470,22 +470,23 @@
         // if this receiver was slow, impose deferral policy on the app.  This will kick in
         // when processNextBroadcastLocked() next finds this uid as a receiver identity.
         if (!r.timeoutExempt) {
-            if (mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
+            // r.curApp can be null if finish has raced with process death - benign
+            // edge case, and we just ignore it because we're already cleaning up
+            // as expected.
+            if (r.curApp != null
+                    && mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
                 // Core system packages are exempt from deferral policy
                 if (!UserHandle.isCore(r.curApp.uid)) {
                     if (DEBUG_BROADCAST_DEFERRAL) {
                         Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
                                 + " was slow: " + receiver + " br=" + r);
                     }
-                    if (r.curApp != null) {
-                        mDispatcher.startDeferring(r.curApp.uid);
-                    } else {
-                        Slog.d(TAG_BROADCAST, "finish receiver curApp is null? " + r);
-                    }
+                    mDispatcher.startDeferring(r.curApp.uid);
                 } else {
                     if (DEBUG_BROADCAST_DEFERRAL) {
                         Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
-                                + " receiver was slow but not deferring: " + receiver + " br=" + r);
+                                + " receiver was slow but not deferring: "
+                                + receiver + " br=" + r);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/audio/SoundEffectsHelper.java b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
index 84d2ff8..27d5767 100644
--- a/services/core/java/com/android/server/audio/SoundEffectsHelper.java
+++ b/services/core/java/com/android/server/audio/SoundEffectsHelper.java
@@ -441,11 +441,12 @@
                     onUnloadSoundEffects();
                     break;
                 case MSG_PLAY_EFFECT:
+                    final int effect = msg.arg1, volume = msg.arg2;
                     onLoadSoundEffects(new OnEffectsLoadCompleteHandler() {
                         @Override
                         public void run(boolean success) {
                             if (success) {
-                                onPlaySoundEffect(msg.arg1 /*effect*/, msg.arg2 /*volume*/);
+                                onPlaySoundEffect(effect, volume);
                             }
                         }
                     });
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 6be45747..03ca8fa 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -16,6 +16,7 @@
 
 package com.android.server.biometrics;
 
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 
 import static com.android.server.biometrics.PreAuthInfo.AUTHENTICATOR_OK;
@@ -30,19 +31,34 @@
 import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NO_HARDWARE;
 import static com.android.server.biometrics.PreAuthInfo.CREDENTIAL_NOT_ENROLLED;
 
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
 import android.hardware.biometrics.BiometricPrompt.AuthenticationResultType;
+import android.hardware.biometrics.IBiometricService;
 import android.hardware.biometrics.PromptInfo;
+import android.os.Binder;
 import android.os.Build;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Slog;
 
+import com.android.internal.R;
+import com.android.server.biometrics.sensors.ClientMonitor;
+
 public class Utils {
+
+    private static final String TAG = "BiometricUtils";
+
     public static boolean isDebugEnabled(Context context, int targetUserId) {
         if (targetUserId == UserHandle.USER_NULL) {
             return false;
@@ -331,4 +347,58 @@
         }
         return false;
     }
+
+    public static void checkPermission(Context context, String permission) {
+        context.enforceCallingOrSelfPermission(permission,
+                "Must have " + permission + " permission.");
+    }
+
+    public static boolean isCurrentUserOrProfile(Context context, int userId) {
+        UserManager um = UserManager.get(context);
+        if (um == null) {
+            Slog.e(TAG, "Unable to get UserManager");
+            return false;
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            // Allow current user or profiles of the current user...
+            for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
+                if (profileId == userId) {
+                    return true;
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+
+        return false;
+    }
+
+    public static boolean isStrongBiometric(int sensorId) {
+        IBiometricService service = IBiometricService.Stub.asInterface(
+                ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+        try {
+            return Utils.isAtLeastStrength(service.getCurrentStrength(sensorId),
+                    Authenticators.BIOMETRIC_STRONG);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "RemoteException", e);
+            return false;
+        }
+    }
+
+    public static boolean isKeyguard(Context context, String clientPackage) {
+        final boolean hasPermission = context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
+                == PackageManager.PERMISSION_GRANTED;
+
+        final ComponentName keyguardComponent = ComponentName.unflattenFromString(
+                context.getResources().getString(R.string.config_keyguardComponent));
+        final String keyguardPackage = keyguardComponent != null
+                ? keyguardComponent.getPackageName() : null;
+        return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage);
+    }
+
+    public static String getClientName(@Nullable ClientMonitor<?> client) {
+        return client != null ? client.getClass().getSimpleName() : "null";
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
index 68cc884..f8e8dd9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java
@@ -32,8 +32,7 @@
  * Abstract {@link ClientMonitor} subclass that operations eligible/interested in acquisition
  * messages should extend.
  */
-public abstract class AcquisitionClient<T> extends ClientMonitor<T>
-        implements ErrorConsumer, Cancellable {
+public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements Interruptable {
 
     private static final String TAG = "Biometrics/AcquisitionClient";
 
@@ -46,6 +45,7 @@
     private final PowerManager mPowerManager;
     private final VibrationEffect mSuccessVibrationEffect;
     private final VibrationEffect mErrorVibrationEffect;
+    private boolean mShouldSendErrorToClient;
 
     /**
      * Stops the HAL operation specific to the ClientMonitor subclass.
@@ -75,15 +75,43 @@
 
     @Override
     public void onError(int errorCode, int vendorCode) {
-        logOnError(getContext(), errorCode, vendorCode, getTargetUserId());
+        // Errors from the HAL always finish the client
+        onErrorInternal(errorCode, vendorCode, true /* finish */);
+    }
+
+    protected void onErrorInternal(int errorCode, int vendorCode, boolean finish) {
+        // In some cases, the framework will send an error to the caller before a true terminal
+        // case (success, failure, or error) is received from the HAL (e.g. versions of fingerprint
+        // that do not handle lockout under the HAL. In these cases, ensure that the framework only
+        // sends errors once per ClientMonitor.
+        if (!mShouldSendErrorToClient) {
+            logOnError(getContext(), errorCode, vendorCode, getTargetUserId());
+            try {
+                if (getListener() != null) {
+                    mShouldSendErrorToClient = true;
+                    getListener().onError(getSensorId(), getCookie(), errorCode, vendorCode);
+                }
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to invoke sendError", e);
+            }
+        }
+
+        if (finish) {
+            mFinishCallback.onClientFinished(this, false /* success */);
+        }
+    }
+
+    @Override
+    public void cancelWithoutStarting(@NonNull FinishCallback finishCallback) {
+        final int errorCode = BiometricConstants.BIOMETRIC_ERROR_CANCELED;
         try {
             if (getListener() != null) {
-                getListener().onError(getSensorId(), getCookie(), errorCode, vendorCode);
+                getListener().onError(getSensorId(), getCookie(), errorCode, 0 /* vendorCode */);
             }
         } catch (RemoteException e) {
             Slog.w(TAG, "Failed to invoke sendError", e);
         }
-        mFinishCallback.onClientFinished(this, false /* success */);
+        finishCallback.onClientFinished(this, true /* success */);
     }
 
     /**
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index df836d5..fdc3def 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -17,6 +17,7 @@
 package com.android.server.biometrics.sensors;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityTaskManager;
 import android.app.IActivityTaskManager;
 import android.app.TaskStackListener;
@@ -41,7 +42,7 @@
     private final boolean mIsStrongBiometric;
     private final boolean mRequireConfirmation;
     private final IActivityTaskManager mActivityTaskManager;
-    private final TaskStackListener mTaskStackListener;
+    @Nullable private final TaskStackListener mTaskStackListener;
     private final LockoutTracker mLockoutTracker;
     private final boolean mIsRestricted;
 
@@ -56,7 +57,7 @@
             @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
             int targetUserId, long operationId, boolean restricted, @NonNull String owner,
             int cookie, boolean requireConfirmation, int sensorId, boolean isStrongBiometric,
-            int statsModality, int statsClient, @NonNull TaskStackListener taskStackListener,
+            int statsModality, int statsClient, @Nullable TaskStackListener taskStackListener,
             @NonNull LockoutTracker lockoutTracker) {
         super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
                 statsModality, BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
@@ -119,6 +120,13 @@
                     + ", requireConfirmation: " + mRequireConfirmation
                     + ", user: " + getTargetUserId());
 
+            final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
+            if (isCryptoOperation()) {
+                pm.incrementCryptoAuthForUser(getTargetUserId(), authenticated);
+            } else {
+                pm.incrementAuthForUser(getTargetUserId(), authenticated);
+            }
+
             if (authenticated) {
                 mAlreadyDone = true;
 
@@ -126,10 +134,12 @@
                     vibrateSuccess();
                 }
 
-                try {
-                    mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-                } catch (RemoteException e) {
-                    Slog.e(TAG, "Could not unregister task stack listener", e);
+                if (mTaskStackListener != null) {
+                    try {
+                        mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Could not unregister task stack listener", e);
+                    }
                 }
 
                 final byte[] byteToken = new byte[hardwareAuthToken.size()];
@@ -184,6 +194,18 @@
         }
     }
 
+    @Override
+    public void onAcquired(int acquiredInfo, int vendorCode) {
+        super.onAcquired(acquiredInfo, vendorCode);
+
+        final @LockoutTracker.LockoutMode int lockoutMode =
+                mLockoutTracker.getLockoutModeForUser(getTargetUserId());
+        if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
+            PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
+            pt.incrementAcquireForUser(getTargetUserId(), isCryptoOperation());
+        }
+    }
+
     /**
      * Start authentication
      */
@@ -202,10 +224,12 @@
             return;
         }
 
-        try {
-            mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Could not register task stack listener", e);
+        if (mTaskStackListener != null) {
+            try {
+                mActivityTaskManager.registerTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Could not register task stack listener", e);
+            }
         }
 
         if (DEBUG) Slog.w(TAG, "Requesting auth for " + getOwnerString());
@@ -222,10 +246,12 @@
             return;
         }
 
-        try {
-            mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Could not unregister task stack listener", e);
+        if (mTaskStackListener != null) {
+            try {
+                mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Could not unregister task stack listener", e);
+            }
         }
 
         if (DEBUG) Slog.w(TAG, "Requesting cancel for " + getOwnerString());
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
new file mode 100644
index 0000000..6bdd783
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.biometrics.IBiometricService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.text.SimpleDateFormat;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Queue;
+
+/**
+ * A scheduler for biometric HAL operations. Maintains a queue of {@link ClientMonitor} operations,
+ * without caring about its implementation details. Operations may perform one or more
+ * interactions with the HAL before finishing.
+ */
+public class BiometricScheduler {
+
+    private static final String BASE_TAG = "BiometricScheduler";
+
+    /**
+     * Contains all the necessary information for a HAL operation.
+     */
+    private static final class Operation {
+
+        /**
+         * The operation is added to the list of pending operations and waiting for its turn.
+         */
+        static final int STATE_WAITING_IN_QUEUE = 0;
+
+        /**
+         * The operation is added to the list of pending operations, but a subsequent operation
+         * has been added. This state only applies to {@link Interruptable} operations. When this
+         * operation reaches the head of the queue, it will send ERROR_CANCELED and finish.
+         */
+        static final int STATE_WAITING_IN_QUEUE_CANCELING = 1;
+
+        /**
+         * The operation has reached the front of the queue and has started.
+         */
+        static final int STATE_STARTED = 2;
+
+        /**
+         * The operation was started, but is now canceling. Operations should wait for the HAL to
+         * acknowledge that the operation was canceled, at which point it finishes.
+         */
+        static final int STATE_STARTED_CANCELING = 3;
+
+        /**
+         * The operation has reached the head of the queue but is waiting for BiometricService
+         * to acknowledge and start the operation.
+         */
+        static final int STATE_WAITING_FOR_COOKIE = 4;
+
+        /**
+         * The {@link ClientMonitor.FinishCallback} has been invoked and the client is finished.
+         */
+        static final int STATE_FINISHED = 5;
+
+        @IntDef({STATE_WAITING_IN_QUEUE,
+                STATE_WAITING_IN_QUEUE_CANCELING,
+                STATE_STARTED,
+                STATE_STARTED_CANCELING,
+                STATE_WAITING_FOR_COOKIE,
+                STATE_FINISHED})
+        @Retention(RetentionPolicy.SOURCE)
+        @interface OperationState {}
+
+        @NonNull final ClientMonitor<?> clientMonitor;
+        @Nullable final ClientMonitor.FinishCallback clientFinishCallback;
+        @OperationState int state;
+
+        Operation(@NonNull ClientMonitor<?> clientMonitor,
+                @Nullable ClientMonitor.FinishCallback finishCallback) {
+            this.clientMonitor = clientMonitor;
+            this.clientFinishCallback = finishCallback;
+            state = STATE_WAITING_IN_QUEUE;
+        }
+
+        @Override
+        public String toString() {
+            return clientMonitor + ", State: " + state;
+        }
+    }
+
+    /**
+     * Monitors an operation's cancellation. If cancellation takes too long, the watchdog will
+     * kill the current operation and forcibly start the next.
+     */
+    private static final class CancellationWatchdog implements Runnable {
+        static final int DELAY_MS = 3000;
+
+        final String tag;
+        final Operation operation;
+        CancellationWatchdog(String tag, Operation operation) {
+            this.tag = tag;
+            this.operation = operation;
+        }
+
+        @Override
+        public void run() {
+            if (operation.state != Operation.STATE_FINISHED) {
+                Slog.e(tag, "[Watchdog Triggered]: " + operation);
+                operation.clientMonitor.mFinishCallback
+                        .onClientFinished(operation.clientMonitor, false /* success */);
+            }
+        }
+    }
+
+    private static final class CrashState {
+        static final int NUM_ENTRIES = 10;
+        final String timestamp;
+        final String currentOperation;
+        final List<String> pendingOperations;
+
+        CrashState(String timestamp, String currentOperation, List<String> pendingOperations) {
+            this.timestamp = timestamp;
+            this.currentOperation = currentOperation;
+            this.pendingOperations = pendingOperations;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder();
+            sb.append(timestamp).append(": ");
+            sb.append("Current Operation: {").append(currentOperation).append("}");
+            sb.append(", Pending Operations(").append(pendingOperations.size()).append(")");
+
+            if (!pendingOperations.isEmpty()) {
+                sb.append(": ");
+            }
+            for (int i = 0; i < pendingOperations.size(); i++) {
+                sb.append(pendingOperations.get(i));
+                if (i < pendingOperations.size() - 1) {
+                    sb.append(", ");
+                }
+            }
+            return sb.toString();
+        }
+    }
+
+    @NonNull private final String mBiometricTag;
+    @Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
+    @NonNull private final IBiometricService mBiometricService;
+    @NonNull private final Handler mHandler = new Handler(Looper.getMainLooper());
+    @NonNull private final InternalFinishCallback mInternalFinishCallback;
+    @NonNull private final Queue<Operation> mPendingOperations;
+    @Nullable private Operation mCurrentOperation;
+    @NonNull private final ArrayDeque<CrashState> mCrashStates;
+
+    // Internal finish callback, notified when an operation is complete. Notifies the requester
+    // that the operation is complete, before performing internal scheduler work (such as
+    // starting the next client).
+    private class InternalFinishCallback implements ClientMonitor.FinishCallback {
+        @Override
+        public void onClientFinished(ClientMonitor<?> clientMonitor, boolean success) {
+            mHandler.post(() -> {
+                if (mCurrentOperation == null) {
+                    Slog.e(getTag(), "[Finishing] " + clientMonitor
+                            + " but current operation is null, success: " + success
+                            + ", possible lifecycle bug in clientMonitor implementation?");
+                    return;
+                }
+
+                mCurrentOperation.state = Operation.STATE_FINISHED;
+
+                if (mCurrentOperation.clientFinishCallback != null) {
+                    mCurrentOperation.clientFinishCallback.onClientFinished(clientMonitor, success);
+                }
+
+                if (clientMonitor != mCurrentOperation.clientMonitor) {
+                    throw new IllegalStateException("Mismatched operation, "
+                            + " current: " + mCurrentOperation.clientMonitor
+                            + " received: " + clientMonitor);
+                }
+
+                Slog.d(getTag(), "[Finished] " + clientMonitor + ", success: " + success);
+                if (mGestureAvailabilityDispatcher != null) {
+                    mGestureAvailabilityDispatcher.markSensorActive(
+                            mCurrentOperation.clientMonitor.getSensorId(), false /* active */);
+                }
+
+                mCurrentOperation = null;
+                startNextOperationIfIdle();
+            });
+        }
+    }
+
+    /**
+     * Creates a new scheduler.
+     * @param tag for the specific instance of the scheduler. Should be unique.
+     * @param gestureAvailabilityDispatcher may be null if the sensor does not support gestures
+     *                                      (such as fingerprint swipe).
+     */
+    public BiometricScheduler(@NonNull String tag,
+            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
+        mBiometricTag = tag;
+        mInternalFinishCallback = new InternalFinishCallback();
+        mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher;
+        mPendingOperations = new ArrayDeque<>();
+        mBiometricService = IBiometricService.Stub.asInterface(
+                ServiceManager.getService(Context.BIOMETRIC_SERVICE));
+        mCrashStates = new ArrayDeque<>();
+    }
+
+    private String getTag() {
+        return BASE_TAG + "/" + mBiometricTag;
+    }
+
+    private void startNextOperationIfIdle() {
+        if (mCurrentOperation != null) {
+            Slog.v(getTag(), "Not idle, current operation: " + mCurrentOperation);
+            return;
+        }
+        if (mPendingOperations.isEmpty()) {
+            Slog.d(getTag(), "No operations, returning to idle");
+            return;
+        }
+
+        mCurrentOperation = mPendingOperations.poll();
+        final ClientMonitor<?> currentClient = mCurrentOperation.clientMonitor;
+
+        // If the operation at the front of the queue has been marked for cancellation, send
+        // ERROR_CANCELED. No need to start this client.
+        if (mCurrentOperation.state == Operation.STATE_WAITING_IN_QUEUE_CANCELING) {
+            Slog.d(getTag(), "[Now Cancelling] " + mCurrentOperation);
+            if (!(currentClient instanceof Interruptable)) {
+                throw new IllegalStateException("Mis-implemented client or scheduler, "
+                        + "trying to cancel non-interruptable operation: " + mCurrentOperation);
+            }
+
+            final Interruptable interruptable = (Interruptable) currentClient;
+            interruptable.cancelWithoutStarting(mInternalFinishCallback);
+            // Now we wait for the client to send its FinishCallback, which kicks off the next
+            // operation.
+            return;
+        }
+
+        if (mGestureAvailabilityDispatcher != null
+                && mCurrentOperation.clientMonitor instanceof AcquisitionClient) {
+            mGestureAvailabilityDispatcher.markSensorActive(
+                    mCurrentOperation.clientMonitor.getSensorId(),
+                    true /* active */);
+        }
+
+        // Not all operations start immediately. BiometricPrompt waits for its operation
+        // to arrive at the head of the queue, before pinging it to start.
+        final boolean shouldStartNow = currentClient.getCookie() == 0;
+        if (shouldStartNow) {
+            Slog.d(getTag(), "[Starting] " + mCurrentOperation);
+            currentClient.start(mInternalFinishCallback);
+            mCurrentOperation.state = Operation.STATE_STARTED;
+        } else {
+            try {
+                mBiometricService.onReadyForAuthentication(currentClient.getCookie());
+            } catch (RemoteException e) {
+                Slog.e(getTag(), "Remote exception when contacting BiometricService", e);
+            }
+            Slog.d(getTag(), "Waiting for cookie before starting: " + mCurrentOperation);
+            mCurrentOperation.state = Operation.STATE_WAITING_FOR_COOKIE;
+        }
+    }
+
+    /**
+     * Starts the {@link #mCurrentOperation} if
+     * 1) its state is {@link Operation#STATE_WAITING_FOR_COOKIE} and
+     * 2) its cookie matches this cookie
+     *
+     * This is currently only used by {@link com.android.server.biometrics.BiometricService}, which
+     * requests sensors to prepare for authentication with a cookie. Once sensor(s) are ready (e.g.
+     * the BiometricService client becomes the current client in the scheduler), the cookie is
+     * returned to BiometricService. Once BiometricService decides that authentication can start,
+     * it invokes this code path.
+     *
+     * @param cookie of the operation to be started
+     */
+    public void startPreparedClient(int cookie) {
+        if (mCurrentOperation == null) {
+            Slog.e(getTag(), "Current operation is null");
+            return;
+        }
+        if (mCurrentOperation.state != Operation.STATE_WAITING_FOR_COOKIE) {
+            Slog.e(getTag(), "Operation is in the wrong state: " + mCurrentOperation
+                    + ", expected STATE_WAITING_FOR_COOKIE");
+            return;
+        }
+        if (mCurrentOperation.clientMonitor.getCookie() != cookie) {
+            Slog.e(getTag(), "Mismatched cookie for operation: " + mCurrentOperation
+                    + ", received: " + cookie);
+            return;
+        }
+
+        Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation);
+        mCurrentOperation.state = Operation.STATE_STARTED;
+        mCurrentOperation.clientMonitor.start(mInternalFinishCallback);
+    }
+
+    /**
+     * Adds a {@link ClientMonitor} to the pending queue
+     *
+     * @param clientMonitor operation to be scheduled
+     */
+    public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor) {
+        scheduleClientMonitor(clientMonitor, null /* clientFinishCallback */);
+    }
+
+    /**
+     * Adds a {@link ClientMonitor} to the pending queue
+     *
+     * @param clientMonitor        operation to be scheduled
+     * @param clientFinishCallback optional callback, invoked when the client is finished, but
+     *                             before it has been removed from the queue.
+     */
+    public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor,
+            @Nullable ClientMonitor.FinishCallback clientFinishCallback) {
+        // Mark any interruptable pending clients as canceling. Once they reach the head of the
+        // queue, the scheduler will send ERROR_CANCELED and skip the operation.
+        for (Operation operation : mPendingOperations) {
+            if (operation.clientMonitor instanceof Interruptable
+                    && operation.state != Operation.STATE_WAITING_IN_QUEUE_CANCELING) {
+                Slog.d(getTag(), "New client incoming, marking pending client as canceling: "
+                        + operation.clientMonitor);
+                operation.state = Operation.STATE_WAITING_IN_QUEUE_CANCELING;
+            }
+        }
+
+        mPendingOperations.add(new Operation(clientMonitor, clientFinishCallback));
+        Slog.d(getTag(), "[Added] " + clientMonitor
+                + ", new queue size: " + mPendingOperations.size());
+
+        // If the current operation is cancellable, start the cancellation process.
+        if (mCurrentOperation != null && mCurrentOperation.clientMonitor instanceof Interruptable
+                && mCurrentOperation.state == Operation.STATE_STARTED) {
+            Slog.d(getTag(), "[Cancelling Interruptable]: " + mCurrentOperation);
+            cancelInternal(mCurrentOperation);
+        }
+
+        startNextOperationIfIdle();
+    }
+
+    private void cancelInternal(Operation operation) {
+        if (operation != mCurrentOperation) {
+            Slog.e(getTag(), "cancelInternal invoked on non-current operation: " + operation);
+            return;
+        }
+        if (!(operation.clientMonitor instanceof Interruptable)) {
+            Slog.w(getTag(), "Operation not interruptable: " + operation);
+            return;
+        }
+        if (operation.state == Operation.STATE_STARTED_CANCELING) {
+            Slog.w(getTag(), "Cancel already invoked for operation: " + operation);
+            return;
+        }
+        Slog.d(getTag(), "[Cancelling] Current client: " + operation.clientMonitor);
+        final Interruptable interruptable = (Interruptable) operation.clientMonitor;
+        interruptable.cancel();
+        operation.state = Operation.STATE_STARTED_CANCELING;
+
+        // Add a watchdog. If the HAL does not acknowledge within the timeout, we will
+        // forcibly finish this client.
+        mHandler.postDelayed(new CancellationWatchdog(getTag(), operation),
+                CancellationWatchdog.DELAY_MS);
+    }
+
+    /**
+     * Requests to cancel enrollment.
+     * @param token from the caller, should match the token passed in when requesting enrollment
+     */
+    public void cancelEnrollment(IBinder token) {
+        if (mCurrentOperation == null) {
+            Slog.e(getTag(), "Unable to cancel enrollment, null operation");
+            return;
+        }
+        final boolean isEnrolling = mCurrentOperation.clientMonitor instanceof EnrollClient;
+        final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token;
+        if (!isEnrolling || !tokenMatches) {
+            Slog.w(getTag(), "Not cancelling enrollment, isEnrolling: " + isEnrolling
+                    + " tokenMatches: " + tokenMatches);
+            return;
+        }
+
+        cancelInternal(mCurrentOperation);
+    }
+
+    /**
+     * Requests to cancel authentication.
+     * @param token from the caller, should match the token passed in when requesting authentication
+     */
+    public void cancelAuthentication(IBinder token) {
+        if (mCurrentOperation == null) {
+            Slog.e(getTag(), "Unable to cancel authentication, null operation");
+            return;
+        }
+        final boolean isAuthenticating =
+                mCurrentOperation.clientMonitor instanceof AuthenticationClient;
+        final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token;
+        if (!isAuthenticating || !tokenMatches) {
+            Slog.w(getTag(), "Not cancelling authentication, isEnrolling: " + isAuthenticating
+                    + " tokenMatches: " + tokenMatches);
+            return;
+        }
+
+        cancelInternal(mCurrentOperation);
+    }
+
+    /**
+     * @return the current operation
+     */
+    public ClientMonitor<?> getCurrentClient() {
+        if (mCurrentOperation == null) {
+            return null;
+        }
+        return mCurrentOperation.clientMonitor;
+    }
+
+    public void recordCrashState() {
+        if (mCrashStates.size() >= CrashState.NUM_ENTRIES) {
+            mCrashStates.removeFirst();
+        }
+        final SimpleDateFormat dateFormat =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
+        final String timestamp = dateFormat.format(new Date(System.currentTimeMillis()));
+        final List<String> pendingOperations = new ArrayList<>();
+        for (Operation operation : mPendingOperations) {
+            pendingOperations.add(operation.toString());
+        }
+
+        final CrashState crashState = new CrashState(timestamp,
+                mCurrentOperation != null ? mCurrentOperation.toString() : null,
+                pendingOperations);
+        mCrashStates.add(crashState);
+        Slog.e(getTag(), "Recorded crash state: " + crashState.toString());
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("Dump of BiometricScheduler " + getTag());
+        for (CrashState crashState : mCrashStates) {
+            pw.println("Crash State " + crashState);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java
deleted file mode 100644
index 9f5abd8..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java
+++ /dev/null
@@ -1,854 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
-import static android.hardware.biometrics.BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
-
-import android.app.ActivityManager;
-import android.app.ActivityTaskManager;
-import android.app.AppOpsManager;
-import android.app.IActivityTaskManager;
-import android.app.SynchronousUserSwitchObserver;
-import android.app.TaskStackListener;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricConstants;
-import android.hardware.biometrics.BiometricManager.Authenticators;
-import android.hardware.biometrics.BiometricsProtoEnums;
-import android.hardware.biometrics.IBiometricService;
-import android.hardware.fingerprint.Fingerprint;
-import android.os.Binder;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IHwBinder;
-import android.os.Looper;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Slog;
-
-import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.util.FrameworkStatsLog;
-import com.android.server.SystemService;
-import com.android.server.biometrics.Utils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Abstract base class containing all of the business logic for biometric services, e.g.
- * Fingerprint, Face, Iris.
- *
- * @hide
- */
-public abstract class BiometricServiceBase<T> extends SystemService
-        implements IHwBinder.DeathRecipient {
-
-    protected static final boolean DEBUG = true;
-
-    private static final int MSG_USER_SWITCHING = 10;
-    private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
-
-    private final Context mContext;
-    private final String mKeyguardPackage;
-    protected final IActivityTaskManager mActivityTaskManager;
-    protected final BiometricTaskStackListener mTaskStackListener =
-            new BiometricTaskStackListener();
-    private final ResetClientStateRunnable mResetClientState = new ResetClientStateRunnable();
-
-    protected final IStatusBarService mStatusBarService;
-    protected final Map<Integer, Long> mAuthenticatorIds =
-            Collections.synchronizedMap(new HashMap<>());
-    protected final AppOpsManager mAppOps;
-
-    /**
-     * Handler which all subclasses should post events to.
-     */
-    protected final Handler mHandler = new Handler(Looper.getMainLooper()) {
-        @Override
-        public void handleMessage(android.os.Message msg) {
-            switch (msg.what) {
-                case MSG_USER_SWITCHING:
-                    handleUserSwitching(msg.arg1);
-                    break;
-                default:
-                    Slog.w(getTag(), "Unknown message:" + msg.what);
-            }
-        }
-    };
-
-    protected final ClientMonitor.FinishCallback mClientFinishCallback =
-            (clientMonitor, success) -> {
-        removeClient(clientMonitor);
-        // When enrollment finishes, update this group's authenticator id, as the HAL has
-        // already generated a new authenticator id when the new biometric is enrolled.
-        if (clientMonitor instanceof EnrollClient) {
-            updateActiveGroup(clientMonitor.getTargetUserId());
-        }
-    };
-
-    private IBiometricService mBiometricService;
-    private ClientMonitor<T> mCurrentClient;
-    private ClientMonitor<T> mPendingClient;
-    private PerformanceTracker mPerformanceTracker;
-    private int mSensorId;
-    protected int mCurrentUserId = UserHandle.USER_NULL;
-
-    /**
-     * @return the log tag.
-     */
-    protected abstract String getTag();
-
-    /**
-     * @return a fresh reference to the biometric HAL
-     */
-    protected abstract T getDaemon();
-
-    /**
-     * @return the biometric utilities for a specific implementation.
-     */
-    protected abstract BiometricUtils getBiometricUtils();
-
-    /**
-     * @param userId
-     * @return true if the enrollment limit has been reached.
-     */
-    protected abstract boolean hasReachedEnrollmentLimit(int userId);
-
-    /**
-     * Notifies the HAL that the user has changed.
-     * @param userId
-     */
-    protected abstract void updateActiveGroup(int userId);
-
-    /**
-     * @param userId
-     * @return Returns true if the user has any enrolled biometrics.
-     */
-    protected abstract boolean hasEnrolledBiometrics(int userId);
-
-    /**
-     * @return Returns the MANAGE_* permission string, which is required for enrollment, removal
-     * etc.
-     */
-    protected abstract String getManageBiometricPermission();
-
-    /**
-     * Checks if the caller has permission to use the biometric service - throws a SecurityException
-     * if not.
-     */
-    protected abstract void checkUseBiometricPermission();
-
-    /**
-     * Checks if the caller passes the app ops check
-     */
-    protected abstract boolean checkAppOps(int uid, String opPackageName);
-
-    protected abstract List<? extends BiometricAuthenticator.Identifier> getEnrolledTemplates(
-            int userId);
-
-    /**
-     * Notifies clients of any change in the biometric state (active / idle). This is mainly for
-     * Fingerprint navigation gestures.
-     * @param isActive
-     */
-    protected void notifyClientActiveCallbacks(boolean isActive) {}
-
-    protected abstract int statsModality();
-
-    /**
-     * @return one of the AuthenticationClient LOCKOUT constants
-     */
-    protected abstract @LockoutTracker.LockoutMode int getLockoutMode(int userId);
-
-    private final Runnable mOnTaskStackChangedRunnable = new Runnable() {
-        @Override
-        public void run() {
-            try {
-                if (!(mCurrentClient instanceof AuthenticationClient)) {
-                    return;
-                }
-                final String currentClient = mCurrentClient.getOwnerString();
-                if (isKeyguard(currentClient)) {
-                    return; // Keyguard is always allowed
-                }
-                List<ActivityManager.RunningTaskInfo> runningTasks =
-                        mActivityTaskManager.getTasks(1);
-                if (!runningTasks.isEmpty()) {
-                    final String topPackage = runningTasks.get(0).topActivity.getPackageName();
-                    if (!topPackage.contentEquals(currentClient)
-                            && !mCurrentClient.isAlreadyDone()) {
-                        Slog.e(getTag(), "Stopping background authentication, top: "
-                                + topPackage + " currentClient: " + currentClient);
-                        ((AuthenticationClient) mCurrentClient).cancel();
-                    }
-                }
-            } catch (RemoteException e) {
-                Slog.e(getTag(), "Unable to get running tasks", e);
-            }
-        }
-    };
-
-    private final class BiometricTaskStackListener extends TaskStackListener {
-        @Override
-        public void onTaskStackChanged() {
-            mHandler.post(mOnTaskStackChangedRunnable);
-        }
-    }
-
-    private final class ResetClientStateRunnable implements Runnable {
-        @Override
-        public void run() {
-            /**
-             * Warning: if we get here, the driver never confirmed our call to cancel the current
-             * operation (authenticate, enroll, remove, enumerate, etc), which is
-             * really bad.  The result will be a 3-second delay in starting each new client.
-             * If you see this on a device, make certain the driver notifies with
-             * {@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} in response to cancel()
-             * once it has successfully switched to the IDLE state in the HAL.
-             * Additionally,{@link BiometricConstants#BIOMETRIC_ERROR_CANCELED} should only be sent
-             * in response to an actual cancel() call.
-             */
-            Slog.w(getTag(), "Client "
-                    + (mCurrentClient != null ? mCurrentClient.getOwnerString() : "null")
-                    + " failed to respond to cancel, starting client "
-                    + (mPendingClient != null ? mPendingClient.getOwnerString() : "null"));
-
-            FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
-                    statsModality(), BiometricsProtoEnums.ISSUE_CANCEL_TIMED_OUT);
-
-            ClientMonitor<T> newClient = mPendingClient;
-            mCurrentClient = null;
-            mPendingClient = null;
-            startClient(newClient, false);
-        }
-    }
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public BiometricServiceBase(Context context) {
-        super(context);
-        mContext = context;
-        mStatusBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        final ComponentName keyguardComponent = ComponentName.unflattenFromString(
-                context.getResources().getString(R.string.config_keyguardComponent));
-        mKeyguardPackage = keyguardComponent != null ? keyguardComponent.getPackageName() : null;
-        mAppOps = context.getSystemService(AppOpsManager.class);
-        mActivityTaskManager = ActivityTaskManager.getService();
-        mPerformanceTracker = PerformanceTracker.getInstanceForSensorId(getSensorId());
-    }
-
-    @Override
-    public void onStart() {
-        listenForUserSwitches();
-    }
-
-    @Override
-    public void serviceDied(long cookie) {
-        Slog.e(getTag(), "HAL died");
-        mPerformanceTracker.incrementHALDeathCount();
-        mCurrentUserId = UserHandle.USER_NULL;
-
-        // All client lifecycle must be managed on the handler.
-        mHandler.post(() -> {
-            Slog.e(getTag(), "Sending BIOMETRIC_ERROR_HW_UNAVAILABLE after HAL crash");
-            handleError(BIOMETRIC_ERROR_HW_UNAVAILABLE, 0 /* vendorCode */);
-        });
-
-        FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
-                statsModality(), BiometricsProtoEnums.ISSUE_HAL_DEATH);
-    }
-
-    protected void initializeConfigurationInternal(int sensorId) {
-        if (DEBUG) {
-            Slog.d(getTag(), "initializeConfigurationInternal(" + sensorId + ")");
-        }
-        mSensorId = sensorId;
-    }
-
-    protected ClientMonitor getCurrentClient() {
-        return mCurrentClient;
-    }
-
-    protected ClientMonitor getPendingClient() {
-        return mPendingClient;
-    }
-
-    protected boolean isStrongBiometric() {
-        IBiometricService service = IBiometricService.Stub.asInterface(
-                ServiceManager.getService(Context.BIOMETRIC_SERVICE));
-        try {
-            return Utils.isAtLeastStrength(service.getCurrentStrength(mSensorId),
-                    Authenticators.BIOMETRIC_STRONG);
-        } catch (RemoteException e) {
-            Slog.e(getTag(), "RemoteException", e);
-            return false;
-        }
-    }
-
-    protected int getSensorId() {
-        return mSensorId;
-    }
-
-    /**
-     * Callback handlers from the daemon. The caller must put this on a handler.
-     */
-
-    protected void handleAcquired(int acquiredInfo, int vendorCode) {
-        final ClientMonitor client = mCurrentClient;
-        if (!(client instanceof AcquisitionClient)) {
-            final String clientName = client != null ? client.getClass().getSimpleName() : "null";
-            Slog.e(getTag(), "handleAcquired for non-acquire consumer: " + clientName);
-            return;
-        }
-
-        final AcquisitionClient acquisitionClient = (AcquisitionClient) client;
-        acquisitionClient.onAcquired(acquiredInfo, vendorCode);
-
-        if (client instanceof AuthenticationClient) {
-            final int userId = client.getTargetUserId();
-            if (getLockoutMode(userId) == LockoutTracker.LOCKOUT_NONE) {
-                mPerformanceTracker.incrementAcquireForUser(userId, client.isCryptoOperation());
-            }
-        }
-    }
-
-    protected void handleAuthenticated(BiometricAuthenticator.Identifier identifier,
-            ArrayList<Byte> token) {
-        final ClientMonitor client = mCurrentClient;
-        if (!(client instanceof AuthenticationClient)) {
-            final String clientName = client != null ? client.getClass().getSimpleName() : "null";
-            Slog.e(getTag(), "handleAuthenticated for non-authentication client: " + clientName);
-            return;
-        }
-
-        final AuthenticationClient authenticationClient = (AuthenticationClient) client;
-        final boolean authenticated = identifier.getBiometricId() != 0;
-
-        final int userId = authenticationClient.getTargetUserId();
-        if (authenticationClient.isCryptoOperation()) {
-            mPerformanceTracker.incrementCryptoAuthForUser(userId, authenticated);
-        } else {
-            mPerformanceTracker.incrementAuthForUser(userId, authenticated);
-        }
-
-        authenticationClient.onAuthenticated(identifier, authenticated, token);
-    }
-
-    protected void handleEnrollResult(BiometricAuthenticator.Identifier identifier,
-            int remaining) {
-        final ClientMonitor client = mCurrentClient;
-        if (!(client instanceof EnrollClient)) {
-            final String clientName = client != null ? client.getClass().getSimpleName() : "null";
-            Slog.e(getTag(), "handleEnrollResult for non-enroll client: " + clientName);
-            return;
-        }
-
-        final EnrollClient enrollClient = (EnrollClient) client;
-        enrollClient.onEnrollResult(identifier, remaining);
-    }
-
-    protected void handleError(int error, int vendorCode) {
-        final ClientMonitor client = mCurrentClient;
-
-        if (DEBUG) Slog.v(getTag(), "handleError(client="
-                + (client != null ? client.getOwnerString() : "null") + ", error = " + error + ")");
-
-        if (!(client instanceof ErrorConsumer)) {
-            Slog.e(getTag(), "error received for non-ErrorConsumer");
-            return;
-        }
-
-        final ErrorConsumer errorConsumer = (ErrorConsumer) client;
-        errorConsumer.onError(error, vendorCode);
-
-        if (error == BiometricConstants.BIOMETRIC_ERROR_CANCELED) {
-            mHandler.removeCallbacks(mResetClientState);
-            if (mPendingClient != null) {
-                if (DEBUG) Slog.v(getTag(), "start pending client " +
-                        mPendingClient.getOwnerString());
-                startClient(mPendingClient, false);
-                mPendingClient = null;
-            }
-        }
-    }
-
-    protected void handleRemoved(BiometricAuthenticator.Identifier identifier,
-            final int remaining) {
-        if (DEBUG) Slog.w(getTag(), "Removed: fid=" + identifier.getBiometricId()
-                + ", dev=" + identifier.getDeviceId()
-                + ", rem=" + remaining);
-
-        final ClientMonitor client = mCurrentClient;
-        if (!(client instanceof RemovalConsumer)) {
-            final String clientName = client != null ? client.getClass().getSimpleName() : "null";
-            Slog.e(getTag(), "handleRemoved for non-removal consumer: " + clientName);
-            return;
-        }
-
-        final RemovalConsumer removalConsumer = (RemovalConsumer) client;
-        removalConsumer.onRemoved(identifier, remaining);
-    }
-
-    protected void handleEnumerate(BiometricAuthenticator.Identifier identifier, int remaining) {
-        final ClientMonitor client = mCurrentClient;
-        if (!(client instanceof EnumerateConsumer)) {
-            final String clientName = client != null ? client.getClass().getSimpleName() : "null";
-            Slog.e(getTag(), "handleEnumerate for non-enumerate consumer: "
-                    + clientName);
-            return;
-        }
-
-        final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
-        enumerateConsumer.onEnumerationResult(identifier, remaining);
-    }
-
-    /**
-     * Calls from the Manager. These are still on the calling binder's thread.
-     */
-
-    protected void enrollInternal(EnrollClient<T> client, int userId) {
-        if (hasReachedEnrollmentLimit(userId)) {
-            return;
-        }
-
-        // Group ID is arbitrarily set to parent profile user ID. It just represents
-        // the default biometrics for the user.
-        if (!isCurrentUserOrProfile(userId)) {
-            return;
-        }
-
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void cancelEnrollmentInternal(IBinder token) {
-        mHandler.post(() -> {
-            ClientMonitor client = mCurrentClient;
-            if (client instanceof EnrollClient && client.getToken() == token) {
-                if (DEBUG) Slog.v(getTag(), "Cancelling enrollment");
-                ((EnrollClient) client).cancel();
-            }
-        });
-    }
-
-    protected void generateChallengeInternal(GenerateChallengeClient<T> client) {
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void revokeChallengeInternal(RevokeChallengeClient<T> client) {
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void authenticateInternal(AuthenticationClient<T> client, String opPackageName) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingPid = Binder.getCallingPid();
-        final int callingUserId = UserHandle.getCallingUserId();
-        authenticateInternal(client, opPackageName, callingUid, callingPid, callingUserId);
-    }
-
-    protected void authenticateInternal(AuthenticationClient<T> client,
-            String opPackageName, int callingUid, int callingPid, int callingUserId) {
-        if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
-                callingUserId)) {
-            if (DEBUG) Slog.v(getTag(), "authenticate(): reject " + opPackageName);
-            return;
-        }
-
-        mHandler.post(() -> {
-            startAuthentication(client, opPackageName);
-        });
-    }
-
-    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName) {
-        final int callingUid = Binder.getCallingUid();
-        final int callingPid = Binder.getCallingPid();
-        final int callingUserId = UserHandle.getCallingUserId();
-        cancelAuthenticationInternal(token, opPackageName, callingUid, callingPid, callingUserId,
-                true /* fromClient */);
-    }
-
-    protected void cancelAuthenticationInternal(final IBinder token, final String opPackageName,
-            int callingUid, int callingPid, int callingUserId, boolean fromClient) {
-
-        if (DEBUG) Slog.v(getTag(), "cancelAuthentication(" + opPackageName + ")");
-        if (fromClient) {
-            // Only check this if cancel was called from the client (app). If cancel was called
-            // from BiometricService, it means the dialog was dismissed due to user interaction.
-            if (!canUseBiometric(opPackageName, true /* foregroundOnly */, callingUid, callingPid,
-                    callingUserId)) {
-                if (DEBUG) {
-                    Slog.v(getTag(), "cancelAuthentication(): reject " + opPackageName);
-                }
-                return;
-            }
-        }
-
-        mHandler.post(() -> {
-            ClientMonitor client = mCurrentClient;
-            if (client instanceof AuthenticationClient) {
-                if (client.getToken() == token || !fromClient) {
-                    if (DEBUG) Slog.v(getTag(), "Stopping client " + client.getOwnerString()
-                            + ", fromClient: " + fromClient);
-                    // If cancel was from BiometricService, it means the dialog was dismissed
-                    // and authentication should be canceled.
-                    ((AuthenticationClient) client).cancel();
-                } else {
-                    if (DEBUG) Slog.v(getTag(), "Can't stop client " + client.getOwnerString()
-                            + " since tokens don't match. fromClient: " + fromClient);
-                }
-            } else if (client != null) {
-                if (DEBUG) Slog.v(getTag(), "Can't cancel non-authenticating client "
-                        + client.getOwnerString());
-            }
-        });
-    }
-
-    protected void removeInternal(RemovalClient<T> client) {
-        mHandler.post(() -> {
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    protected void cleanupInternal(
-            InternalCleanupClient<? extends BiometricAuthenticator.Identifier, T> client) {
-        mHandler.post(() -> {
-            if (DEBUG) {
-                Slog.v(getTag(), "Cleaning up templates for user("
-                        + client.getTargetUserId() + ")");
-            }
-            startClient(client, true /* initiatedByClient */);
-        });
-    }
-
-    // Should be done on a handler thread - not on the Binder's thread.
-    private void startAuthentication(AuthenticationClient<T> client, String opPackageName) {
-        if (DEBUG) Slog.v(getTag(), "startAuthentication(" + opPackageName + ")");
-
-        startClient(client, true /* initiatedByClient */);
-    }
-
-    /**
-     * Helper methods.
-     */
-
-    /**
-     * @param opPackageName name of package for caller
-     * @param requireForeground only allow this call while app is in the foreground
-     * @return true if caller can use the biometric API
-     */
-    protected boolean canUseBiometric(String opPackageName, boolean requireForeground, int uid,
-            int pid, int userId) {
-        checkUseBiometricPermission();
-
-
-        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
-            return true; // System process (BiometricService, etc) is always allowed
-        }
-        if (isKeyguard(opPackageName)) {
-            return true; // Keyguard is always allowed
-        }
-        if (!isCurrentUserOrProfile(userId)) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; not a current user or profile");
-            return false;
-        }
-        if (!checkAppOps(uid, opPackageName)) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; permission denied");
-            return false;
-        }
-
-        if (requireForeground && !(isForegroundActivity(uid, pid) || isCurrentClient(
-                opPackageName))) {
-            Slog.w(getTag(), "Rejecting " + opPackageName + "; not in foreground");
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * @param opPackageName package of the caller
-     * @return true if this is the same client currently using the biometric
-     */
-    private boolean isCurrentClient(String opPackageName) {
-        return mCurrentClient != null && mCurrentClient.getOwnerString().equals(opPackageName);
-    }
-
-    /**
-     * @return true if this is keyguard package
-     */
-    public boolean isKeyguard(String clientPackage) {
-        return mKeyguardPackage.equals(clientPackage);
-    }
-
-    private boolean isForegroundActivity(int uid, int pid) {
-        try {
-            final List<ActivityManager.RunningAppProcessInfo> procs =
-                    ActivityManager.getService().getRunningAppProcesses();
-            if (procs == null) {
-                Slog.e(getTag(), "Processes null, defaulting to true");
-                return true;
-            }
-
-            int N = procs.size();
-            for (int i = 0; i < N; i++) {
-                ActivityManager.RunningAppProcessInfo proc = procs.get(i);
-                if (proc.pid == pid && proc.uid == uid
-                        && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
-                    return true;
-                }
-            }
-        } catch (RemoteException e) {
-            Slog.w(getTag(), "am.getRunningAppProcesses() failed");
-        }
-        return false;
-    }
-
-    /**
-     * Calls the HAL to switch states to the new task. If there's already a current task,
-     * it calls cancel() and sets mPendingClient to begin when the current task finishes
-     * ({@link BiometricConstants#BIOMETRIC_ERROR_CANCELED}).
-     *
-     * @param newClient the new client that wants to connect
-     * @param initiatedByClient true for authenticate, remove and enroll
-     */
-    @VisibleForTesting
-    protected void startClient(ClientMonitor<T> newClient, boolean initiatedByClient) {
-        ClientMonitor currentClient = mCurrentClient;
-        if (currentClient != null) {
-            if (DEBUG) Slog.v(getTag(), "request stop current client " +
-                    currentClient.getOwnerString());
-            if (currentClient instanceof InternalCleanupClient) {
-                // This condition means we're currently running internal diagnostics to
-                // remove extra templates in the hardware and/or the software
-                // TODO: design an escape hatch in case client never finishes
-                if (newClient != null) {
-                    Slog.w(getTag(), "Internal cleanup in progress but trying to start client "
-                            + newClient.getClass().getSuperclass().getSimpleName()
-                            + "(" + newClient.getOwnerString() + ")"
-                            + ", initiatedByClient = " + initiatedByClient);
-                }
-            } else if (currentClient instanceof Cancellable) {
-                ((Cancellable) currentClient).cancel();
-
-                // Only post the reset runnable for non-cleanup clients. Cleanup clients should
-                // never be forcibly stopped since they ensure synchronization between HAL and
-                // framework. Thus, we should instead just start the pending client once cleanup
-                // finishes instead of using the reset runnable.
-                mHandler.removeCallbacks(mResetClientState);
-                mHandler.postDelayed(mResetClientState, CANCEL_TIMEOUT_LIMIT);
-            }
-            mPendingClient = newClient;
-        } else if (newClient != null) {
-            // For BiometricPrompt clients, do not start until
-            // <Biometric>Service#startPreparedClient is called. BiometricService waits until all
-            // modalities are ready before initiating authentication.
-            if (newClient instanceof AuthenticationClient) {
-                AuthenticationClient client = (AuthenticationClient) newClient;
-                if (client.isBiometricPrompt()) {
-                    if (DEBUG) Slog.v(getTag(), "Returning cookie: " + client.getCookie());
-                    mCurrentClient = newClient;
-                    if (mBiometricService == null) {
-                        mBiometricService = IBiometricService.Stub.asInterface(
-                                ServiceManager.getService(Context.BIOMETRIC_SERVICE));
-                    }
-                    try {
-                        mBiometricService.onReadyForAuthentication(client.getCookie());
-                    } catch (RemoteException e) {
-                        Slog.e(getTag(), "Remote exception", e);
-                    }
-                    return;
-                }
-            }
-
-            // We are not a BiometricPrompt client, start the client immediately
-            mCurrentClient = newClient;
-            startCurrentClient(mCurrentClient.getCookie());
-        }
-    }
-
-    protected void startCurrentClient(int cookie) {
-        if (mCurrentClient == null) {
-            Slog.e(getTag(), "Trying to start null client!");
-            return;
-        }
-
-        if (DEBUG) Slog.v(getTag(), "Starting client "
-                + mCurrentClient.getClass().getSimpleName()
-                + "(" + mCurrentClient.getOwnerString() + ")"
-                + " targetUserId: " + mCurrentClient.getTargetUserId()
-                + " currentUserId: " + mCurrentUserId
-                + " cookie: " + cookie + "/" + mCurrentClient.getCookie());
-
-        if (cookie != mCurrentClient.getCookie()) {
-            Slog.e(getTag(), "Mismatched cookie");
-            return;
-        }
-
-        final T daemon = mCurrentClient.getFreshDaemon();
-        if (daemon == null) {
-            Slog.e(getTag(), "Daemon null, unable to start: "
-                    + mCurrentClient.getClass().getSimpleName());
-            mCurrentClient.unableToStart();
-            mCurrentClient = null;
-            return;
-        }
-
-        mCurrentClient.start(mClientFinishCallback);
-        notifyClientActiveCallbacks(true);
-    }
-
-    protected void removeClient(ClientMonitor client) {
-        if (client != null) {
-            client.destroy();
-            if (client != mCurrentClient && mCurrentClient != null) {
-                Slog.w(getTag(), "Unexpected client: " + client.getOwnerString() + "expected: "
-                        + mCurrentClient.getOwnerString());
-            }
-        }
-        if (mCurrentClient != null) {
-            if (DEBUG) Slog.v(getTag(), "Done with client: "
-                    + mCurrentClient.getClass().getSimpleName()
-                    + "(" + mCurrentClient.getOwnerString() + ")");
-            mCurrentClient = null;
-        }
-        if (mPendingClient == null) {
-            notifyClientActiveCallbacks(false);
-        }
-    }
-
-    /**
-     * Populates existing authenticator ids. To be used only during the start of the service.
-     */
-    protected void loadAuthenticatorIds() {
-        // This operation can be expensive, so keep track of the elapsed time. Might need to move to
-        // background if it takes too long.
-        long t = System.currentTimeMillis();
-        mAuthenticatorIds.clear();
-        for (UserInfo user : UserManager.get(getContext()).getUsers(true /* excludeDying */)) {
-            int userId = user.id;
-            if (!mAuthenticatorIds.containsKey(userId)) {
-                updateActiveGroup(userId);
-            }
-        }
-
-        t = System.currentTimeMillis() - t;
-        if (t > 1000) {
-            Slog.w(getTag(), "loadAuthenticatorIds() taking too long: " + t + "ms");
-        }
-    }
-
-    protected boolean isRestricted() {
-        // Only give privileged apps (like Settings) access to biometric info
-        final boolean restricted = !hasPermission(getManageBiometricPermission());
-        return restricted;
-    }
-
-    protected boolean hasPermission(String permission) {
-        return getContext().checkCallingOrSelfPermission(permission)
-                == PackageManager.PERMISSION_GRANTED;
-    }
-
-    protected void checkPermission(String permission) {
-        getContext().enforceCallingOrSelfPermission(permission,
-                "Must have " + permission + " permission.");
-    }
-
-    protected boolean isCurrentUserOrProfile(int userId) {
-        UserManager um = UserManager.get(mContext);
-        if (um == null) {
-            Slog.e(getTag(), "Unable to acquire UserManager");
-            return false;
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        try {
-            // Allow current user or profiles of the current user...
-            for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
-                if (profileId == userId) {
-                    return true;
-                }
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-
-        return false;
-    }
-
-    /**
-     * @return authenticator id for the calling user
-     */
-    protected long getAuthenticatorId(int callingUserId) {
-        return mAuthenticatorIds.getOrDefault(callingUserId, 0L);
-    }
-
-    /**
-     * This method should be called upon connection to the daemon, and when user switches.
-     */
-    protected abstract void doTemplateCleanupForUser(int userId);
-
-    /**
-     * This method is called when the user switches. Implementations should probably notify the
-     * HAL.
-     */
-    protected void handleUserSwitching(int userId) {
-        if (getCurrentClient() instanceof InternalCleanupClient) {
-            Slog.w(getTag(), "User switched while performing cleanup");
-        }
-        updateActiveGroup(userId);
-        doTemplateCleanupForUser(userId);
-    }
-
-    private void listenForUserSwitches() {
-        try {
-            ActivityManager.getService().registerUserSwitchObserver(
-                    new SynchronousUserSwitchObserver() {
-                        @Override
-                        public void onUserSwitching(int newUserId) {
-                            mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
-                                    .sendToTarget();
-                        }
-                    }, getTag());
-        } catch (RemoteException e) {
-            Slog.w(getTag(), "Failed to listen for user switching event" ,e);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
index 3f301cc..8b27781 100644
--- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java
@@ -34,7 +34,10 @@
 public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinder.DeathRecipient {
 
     private static final String TAG = "Biometrics/ClientMonitor";
-    protected static final boolean DEBUG = BiometricServiceBase.DEBUG;
+    protected static final boolean DEBUG = true;
+
+    // Counter used to distinguish between ClientMonitor instances to help debugging.
+    private static int sCount = 0;
 
     /**
      * Interface that ClientMonitor holders should use to receive callbacks.
@@ -49,7 +52,7 @@
          * @param clientMonitor Reference of the ClientMonitor that finished.
          * @param success True if the operation completed successfully.
          */
-        void onClientFinished(ClientMonitor clientMonitor, boolean success);
+        void onClientFinished(ClientMonitor<?> clientMonitor, boolean success);
     }
 
     /**
@@ -62,6 +65,7 @@
         T getDaemon();
     }
 
+    private final int mSequentialId;
     @NonNull private final Context mContext;
     @NonNull protected final LazyDaemon<T> mLazyDaemon;
     private final int mTargetUserId;
@@ -95,6 +99,7 @@
             @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
             int statsClient) {
         super(statsModality, statsAction, statsClient);
+        mSequentialId = sCount++;
         mContext = context;
         mLazyDaemon = lazyDaemon;
         mToken = token;
@@ -163,9 +168,9 @@
     // TODO(b/157790417): Move this to the scheduler
     void binderDiedInternal(boolean clearListener) {
         // If the current client dies we should cancel the current operation.
-        if (this instanceof Cancellable) {
+        if (this instanceof Interruptable) {
             Slog.e(TAG, "Binder died, cancelling client");
-            ((Cancellable) this).cancel();
+            ((Interruptable) this).cancel();
         }
         mToken = null;
         if (clearListener) {
@@ -200,4 +205,12 @@
     public final T getFreshDaemon() {
         return mLazyDaemon.getDaemon();
     }
+
+    @Override
+    public String toString() {
+        return "{[" + mSequentialId + "] "
+                + this.getClass().getSimpleName()
+                + ", " + getOwnerString()
+                + ", " + getCookie() + "}";
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
index a3d9677..163f29e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
@@ -35,12 +35,17 @@
 
     protected final byte[] mHardwareAuthToken;
     protected final int mTimeoutSec;
-    private final BiometricUtils mBiometricUtils;
+    protected final BiometricUtils mBiometricUtils;
     private final boolean mShouldVibrate;
 
     private long mEnrollmentStartTimeMs;
     private boolean mAlreadyCancelled;
 
+    /**
+     * @return true if the user has already enrolled the maximum number of templates.
+     */
+    protected abstract boolean hasReachedEnrollmentLimit();
+
     public EnrollClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
             @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
             @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils,
@@ -82,6 +87,12 @@
     public void start(@NonNull FinishCallback finishCallback) {
         super.start(finishCallback);
 
+        if (hasReachedEnrollmentLimit()) {
+            Slog.e(TAG, "Reached enrollment limit");
+            finishCallback.onClientFinished(this, false /* success */);
+            return;
+        }
+
         mEnrollmentStartTimeMs = System.currentTimeMillis();
         startHalOperation();
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/ErrorConsumer.java b/services/core/java/com/android/server/biometrics/sensors/ErrorConsumer.java
deleted file mode 100644
index 0c3b0b7..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/ErrorConsumer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-/**
- * Interface that {@link ClientMonitor} subclasses eligible/interested in error callbacks should
- * implement.
- */
-public interface ErrorConsumer {
-    /**
-     * @param errorCode defined by the HIDL interface
-     * @param vendorCode defined by the vendor
-     */
-    void onError(int errorCode, int vendorCode);
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/Interruptable.java b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java
new file mode 100644
index 0000000..35d9177
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors;
+
+import android.annotation.NonNull;
+
+/**
+ * Interface that {@link ClientMonitor} subclasses eligible/interested in error callbacks should
+ * implement.
+ */
+public interface Interruptable {
+    /**
+     * Requests to end the ClientMonitor's lifecycle.
+     */
+    void cancel();
+
+    /**
+     * Notifies the client of errors from the HAL.
+     * @param errorCode defined by the HIDL interface
+     * @param vendorCode defined by the vendor
+     */
+    void onError(int errorCode, int vendorCode);
+
+    /**
+     * Notifies the client that it needs to finish before
+     * {@link ClientMonitor#start(ClientMonitor.FinishCallback)} was invoked. This usually happens
+     * if the client is still waiting in the pending queue and got notified that a subsequent
+     * operation is preempting it.
+     * @param finishCallback invoked when the operation is completed.
+     */
+    void cancelWithoutStarting(@NonNull ClientMonitor.FinishCallback finishCallback);
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/LockoutResetTracker.java b/services/core/java/com/android/server/biometrics/sensors/LockoutResetDispatcher.java
similarity index 87%
rename from services/core/java/com/android/server/biometrics/sensors/LockoutResetTracker.java
rename to services/core/java/com/android/server/biometrics/sensors/LockoutResetDispatcher.java
index 9bb5c6e..f4997d4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/LockoutResetTracker.java
+++ b/services/core/java/com/android/server/biometrics/sensors/LockoutResetDispatcher.java
@@ -29,9 +29,10 @@
 
 /**
  * Allows clients (such as keyguard) to register for notifications on when biometric lockout
- * ends.
+ * ends. This class keeps track of all client callbacks. Individual sensors should notify this
+ * when lockout for a specific sensor has been reset.
  */
-public class LockoutResetTracker implements IBinder.DeathRecipient {
+public class LockoutResetDispatcher implements IBinder.DeathRecipient {
 
     private static final String TAG = "LockoutResetTracker";
 
@@ -54,11 +55,11 @@
                     "LockoutResetMonitor:SendLockoutReset");
         }
 
-        void sendLockoutReset() {
+        void sendLockoutReset(int sensorId) {
             if (mCallback != null) {
                 try {
                     mWakeLock.acquire(WAKELOCK_TIMEOUT_MS);
-                    mCallback.onLockoutReset(new IRemoteCallback.Stub() {
+                    mCallback.onLockoutReset(sensorId, new IRemoteCallback.Stub() {
                         @Override
                         public void sendResult(Bundle data) {
                             releaseWakelock();
@@ -78,7 +79,7 @@
         }
     }
 
-    public LockoutResetTracker(Context context) {
+    public LockoutResetDispatcher(Context context) {
         mContext = context;
         mClientCallbacks = new ArrayList<>();
     }
@@ -114,9 +115,9 @@
         }
     }
 
-    public void notifyLockoutResetCallbacks() {
+    public void notifyLockoutResetCallbacks(int sensorId) {
         for (ClientCallback callback : mClientCallbacks) {
-            callback.sendLockoutReset();
+            callback.sendLockoutReset(sensorId);
         }
     }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
index a7c63f7..1a4216f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/LoggableMonitor.java
@@ -39,10 +39,6 @@
     private final int mStatsClient;
     private long mFirstAcquireTimeMs;
 
-    protected long getFirstAcquireTimeMs() {
-        return mFirstAcquireTimeMs;
-    }
-
     /**
      * Only valid for AuthenticationClient.
      * @return true if the client is authenticating for a crypto operation.
@@ -62,6 +58,12 @@
         mStatsClient = statsClient;
     }
 
+    private boolean isAnyFieldUnknown() {
+        return mStatsModality == BiometricsProtoEnums.MODALITY_UNKNOWN
+                || mStatsAction == BiometricsProtoEnums.ACTION_UNKNOWN
+                || mStatsClient == BiometricsProtoEnums.CLIENT_UNKNOWN;
+    }
+
     protected final void logOnAcquired(Context context, int acquiredInfo, int vendorCode,
             int targetUserId) {
 
@@ -86,6 +88,11 @@
                     + ", AcquiredInfo: " + acquiredInfo
                     + ", VendorCode: " + vendorCode);
         }
+
+        if (isAnyFieldUnknown()) {
+            return;
+        }
+
         FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ACQUIRED,
                 mStatsModality,
                 targetUserId,
@@ -114,6 +121,11 @@
         } else {
             Slog.v(TAG, "Error latency: " + latency);
         }
+
+        if (isAnyFieldUnknown()) {
+            return;
+        }
+
         FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ERROR_OCCURRED,
                 mStatsModality,
                 targetUserId,
@@ -157,6 +169,10 @@
             Slog.v(TAG, "Authentication latency: " + latency);
         }
 
+        if (isAnyFieldUnknown()) {
+            return;
+        }
+
         FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_AUTHENTICATED,
                 mStatsModality,
                 targetUserId,
@@ -179,6 +195,10 @@
             Slog.v(TAG, "Enroll latency: " + latency);
         }
 
+        if (isAnyFieldUnknown()) {
+            return;
+        }
+
         FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_ENROLLED,
                 mStatsModality,
                 targetUserId,
diff --git a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
index fa490ee..9fdba4b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
+++ b/services/core/java/com/android/server/biometrics/sensors/PerformanceTracker.java
@@ -107,7 +107,7 @@
         mAllUsersInfo.get(userId).mPermanentLockout++;
     }
 
-    void incrementHALDeathCount() {
+    public void incrementHALDeathCount() {
         mHALDeathCount++;
     }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
new file mode 100644
index 0000000..c4ea0a8
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
@@ -0,0 +1,649 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.face;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.NotificationManager;
+import android.app.SynchronousUserSwitchObserver;
+import android.app.UserSwitchObserver;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.face.V1_0.IBiometricsFace;
+import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
+import android.hardware.face.Face;
+import android.hardware.face.IFaceServiceReceiver;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IHwBinder;
+import android.os.Looper;
+import android.os.NativeHandle;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.Slog;
+
+import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.sensors.AcquisitionClient;
+import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.ClientMonitor;
+import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.EnumerateConsumer;
+import com.android.server.biometrics.sensors.Interruptable;
+import com.android.server.biometrics.sensors.LockoutResetDispatcher;
+import com.android.server.biometrics.sensors.LockoutTracker;
+import com.android.server.biometrics.sensors.PerformanceTracker;
+import com.android.server.biometrics.sensors.RemovalConsumer;
+import com.android.server.biometrics.sensors.fingerprint.FingerprintUpdateActiveUserClient;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Supports a single instance of the {@link android.hardware.biometrics.face.V1_0} or
+ * its extended minor versions.
+ */
+class Face10 implements IHwBinder.DeathRecipient {
+
+    private static final String TAG = "Face10";
+    private static final int ENROLL_TIMEOUT_SEC = 75;
+    static final String NOTIFICATION_TAG = "FaceService";
+    static final int NOTIFICATION_ID = 1;
+
+    @NonNull private final Context mContext;
+    @NonNull private final BiometricScheduler mScheduler;
+    @NonNull private final Handler mHandler;
+    @NonNull private final ClientMonitor.LazyDaemon<IBiometricsFace> mLazyDaemon;
+    @NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
+    @NonNull private final LockoutHalImpl mLockoutTracker;
+    @NonNull private final UsageStats mUsageStats;
+    @NonNull private NotificationManager mNotificationManager;
+    private final int mSensorId;
+    @NonNull private final Map<Integer, Long> mAuthenticatorIds;
+
+    @Nullable private IBiometricsFace mDaemon;
+    private int mCurrentUserId = UserHandle.USER_NULL;
+
+    private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
+        @Override
+        public void onUserSwitching(int newUserId) {
+            scheduleInternalCleanup(newUserId);
+        }
+    };
+
+    private final IBiometricsFaceClientCallback mDaemonCallback =
+            new IBiometricsFaceClientCallback.Stub() {
+        @Override
+        public void onEnrollResult(long deviceId, int faceId, int userId, int remaining) {
+            mHandler.post(() -> {
+                final CharSequence name = FaceUtils.getInstance()
+                        .getUniqueName(mContext, userId);
+                final Face face = new Face(name, faceId, deviceId);
+
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof FaceEnrollClient)) {
+                    Slog.e(TAG, "onEnrollResult for non-enroll client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final FaceEnrollClient enrollClient = (FaceEnrollClient) client;
+                enrollClient.onEnrollResult(face, remaining);
+            });
+        }
+
+        @Override
+        public void onAuthenticated(long deviceId, int faceId, int userId, ArrayList<Byte> token) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof FaceAuthenticationClient)) {
+                    Slog.e(TAG, "onAuthenticated for non-authentication client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final FaceAuthenticationClient authenticationClient =
+                        (FaceAuthenticationClient) client;
+                final boolean authenticated = faceId != 0;
+                final Face face = new Face("", faceId, deviceId);
+                authenticationClient.onAuthenticated(face, authenticated, token);
+            });
+        }
+
+        @Override
+        public void onAcquired(long deviceId, int userId, int acquiredInfo, int vendorCode) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof AcquisitionClient)) {
+                    Slog.e(TAG, "onAcquired for non-acquire client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
+                acquisitionClient.onAcquired(acquiredInfo, vendorCode);
+            });
+        }
+
+        @Override
+        public void onError(long deviceId, int userId, int error, int vendorCode) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                Slog.d(TAG, "handleError"
+                        + ", client: " + (client != null ? client.getOwnerString() : null)
+                        + ", error: " + error
+                        + ", vendorCode: " + vendorCode);
+                if (!(client instanceof Interruptable)) {
+                    Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
+                    return;
+                }
+
+                final Interruptable interruptable = (Interruptable) client;
+                interruptable.onError(error, vendorCode);
+
+                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+                    Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
+                    mDaemon = null;
+                    mCurrentUserId = UserHandle.USER_NULL;
+                }
+            });
+        }
+
+        @Override
+        public void onRemoved(long deviceId, ArrayList<Integer> removed, int userId) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof RemovalConsumer)) {
+                    Slog.e(TAG, "onRemoved for non-removal consumer: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final RemovalConsumer removalConsumer = (RemovalConsumer) client;
+
+                if (!removed.isEmpty()) {
+                    // Convert to old fingerprint-like behavior, where remove() receives one removal
+                    // at a time. This way, remove can share some more common code.
+                    for (int i = 0; i < removed.size(); i++) {
+                        final int id = removed.get(i);
+                        final Face face = new Face("", id, deviceId);
+                        final int remaining = removed.size() - i - 1;
+                        Slog.d(TAG, "Removed, faceId: " + id + ", remaining: " + remaining);
+                        removalConsumer.onRemoved(face, remaining);
+                    }
+                } else {
+                    final Face face = new Face("", 0 /* identifier */, deviceId);
+                    removalConsumer.onRemoved(face, 0 /* remaining */);
+                }
+
+                Settings.Secure.putIntForUser(mContext.getContentResolver(),
+                        Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
+            });
+        }
+
+        @Override
+        public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof EnumerateConsumer)) {
+                    Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
+
+                if (!faceIds.isEmpty()) {
+                    // Convert to old fingerprint-like behavior, where enumerate() receives one
+                    // template at a time. This way, enumerate can share some more common code.
+                    for (int i = 0; i < faceIds.size(); i++) {
+                        final Face face = new Face("", faceIds.get(i), deviceId);
+                        enumerateConsumer.onEnumerationResult(face, faceIds.size() - i - 1);
+                    }
+                } else {
+                    // For face, the HIDL contract is to receive an empty list when there are no
+                    // templates enrolled. Send a null identifier since we don't consume them
+                    // anywhere, and send remaining == 0 so this code can be shared with
+                    // Fingerprint@2.1
+                    enumerateConsumer.onEnumerationResult(null /* identifier */, 0);
+                }
+            });
+        }
+
+        @Override
+        public void onLockoutChanged(long duration) {
+            mHandler.post(() -> {
+                Slog.d(TAG, "onLockoutChanged: " + duration);
+                final @LockoutTracker.LockoutMode int lockoutMode;
+                if (duration == 0) {
+                    lockoutMode = LockoutTracker.LOCKOUT_NONE;
+                } else if (duration == -1 || duration == Long.MAX_VALUE) {
+                    lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
+                } else {
+                    lockoutMode = LockoutTracker.LOCKOUT_TIMED;
+                }
+
+                mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
+
+                if (duration == 0) {
+                    mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorId);
+                }
+            });
+        }
+    };
+
+    Face10(@NonNull Context context, int sensorId,
+            @NonNull LockoutResetDispatcher lockoutResetDispatcher) {
+        mContext = context;
+        mSensorId = sensorId;
+        mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */);
+        mHandler = new Handler(Looper.getMainLooper());
+        mUsageStats = new UsageStats(context);
+        mAuthenticatorIds = new HashMap<>();
+        mLazyDaemon = Face10.this::getDaemon;
+        mNotificationManager = mContext.getSystemService(NotificationManager.class);
+        mLockoutTracker = new LockoutHalImpl();
+        mLockoutResetDispatcher = lockoutResetDispatcher;
+
+        try {
+            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to register user switch observer");
+        }
+    }
+
+    @Override
+    public void serviceDied(long cookie) {
+        Slog.e(TAG, "HAL died");
+        mHandler.post(() -> {
+            PerformanceTracker.getInstanceForSensorId(mSensorId)
+                    .incrementHALDeathCount();
+            mDaemon = null;
+            mCurrentUserId = UserHandle.USER_NULL;
+
+            final ClientMonitor<?> client = mScheduler.getCurrentClient();
+            if (client instanceof Interruptable) {
+                Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
+                final Interruptable interruptable = (Interruptable) client;
+                interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                        0 /* vendorCode */);
+
+                mScheduler.recordCrashState();
+
+                FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+                        BiometricsProtoEnums.MODALITY_FACE,
+                        BiometricsProtoEnums.ISSUE_HAL_DEATH);
+            }
+        });
+    }
+
+    private synchronized IBiometricsFace getDaemon() {
+        if (mDaemon != null) {
+            return mDaemon;
+        }
+
+        Slog.d(TAG, "Daemon was null, reconnecting, current operation: "
+                + mScheduler.getCurrentClient());
+
+        try {
+            mDaemon = IBiometricsFace.getService();
+        } catch (java.util.NoSuchElementException e) {
+            // Service doesn't exist or cannot be opened.
+            Slog.w(TAG, "NoSuchElementException", e);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get face HAL", e);
+        }
+
+        if (mDaemon == null) {
+            Slog.w(TAG, "Face HAL not available");
+            return null;
+        }
+
+        mDaemon.asBinder().linkToDeath(this, 0 /* flags */);
+
+        // HAL ID for these HIDL versions are only used to determine if callbacks have been
+        // successfully set.
+        long halId = 0;
+        try {
+            halId = mDaemon.setCallback(mDaemonCallback).value;
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set callback for face HAL", e);
+            mDaemon = null;
+        }
+
+        Slog.d(TAG, "Face HAL ready, HAL ID: " + halId);
+        if (halId != 0) {
+            scheduleLoadAuthenticatorIds();
+            scheduleInternalCleanup(ActivityManager.getCurrentUser());
+        } else {
+            Slog.e(TAG, "Unable to set callback");
+            mDaemon = null;
+        }
+
+        return mDaemon;
+    }
+
+    @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
+        return mLockoutTracker.getLockoutModeForUser(userId);
+    }
+
+    private void scheduleLoadAuthenticatorIds() {
+        // Note that this can be performed on the scheduler (as opposed to being done immediately
+        // when the HAL is (re)loaded, since
+        // 1) If this is truly the first time it's being performed (e.g. system has just started),
+        //    this will be run very early and way before any applications need to generate keys.
+        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
+        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
+        //    is safe because authenticatorIds only change when A) new template has been enrolled,
+        //    or B) all templates are removed.
+        mHandler.post(() -> {
+            for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) {
+                final int targetUserId = user.id;
+                if (!mAuthenticatorIds.containsKey(targetUserId)) {
+                    scheduleUpdateActiveUserWithoutHandler(targetUserId);
+                }
+            }
+        });
+    }
+
+    /**
+     * Schedules the {@link FingerprintUpdateActiveUserClient} without posting the work onto the
+     * handler. Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
+     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
+     * this operation on the same lambda/runnable as those operations so that the ordering is
+     * correct.
+     */
+    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
+        final boolean hasEnrolled = !getEnrolledFaces(targetUserId).isEmpty();
+        final FaceUpdateActiveUserClient client = new FaceUpdateActiveUserClient(mContext,
+                mLazyDaemon, targetUserId, mContext.getOpPackageName(), mSensorId, mCurrentUserId,
+                hasEnrolled, mAuthenticatorIds);
+        mScheduler.scheduleClientMonitor(client, (clientMonitor, success) -> {
+            if (success) {
+                mCurrentUserId = targetUserId;
+            }
+        });
+    }
+
+    void scheduleResetLockout(int userId, @NonNull byte[] hardwareAuthToken) {
+        mHandler.post(() -> {
+            if (getEnrolledFaces(userId).isEmpty()) {
+                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final FaceResetLockoutClient client = new FaceResetLockoutClient(mContext,
+                    mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
+                    hardwareAuthToken);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleSetFeature(@NonNull IBinder token, int userId, int feature, boolean enabled,
+            @NonNull byte[] hardwareAuthToken, @NonNull IFaceServiceReceiver receiver,
+            @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final List<Face> faces = getEnrolledFaces(userId);
+            if (faces.isEmpty()) {
+                Slog.w(TAG, "Ignoring setFeature, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final int faceId = faces.get(0).getBiometricId();
+            final FaceSetFeatureClient client = new FaceSetFeatureClient(mContext,
+                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
+                    opPackageName, mSensorId, feature, enabled, hardwareAuthToken, faceId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleGetFeature(@NonNull IBinder token, int userId, int feature,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final List<Face> faces = getEnrolledFaces(userId);
+            if (faces.isEmpty()) {
+                Slog.w(TAG, "Ignoring getFeature, no templates enrolled for user: " + userId);
+                return;
+            }
+
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final int faceId = faces.get(0).getBiometricId();
+            final FaceGetFeatureClient client = new FaceGetFeatureClient(mContext,
+                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
+                    opPackageName, mSensorId, feature, faceId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleGenerateChallenge(@NonNull IBinder token, @NonNull IFaceServiceReceiver receiver,
+            @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final FaceGenerateChallengeClient client = new FaceGenerateChallengeClient(mContext,
+                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), opPackageName,
+                    mSensorId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleRevokeChallenge(@NonNull IBinder token, @NonNull String owner) {
+        mHandler.post(() -> {
+            final FaceRevokeChallengeClient client = new FaceRevokeChallengeClient(mContext,
+                    mLazyDaemon, token, owner, mSensorId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleEnroll(@NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName,
+            @NonNull int[] disabledFeatures, @Nullable NativeHandle surfaceHandle) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            mNotificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID,
+                    UserHandle.CURRENT);
+
+            final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token,
+                    new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
+                    opPackageName, FaceUtils.getInstance(), disabledFeatures, ENROLL_TIMEOUT_SEC,
+                    surfaceHandle, mSensorId);
+
+            mScheduler.scheduleClientMonitor(client, ((clientMonitor, success) -> {
+                if (success) {
+                    // Update authenticatorIds
+                    scheduleUpdateActiveUserWithoutHandler(client.getTargetUserId());
+                }
+            }));
+        });
+    }
+
+    void cancelEnrollment(@NonNull IBinder token) {
+        mHandler.post(() -> {
+            mScheduler.cancelEnrollment(token);
+        });
+    }
+
+    void scheduleAuthenticate(@NonNull IBinder token, long operationId, int userId, int cookie,
+            @NonNull ClientMonitorCallbackConverter receiver, @NonNull String opPackageName,
+            boolean restricted, int statsClient) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
+            final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
+                    mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName,
+                    cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric,
+                    statsClient, mLockoutTracker, mUsageStats);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void startPreparedClient(int cookie) {
+        mHandler.post(() -> {
+            mScheduler.startPreparedClient(cookie);
+        });
+    }
+
+    void cancelAuthentication(@NonNull IBinder token) {
+        mHandler.post(() -> {
+            mScheduler.cancelAuthentication(token);
+        });
+    }
+
+    void scheduleRemove(@NonNull IBinder token, int faceId, int userId,
+            @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token,
+                    new ClientMonitorCallbackConverter(receiver), faceId, userId, opPackageName,
+                    FaceUtils.getInstance(), mSensorId, mAuthenticatorIds);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    private void scheduleInternalCleanup(int userId) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final List<Face> enrolledList = getEnrolledFaces(userId);
+            final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
+                    mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList,
+                    FaceUtils.getInstance(), mAuthenticatorIds);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    boolean isHardwareDetected() {
+        final IBiometricsFace daemon = getDaemon();
+        return daemon != null;
+    }
+
+    List<Face> getEnrolledFaces(int userId) {
+        return FaceUtils.getInstance().getBiometricsForUser(mContext, userId);
+    }
+
+    long getAuthenticatorId(int userId) {
+        return mAuthenticatorIds.get(userId);
+    }
+
+    public void dump(@NonNull PrintWriter pw) {
+        PerformanceTracker performanceTracker =
+                PerformanceTracker.getInstanceForSensorId(mSensorId);
+
+        JSONObject dump = new JSONObject();
+        try {
+            dump.put("service", "Face Manager");
+
+            JSONArray sets = new JSONArray();
+            for (UserInfo user : UserManager.get(mContext).getUsers()) {
+                final int userId = user.getUserHandle().getIdentifier();
+                final int N = FaceUtils.getInstance().getBiometricsForUser(mContext, userId).size();
+                JSONObject set = new JSONObject();
+                set.put("id", userId);
+                set.put("count", N);
+                set.put("accept", performanceTracker.getAcceptForUser(userId));
+                set.put("reject", performanceTracker.getRejectForUser(userId));
+                set.put("acquire", performanceTracker.getAcquireForUser(userId));
+                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
+                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
+                // cryptoStats measures statistics about secure face transactions
+                // (e.g. to unlock password storage, make secure purchases, etc.)
+                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
+                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
+                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
+                sets.put(set);
+            }
+
+            dump.put("prints", sets);
+        } catch (JSONException e) {
+            Slog.e(TAG, "dump formatting failure", e);
+        }
+        pw.println(dump);
+        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
+
+        mUsageStats.print(pw);
+    }
+
+    public void dumpHal(@NonNull FileDescriptor fd, @NonNull String[] args) {
+        // WARNING: CDD restricts image data from leaving TEE unencrypted on
+        //          production devices:
+        // [C-1-10] MUST not allow unencrypted access to identifiable biometric
+        //          data or any data derived from it (such as embeddings) to the
+        //         Application Processor outside the context of the TEE.
+        //  As such, this API should only be enabled for testing purposes on
+        //  engineering and userdebug builds.  All modules in the software stack
+        //  MUST enforce final build products do NOT have this functionality.
+        //  Additionally, the following check MUST NOT be removed.
+        if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
+            return;
+        }
+
+        // Additionally, this flag allows turning off face for a device
+        // (either permanently through the build or on an individual device).
+        if (SystemProperties.getBoolean("ro.face.disable_debug_data", false)
+                || SystemProperties.getBoolean("persist.face.disable_debug_data", false)) {
+            return;
+        }
+
+        // The debug method takes two file descriptors. The first is for text
+        // output, which we will drop.  The second is for binary data, which
+        // will be the protobuf data.
+        final IBiometricsFace daemon = getDaemon();
+        if (daemon != null) {
+            FileOutputStream devnull = null;
+            try {
+                devnull = new FileOutputStream("/dev/null");
+                final NativeHandle handle = new NativeHandle(
+                        new FileDescriptor[] { devnull.getFD(), fd },
+                        new int[0], false);
+                daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
+            } catch (IOException | RemoteException ex) {
+                Slog.d(TAG, "error while reading face debugging data", ex);
+            } finally {
+                if (devnull != null) {
+                    try {
+                        devnull.close();
+                    } catch (IOException ex) {
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
index 118cadc..21bda74 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticationClient.java
@@ -21,7 +21,6 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
-import android.app.TaskStackListener;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -67,11 +66,10 @@
             @NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
             boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
             boolean isStrongBiometric, int statsClient,
-            @NonNull TaskStackListener taskStackListener,
             @NonNull LockoutTracker lockoutTracker, @NonNull UsageStats usageStats) {
         super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
                 owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
-                BiometricsProtoEnums.MODALITY_FACE, statsClient, taskStackListener,
+                BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
                 lockoutTracker);
         mNotificationManager = context.getSystemService(NotificationManager.class);
         mUsageStats = usageStats;
@@ -221,8 +219,8 @@
                     .build();
 
             mNotificationManager.createNotificationChannel(channel);
-            mNotificationManager.notifyAsUser(FaceService.NOTIFICATION_TAG,
-                    FaceService.NOTIFICATION_ID, notification,
+            mNotificationManager.notifyAsUser(Face10.NOTIFICATION_TAG,
+                    Face10.NOTIFICATION_ID, notification,
                     UserHandle.CURRENT);
         }
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
index 4f9f46a..52a8226 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceEnrollClient.java
@@ -68,6 +68,19 @@
     }
 
     @Override
+    protected boolean hasReachedEnrollmentLimit() {
+        final int limit = getContext().getResources().getInteger(
+                com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
+        final int enrolled = mBiometricUtils.getBiometricsForUser(getContext(), getTargetUserId())
+                .size();
+        if (enrolled >= limit) {
+            Slog.w(TAG, "Too many faces registered, user: " + getTargetUserId());
+            return true;
+        }
+        return false;
+    }
+
+    @Override
     public void onAcquired(int acquireInfo, int vendorCode) {
         final boolean shouldSend;
         if (acquireInfo == FaceManager.FACE_ACQUIRED_VENDOR) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index a7f8220..3c597a9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -16,65 +16,31 @@
 
 package com.android.server.biometrics.sensors.face;
 
-import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.MANAGE_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 
-import android.app.ActivityManager;
-import android.app.AppOpsManager;
-import android.app.NotificationManager;
+import android.annotation.NonNull;
 import android.content.Context;
-import android.content.pm.UserInfo;
-import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.IBiometricSensorReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
-import android.hardware.biometrics.face.V1_0.IBiometricsFace;
-import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
 import android.hardware.face.Face;
 import android.hardware.face.IFaceService;
 import android.hardware.face.IFaceServiceReceiver;
 import android.os.Binder;
-import android.os.Build;
-import android.os.Environment;
 import android.os.IBinder;
 import android.os.NativeHandle;
-import android.os.RemoteException;
-import android.os.SELinux;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.util.Slog;
 import android.view.Surface;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.DumpUtils;
-import com.android.server.SystemServerInitThreadPool;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.BiometricServiceBase;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitor;
+import com.android.server.SystemService;
+import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.EnrollClient;
-import com.android.server.biometrics.sensors.GenerateChallengeClient;
-import com.android.server.biometrics.sensors.LockoutResetTracker;
+import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.RemovalClient;
-import com.android.server.biometrics.sensors.RevokeChallengeClient;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.File;
 import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -82,182 +48,116 @@
  * A service to manage multiple clients that want to access the face HAL API.
  * The service is responsible for maintaining a list of clients and dispatching all
  * face-related events.
- *
- * @hide
  */
-public class FaceService extends BiometricServiceBase<IBiometricsFace> {
+public class FaceService extends SystemService {
 
     protected static final String TAG = "FaceService";
-    private static final boolean DEBUG = true;
-    private static final String FACE_DATA_DIR = "facedata";
-    private static final String ACTION_LOCKOUT_RESET =
-            "com.android.server.biometrics.face.ACTION_LOCKOUT_RESET";
 
-
-    static final String NOTIFICATION_TAG = "FaceService";
-    static final int NOTIFICATION_ID = 1;
-
-    private final LockoutResetTracker mLockoutResetTracker;
-    private final ClientMonitor.LazyDaemon<IBiometricsFace> mLazyDaemon;
+    private Face10 mFace10;
+    private final LockoutResetDispatcher mLockoutResetDispatcher;
 
     /**
      * Receives the incoming binder calls from FaceManager.
      */
     private final class FaceServiceWrapper extends IFaceService.Stub {
-        private static final int ENROLL_TIMEOUT_SEC = 75;
-
-        /**
-         * The following methods contain common code which is shared in biometrics/common.
-         */
-
         @Override // Binder call
         public void generateChallenge(IBinder token, IFaceServiceReceiver receiver,
                 String opPackageName) {
-            checkPermission(MANAGE_BIOMETRIC);
-
-            final GenerateChallengeClient client = new FaceGenerateChallengeClient(getContext(),
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), opPackageName,
-                    getSensorId());
-            generateChallengeInternal(client);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFace10.scheduleGenerateChallenge(token, receiver, opPackageName);
         }
 
         @Override // Binder call
         public void revokeChallenge(IBinder token, String owner) {
-            checkPermission(MANAGE_BIOMETRIC);
-
-            final RevokeChallengeClient client = new FaceRevokeChallengeClient(getContext(),
-                    mLazyDaemon, token, owner, getSensorId());
-
-            // TODO(b/137106905): Schedule binder calls in FaceService to avoid deadlocks.
-            if (getCurrentClient() == null) {
-                // if we aren't handling any other HIDL calls (mCurrentClient == null), revoke
-                // the challenge right away.
-                revokeChallengeInternal(client);
-            } else {
-                // postpone revoking the challenge until we finish processing the current HIDL
-                // call.
-                mPendingRevokeChallenge = client;
-            }
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFace10.scheduleRevokeChallenge(token, owner);
         }
 
         @Override // Binder call
         public void enroll(int userId, final IBinder token, final byte[] hardwareAuthToken,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures, Surface surface) {
-            checkPermission(MANAGE_BIOMETRIC);
-            updateActiveGroup(userId);
-
-            mHandler.post(() -> {
-                mNotificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID,
-                        UserHandle.CURRENT);
-            });
-
-            final EnrollClient client = new FaceEnrollClient(getContext(), mLazyDaemon, token,
-                    new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
-                    opPackageName, getBiometricUtils(), disabledFeatures, ENROLL_TIMEOUT_SEC,
-                    convertSurfaceToNativeHandle(surface), getSensorId());
-
-            enrollInternal(client, userId);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFace10.scheduleEnroll(token, hardwareAuthToken, userId, receiver, opPackageName,
+                    disabledFeatures, convertSurfaceToNativeHandle(surface));
         }
 
         @Override // Binder call
         public void enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken,
                 final IFaceServiceReceiver receiver, final String opPackageName,
                 final int[] disabledFeatures) {
-            checkPermission(MANAGE_BIOMETRIC);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
             // TODO(b/145027036): Implement this.
         }
 
         @Override // Binder call
         public void cancelEnrollment(final IBinder token) {
-            checkPermission(MANAGE_BIOMETRIC);
-            cancelEnrollmentInternal(token);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFace10.cancelEnrollment(token);
         }
 
         @Override // Binder call
-        public void authenticate(final IBinder token, final long opId, int userId,
+        public void authenticate(final IBinder token, final long operationId, int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            updateActiveGroup(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
-            final boolean restricted = isRestricted();
-            final int statsClient = isKeyguard(opPackageName) ? BiometricsProtoEnums.CLIENT_KEYGUARD
+            final boolean restricted = false; // Face APIs are private
+            final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
+                    ? BiometricsProtoEnums.CLIENT_KEYGUARD
                     : BiometricsProtoEnums.CLIENT_UNKNOWN;
-            final AuthenticationClient client = new FaceAuthenticationClient(getContext(),
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, opId,
-                    restricted, opPackageName, 0 /* cookie */, false /* requireConfirmation */,
-                    getSensorId(), isStrongBiometric(), statsClient, mTaskStackListener,
-                    mLockoutTracker, mUsageStats);
-            authenticateInternal(client, opPackageName);
+            mFace10.scheduleAuthenticate(token, operationId, userId, 0 /* cookie */,
+                    new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
+                    statsClient);
         }
 
         @Override // Binder call
-        public void prepareForAuthentication(boolean requireConfirmation, IBinder token, long opId,
-                int userId, IBiometricSensorReceiver sensorReceiver,
+        public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
+                long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
                 String opPackageName, int cookie, int callingUid, int callingPid,
                 int callingUserId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            updateActiveGroup(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
 
             final boolean restricted = true; // BiometricPrompt is always restricted
-            final AuthenticationClient client = new FaceAuthenticationClient(getContext(),
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(sensorReceiver), userId,
-                    opId, restricted, opPackageName, cookie, requireConfirmation, getSensorId(),
-                    isStrongBiometric(), BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
-                    mTaskStackListener, mLockoutTracker, mUsageStats);
-            authenticateInternal(client, opPackageName, callingUid, callingPid,
-                    callingUserId);
+            mFace10.scheduleAuthenticate(token, operationId, userId, cookie,
+                    new ClientMonitorCallbackConverter(sensorReceiver), opPackageName,
+                    restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT);
         }
 
         @Override // Binder call
         public void startPreparedClient(int cookie) {
-            checkPermission(MANAGE_BIOMETRIC);
-            startCurrentClient(cookie);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.startPreparedClient(cookie);
         }
 
         @Override // Binder call
         public void cancelAuthentication(final IBinder token, final String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            cancelAuthenticationInternal(token, opPackageName);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.cancelAuthentication(token);
         }
 
         @Override // Binder call
         public void cancelAuthenticationFromService(final IBinder token, final String opPackageName,
                 int callingUid, int callingPid, int callingUserId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            // Cancellation is from system server in this case.
-            cancelAuthenticationInternal(token, opPackageName, callingUid, callingPid,
-                    callingUserId, false /* fromClient */);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.cancelAuthentication(token);
         }
 
         @Override // Binder call
         public void remove(final IBinder token, final int faceId, final int userId,
                 final IFaceServiceReceiver receiver, final String opPackageName) {
-            checkPermission(MANAGE_BIOMETRIC);
-            updateActiveGroup(userId);
-
-            if (token == null) {
-                Slog.w(TAG, "remove(): token is null");
-                return;
-            }
-
-            final RemovalClient client = new FaceRemovalClient(getContext(), mLazyDaemon, token,
-                    new ClientMonitorCallbackConverter(receiver), faceId, userId, opPackageName,
-                    getBiometricUtils(), getSensorId(), mAuthenticatorIds);
-            removeInternal(client);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.scheduleRemove(token, faceId, userId, receiver, opPackageName);
         }
 
         @Override
         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
                 final String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            mHandler.post(() -> {
-                mLockoutResetTracker.addCallback(callback, opPackageName);
-            });
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mLockoutResetDispatcher.addCallback(callback, opPackageName);
         }
 
         @Override // Binder call
-        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
                 return;
             }
@@ -265,33 +165,21 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 if (args.length > 1 && "--hal".equals(args[0])) {
-                    dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
+                    mFace10.dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
                 } else {
-                    dumpInternal(pw);
+                    mFace10.dump(pw);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
 
-        /**
-         * The following methods don't use any common code from BiometricService
-         */
-
-        // TODO: refactor out common code here
         @Override // Binder call
         public boolean isHardwareDetected(String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
-                    Binder.getCallingUid(), Binder.getCallingPid(),
-                    UserHandle.getCallingUserId())) {
-                return false;
-            }
-
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
             final long token = Binder.clearCallingIdentity();
             try {
-                IBiometricsFace daemon = getFaceDaemon();
-                return daemon != null;
+                return mFace10.isHardwareDetected();
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -299,540 +187,66 @@
 
         @Override // Binder call
         public List<Face> getEnrolledFaces(int userId, String opPackageName) {
-            checkPermission(MANAGE_BIOMETRIC);
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
-                    Binder.getCallingUid(), Binder.getCallingPid(),
-                    UserHandle.getCallingUserId())) {
-                return null;
-            }
-
-            return FaceService.this.getEnrolledTemplates(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFace10.getEnrolledFaces(userId);
         }
 
         @Override // Binder call
         public boolean hasEnrolledFaces(int userId, String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
-                    Binder.getCallingUid(), Binder.getCallingPid(),
-                    UserHandle.getCallingUserId())) {
-                return false;
-            }
-
-            return FaceService.this.hasEnrolledBiometrics(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return !mFace10.getEnrolledFaces(userId).isEmpty();
         }
 
         @Override
         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            return mLockoutTracker.getLockoutModeForUser(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFace10.getLockoutModeForUser(userId);
         }
 
         @Override // Binder call
-        public long getAuthenticatorId(int callingUserId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            return FaceService.this.getAuthenticatorId(callingUserId);
+        public long getAuthenticatorId(int userId) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFace10.getAuthenticatorId(userId);
         }
 
         @Override // Binder call
         public void resetLockout(int userId, byte[] hardwareAuthToken) {
-            checkPermission(MANAGE_BIOMETRIC);
-            mHandler.post(() -> {
-                if (!FaceService.this.hasEnrolledBiometrics(userId)) {
-                    Slog.w(TAG, "Ignoring lockout reset, no templates enrolled");
-                    return;
-                }
-
-                Slog.d(TAG, "Resetting lockout for user: " + userId);
-
-                updateActiveGroup(userId);
-                final FaceResetLockoutClient client = new FaceResetLockoutClient(getContext(),
-                        mLazyDaemon, userId, getContext().getOpPackageName(), getSensorId(),
-                        hardwareAuthToken);
-                startClient(client, true /* initiatedByClient */);
-            });
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.scheduleResetLockout(userId, hardwareAuthToken);
         }
 
         @Override
         public void setFeature(final IBinder token, int userId, int feature, boolean enabled,
                 final byte[] hardwareAuthToken, IFaceServiceReceiver receiver,
                 final String opPackageName) {
-            checkPermission(MANAGE_BIOMETRIC);
-
-            mHandler.post(() -> {
-                if (DEBUG) {
-                    Slog.d(TAG, "setFeature for user(" + userId + ")");
-                }
-                updateActiveGroup(userId);
-                if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
-                    Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
-                    return;
-                }
-
-                final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
-                final FaceSetFeatureClient client = new FaceSetFeatureClient(getContext(),
-                        mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
-                        opPackageName, getSensorId(), feature, enabled, hardwareAuthToken, faceId);
-                startClient(client, true /* initiatedByClient */);
-            });
-
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10.scheduleSetFeature(token, userId, feature, enabled, hardwareAuthToken, receiver,
+                    opPackageName);
         }
 
         @Override
         public void getFeature(final IBinder token, int userId, int feature,
                 IFaceServiceReceiver receiver, final String opPackageName) {
-            checkPermission(MANAGE_BIOMETRIC);
-
-            mHandler.post(() -> {
-                if (DEBUG) {
-                    Slog.d(TAG, "getFeature for user(" + userId + ")");
-                }
-                updateActiveGroup(userId);
-                // This should ideally return tri-state, but the user isn't shown settings unless
-                // they are enrolled so it's fine for now.
-                if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
-                    Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature);
-                    return;
-                }
-
-                // TODO: Support multiple faces
-                final int faceId = getFirstTemplateForUser(mCurrentUserId);
-
-                final FaceGetFeatureClient client = new FaceGetFeatureClient(getContext(),
-                        mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
-                        opPackageName, getSensorId(), feature, faceId);
-                startClient(client, true /* initiatedByClient */);
-            });
-
-        }
-
-        // TODO: Support multiple faces
-        private int getFirstTemplateForUser(int user) {
-            final List<Face> faces = FaceService.this.getEnrolledTemplates(user);
-            if (!faces.isEmpty()) {
-                return faces.get(0).getBiometricId();
-            }
-            return 0;
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFace10.scheduleGetFeature(token, userId, feature, receiver, opPackageName);
         }
 
         @Override // Binder call
         public void initializeConfiguration(int sensorId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            initializeConfigurationInternal(sensorId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFace10 = new Face10(getContext(), sensorId, mLockoutResetDispatcher);
         }
     }
 
-    private final LockoutHalImpl mLockoutTracker;
-
-    @GuardedBy("this")
-    private IBiometricsFace mDaemon;
-    private UsageStats mUsageStats;
-    private RevokeChallengeClient mPendingRevokeChallenge;
-
-    private NotificationManager mNotificationManager;
-
-    /**
-     * Receives callbacks from the HAL.
-     */
-    private IBiometricsFaceClientCallback mDaemonCallback =
-            new IBiometricsFaceClientCallback.Stub() {
-        @Override
-        public void onEnrollResult(final long deviceId, int faceId, int userId,
-                int remaining) {
-            mHandler.post(() -> {
-                final Face face = new Face(getBiometricUtils()
-                        .getUniqueName(getContext(), userId), faceId, deviceId);
-                FaceService.super.handleEnrollResult(face, remaining);
-
-                // Enrollment changes the authenticatorId, so update it here.
-                IBiometricsFace daemon = getFaceDaemon();
-                if (remaining == 0 && daemon != null) {
-                    try {
-                        mAuthenticatorIds.put(userId,
-                                hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value
-                                        : 0L);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "Unable to get authenticatorId", e);
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onAcquired(final long deviceId, final int userId, final int acquiredInfo,
-                final int vendorCode) {
-            mHandler.post(() -> {
-                FaceService.super.handleAcquired(acquiredInfo, vendorCode);
-            });
-        }
-
-        @Override
-        public void onAuthenticated(final long deviceId, final int faceId, final int userId,
-                ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                Face face = new Face("", faceId, deviceId);
-                FaceService.super.handleAuthenticated(face, token);
-            });
-        }
-
-        @Override
-        public void onError(final long deviceId, final int userId, final int error,
-                final int vendorCode) {
-            mHandler.post(() -> {
-                FaceService.super.handleError(error, vendorCode);
-
-                // TODO: this chunk of code should be common to all biometric services
-                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
-                    // If we get HW_UNAVAILABLE, try to connect again later...
-                    Slog.w(TAG, "Got ERROR_HW_UNAVAILABLE; try reconnecting next client.");
-                    synchronized (this) {
-                        mDaemon = null;
-                        mCurrentUserId = UserHandle.USER_NULL;
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRemoved(final long deviceId, ArrayList<Integer> faceIds, final int userId) {
-            mHandler.post(() -> {
-                if (!faceIds.isEmpty()) {
-                    for (int i = 0; i < faceIds.size(); i++) {
-                        final Face face = new Face("", faceIds.get(i), deviceId);
-                        // Convert to old behavior
-                        FaceService.super.handleRemoved(face, faceIds.size() - i - 1);
-                    }
-                } else {
-                    final Face face = new Face("", 0 /* identifier */, deviceId);
-                    FaceService.super.handleRemoved(face, 0 /* remaining */);
-                }
-                Settings.Secure.putIntForUser(getContext().getContentResolver(),
-                        Settings.Secure.FACE_UNLOCK_RE_ENROLL, 0, UserHandle.USER_CURRENT);
-            });
-        }
-
-        @Override
-        public void onEnumerate(long deviceId, ArrayList<Integer> faceIds, int userId)
-                throws RemoteException {
-            mHandler.post(() -> {
-                if (!faceIds.isEmpty()) {
-                    for (int i = 0; i < faceIds.size(); i++) {
-                        final Face face = new Face("", faceIds.get(i), deviceId);
-                        // Convert to old old behavior
-                        FaceService.super.handleEnumerate(face, faceIds.size() - i - 1);
-                    }
-                } else {
-                    // For face, the HIDL contract is to receive an empty list when there are no
-                    // templates enrolled. Send a null identifier since we don't consume them
-                    // anywhere, and send remaining == 0 to plumb this with existing common code.
-                    FaceService.super.handleEnumerate(null /* identifier */, 0);
-                }
-            });
-        }
-
-        @Override
-        public void onLockoutChanged(long duration) {
-            Slog.d(TAG, "onLockoutChanged: " + duration);
-
-            final @LockoutTracker.LockoutMode int lockoutMode;
-            if (duration == 0) {
-                lockoutMode = LockoutTracker.LOCKOUT_NONE;
-            } else if (duration == -1 || duration == Long.MAX_VALUE) {
-                lockoutMode = LockoutTracker.LOCKOUT_PERMANENT;
-            } else {
-                lockoutMode = LockoutTracker.LOCKOUT_TIMED;
-            }
-            mLockoutTracker.setCurrentUserLockoutMode(lockoutMode);
-
-            mHandler.post(() -> {
-                if (duration == 0) {
-                    mLockoutResetTracker.notifyLockoutResetCallbacks();
-                }
-            });
-        }
-    };
-
     public FaceService(Context context) {
         super(context);
-        mLazyDaemon = FaceService.this::getFaceDaemon;
-        mLockoutResetTracker = new LockoutResetTracker(context);
-        mLockoutTracker = new LockoutHalImpl();
-        mUsageStats = new UsageStats(context);
-        mNotificationManager = getContext().getSystemService(NotificationManager.class);
-    }
-
-    @Override
-    protected void removeClient(ClientMonitor client) {
-        super.removeClient(client);
-        if (mPendingRevokeChallenge != null) {
-            revokeChallengeInternal(mPendingRevokeChallenge);
-            mPendingRevokeChallenge = null;
-        }
+        mLockoutResetDispatcher = new LockoutResetDispatcher(context);
     }
 
     @Override
     public void onStart() {
-        super.onStart();
         publishBinderService(Context.FACE_SERVICE, new FaceServiceWrapper());
-        // Get the face daemon on FaceService's on thread so SystemServerInitThreadPool isn't
-        // blocked
-        SystemServerInitThreadPool.submit(() -> mHandler.post(this::getFaceDaemon),
-                TAG + ".onStart");
-    }
-
-    @Override
-    public String getTag() {
-        return TAG;
-    }
-
-    @Override
-    protected IBiometricsFace getDaemon() {
-        return getFaceDaemon();
-    }
-
-    @Override
-    protected BiometricUtils getBiometricUtils() {
-        return FaceUtils.getInstance();
-    }
-
-    @Override
-    protected boolean hasReachedEnrollmentLimit(int userId) {
-        final int limit = getContext().getResources().getInteger(
-                com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
-        final int enrolled = FaceService.this.getEnrolledTemplates(userId).size();
-        if (enrolled >= limit) {
-            Slog.w(TAG, "Too many faces registered, user: " + userId);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void serviceDied(long cookie) {
-        super.serviceDied(cookie);
-        mDaemon = null;
-
-        mCurrentUserId = UserHandle.USER_NULL; // Force updateActiveGroup() to re-evaluate
-    }
-
-    @Override
-    protected void updateActiveGroup(int userId) {
-        IBiometricsFace daemon = getFaceDaemon();
-
-        if (daemon != null) {
-            try {
-                if (userId != mCurrentUserId) {
-                    final File baseDir = Environment.getDataVendorDeDirectory(userId);
-                    final File faceDir = new File(baseDir, FACE_DATA_DIR);
-                    if (!faceDir.exists()) {
-                        if (!faceDir.mkdir()) {
-                            Slog.v(TAG, "Cannot make directory: " + faceDir.getAbsolutePath());
-                            return;
-                        }
-                        // Calling mkdir() from this process will create a directory with our
-                        // permissions (inherited from the containing dir). This command fixes
-                        // the label.
-                        if (!SELinux.restorecon(faceDir)) {
-                            Slog.w(TAG, "Restorecons failed. Directory will have wrong label.");
-                            return;
-                        }
-                    }
-
-                    daemon.setActiveUser(userId, faceDir.getAbsolutePath());
-                    mCurrentUserId = userId;
-                    mAuthenticatorIds.put(userId,
-                            hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value : 0L);
-                }
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to setActiveUser():", e);
-            }
-        }
-    }
-
-    @Override
-    protected void handleUserSwitching(int userId) {
-        super.handleUserSwitching(userId);
-        // Will be updated when we get the callback from HAL
-        mLockoutTracker.setCurrentUserLockoutMode(LockoutTracker.LOCKOUT_NONE);
-    }
-
-    @Override
-    protected boolean hasEnrolledBiometrics(int userId) {
-        if (userId != UserHandle.getCallingUserId()) {
-            checkPermission(INTERACT_ACROSS_USERS);
-        }
-        return getBiometricUtils().getBiometricsForUser(getContext(), userId).size() > 0;
-    }
-
-    @Override
-    protected String getManageBiometricPermission() {
-        return MANAGE_BIOMETRIC;
-    }
-
-    @Override
-    protected void checkUseBiometricPermission() {
-        // noop for Face. The permission checks are all done on the incoming binder call.
-    }
-
-    @Override
-    protected boolean checkAppOps(int uid, String opPackageName) {
-        return mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName)
-                == AppOpsManager.MODE_ALLOWED;
-    }
-
-    @Override
-    protected List<Face> getEnrolledTemplates(int userId) {
-        return FaceUtils.getInstance().getBiometricsForUser(getContext(), userId);
-    }
-
-    @Override
-    protected void notifyClientActiveCallbacks(boolean isActive) {
-        // noop for Face.
-    }
-
-    @Override
-    protected int statsModality() {
-        return BiometricsProtoEnums.MODALITY_FACE;
-    }
-
-    @Override
-    protected @LockoutTracker.LockoutMode int getLockoutMode(int userId) {
-        return mLockoutTracker.getLockoutModeForUser(userId);
-    }
-
-    @Override
-    protected void doTemplateCleanupForUser(int userId) {
-        final List<Face> enrolledList = getEnrolledTemplates(userId);
-        final FaceInternalCleanupClient client = new FaceInternalCleanupClient(getContext(),
-                mLazyDaemon, userId, getContext().getOpPackageName(), getSensorId(), enrolledList,
-                getBiometricUtils(), mAuthenticatorIds);
-        cleanupInternal(client);
-    }
-
-
-    /** Gets the face daemon */
-    private synchronized IBiometricsFace getFaceDaemon() {
-        if (mDaemon == null) {
-            Slog.v(TAG, "mDaemon was null, reconnect to face");
-            try {
-                mDaemon = IBiometricsFace.getService();
-            } catch (java.util.NoSuchElementException e) {
-                // Service doesn't exist or cannot be opened. Logged below.
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to get biometric interface", e);
-            }
-            if (mDaemon == null) {
-                Slog.w(TAG, "face HIDL not available");
-                return null;
-            }
-
-            mDaemon.asBinder().linkToDeath(this, 0);
-
-            long halId = 0;
-            try {
-                halId = mDaemon.setCallback(mDaemonCallback).value;
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to open face HAL", e);
-                mDaemon = null; // try again later!
-            }
-
-            if (DEBUG) Slog.v(TAG, "Face HAL id: " + halId);
-            if (halId != 0) {
-                loadAuthenticatorIds();
-                updateActiveGroup(ActivityManager.getCurrentUser());
-                doTemplateCleanupForUser(ActivityManager.getCurrentUser());
-            } else {
-                Slog.w(TAG, "Failed to open Face HAL!");
-                MetricsLogger.count(getContext(), "faced_openhal_error", 1);
-                mDaemon = null;
-            }
-        }
-        return mDaemon;
     }
 
     private native NativeHandle convertSurfaceToNativeHandle(Surface surface);
-
-    private void dumpInternal(PrintWriter pw) {
-        PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(getSensorId());
-
-        JSONObject dump = new JSONObject();
-        try {
-            dump.put("service", "Face Manager");
-
-            JSONArray sets = new JSONArray();
-            for (UserInfo user : UserManager.get(getContext()).getUsers()) {
-                final int userId = user.getUserHandle().getIdentifier();
-                final int N = getBiometricUtils().getBiometricsForUser(getContext(), userId).size();
-                JSONObject set = new JSONObject();
-                set.put("id", userId);
-                set.put("count", N);
-                set.put("accept", performanceTracker.getAcceptForUser(userId));
-                set.put("reject", performanceTracker.getRejectForUser(userId));
-                set.put("acquire", performanceTracker.getAcquireForUser(userId));
-                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
-                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
-                // cryptoStats measures statistics about secure face transactions
-                // (e.g. to unlock password storage, make secure purchases, etc.)
-                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
-                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
-                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
-                sets.put(set);
-            }
-
-            dump.put("prints", sets);
-        } catch (JSONException e) {
-            Slog.e(TAG, "dump formatting failure", e);
-        }
-        pw.println(dump);
-        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
-
-        mUsageStats.print(pw);
-    }
-
-    private void dumpHal(FileDescriptor fd, String[] args) {
-        // WARNING: CDD restricts image data from leaving TEE unencrypted on
-        //          production devices:
-        // [C-1-10] MUST not allow unencrypted access to identifiable biometric
-        //          data or any data derived from it (such as embeddings) to the
-        //         Application Processor outside the context of the TEE.
-        //  As such, this API should only be enabled for testing purposes on
-        //  engineering and userdebug builds.  All modules in the software stack
-        //  MUST enforce final build products do NOT have this functionality.
-        //  Additionally, the following check MUST NOT be removed.
-        if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
-            return;
-        }
-
-        // Additionally, this flag allows turning off face for a device
-        // (either permanently through the build or on an individual device).
-        if (SystemProperties.getBoolean("ro.face.disable_debug_data", false)
-                || SystemProperties.getBoolean("persist.face.disable_debug_data", false)) {
-            return;
-        }
-
-        // The debug method takes two file descriptors. The first is for text
-        // output, which we will drop.  The second is for binary data, which
-        // will be the protobuf data.
-        final IBiometricsFace daemon = getFaceDaemon();
-        if (daemon != null) {
-            FileOutputStream devnull = null;
-            try {
-                devnull = new FileOutputStream("/dev/null");
-                final NativeHandle handle = new NativeHandle(
-                        new FileDescriptor[] { devnull.getFD(), fd },
-                        new int[0], false);
-                daemon.debug(handle, new ArrayList<String>(Arrays.asList(args)));
-            } catch (IOException | RemoteException ex) {
-                Slog.d(TAG, "error while reading face debugging data", ex);
-            } finally {
-                if (devnull != null) {
-                    try {
-                        devnull.close();
-                    } catch (IOException ex) {
-                    }
-                }
-            }
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
new file mode 100644
index 0000000..bcf304e
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceUpdateActiveUserClient.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.face;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.face.V1_0.IBiometricsFace;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.ClientMonitor;
+
+import java.io.File;
+import java.util.Map;
+
+public class FaceUpdateActiveUserClient extends ClientMonitor<IBiometricsFace> {
+    private static final String TAG = "FaceUpdateActiveUserClient";
+    private static final String FACE_DATA_DIR = "facedata";
+
+    private final int mCurrentUserId;
+    private final boolean mHasEnrolledBiometrics;
+    @NonNull private final Map<Integer, Long> mAuthenticatorIds;
+
+    FaceUpdateActiveUserClient(@NonNull Context context,
+            @NonNull LazyDaemon<IBiometricsFace> lazyDaemon,  int userId, @NonNull String owner,
+            int sensorId, int currentUserId, boolean hasEnrolledBIometrics,
+            @NonNull Map<Integer, Long> authenticatorIds) {
+        super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner,
+                0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN,
+                BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN);
+        mCurrentUserId = currentUserId;
+        mHasEnrolledBiometrics = hasEnrolledBIometrics;
+        mAuthenticatorIds = authenticatorIds;
+    }
+
+    @Override
+    public void start(@NonNull FinishCallback finishCallback) {
+        super.start(finishCallback);
+
+        if (mCurrentUserId == getTargetUserId()) {
+            Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId");
+            try {
+                mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics
+                        ? getFreshDaemon().getAuthenticatorId().value : 0L);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to refresh authenticatorId", e);
+            }
+            finishCallback.onClientFinished(this, true /* success */);
+            return;
+        }
+
+        startHalOperation();
+    }
+
+    @Override
+    public void unableToStart() {
+        // Nothing to do here
+    }
+
+    @Override
+    protected void startHalOperation() {
+        final File storePath = new File(Environment.getDataVendorDeDirectory(getTargetUserId()),
+                FACE_DATA_DIR);
+        if (!storePath.exists()) {
+            Slog.e(TAG, "vold has not created the directory?");
+            mFinishCallback.onClientFinished(this, false /* success */);
+            return;
+        }
+
+        try {
+            getFreshDaemon().setActiveUser(getTargetUserId(), storePath.getAbsolutePath());
+            mFinishCallback.onClientFinished(this, true /* success */);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to setActiveUser: " + e);
+            mFinishCallback.onClientFinished(this, false /* success */);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java
new file mode 100644
index 0000000..9f94c88
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Fingerprint21.java
@@ -0,0 +1,656 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.IActivityTaskManager;
+import android.app.SynchronousUserSwitchObserver;
+import android.app.TaskStackListener;
+import android.app.UserSwitchObserver;
+import android.content.Context;
+import android.content.pm.UserInfo;
+import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.IFingerprintServiceReceiver;
+import android.hardware.fingerprint.IUdfpsOverlayController;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IHwBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+import android.view.Surface;
+
+import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.Utils;
+import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto;
+import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto;
+import com.android.server.biometrics.fingerprint.PerformanceStatsProto;
+import com.android.server.biometrics.sensors.AcquisitionClient;
+import com.android.server.biometrics.sensors.AuthenticationClient;
+import com.android.server.biometrics.sensors.BiometricScheduler;
+import com.android.server.biometrics.sensors.ClientMonitor;
+import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
+import com.android.server.biometrics.sensors.EnumerateConsumer;
+import com.android.server.biometrics.sensors.Interruptable;
+import com.android.server.biometrics.sensors.LockoutResetDispatcher;
+import com.android.server.biometrics.sensors.LockoutTracker;
+import com.android.server.biometrics.sensors.PerformanceTracker;
+import com.android.server.biometrics.sensors.RemovalConsumer;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Supports a single instance of the {@link android.hardware.biometrics.fingerprint.V2_1} or
+ * its extended minor versions.
+ */
+class Fingerprint21 implements IHwBinder.DeathRecipient {
+
+    private static final String TAG = "Fingerprint21";
+    private static final int ENROLL_TIMEOUT_SEC = 60;
+
+    private final Context mContext;
+    private final IActivityTaskManager mActivityTaskManager;
+    private final SensorProperties mSensorProperties;
+    private final BiometricScheduler mScheduler;
+    private final Handler mHandler;
+    private final LockoutResetDispatcher mLockoutResetDispatcher;
+    private final LockoutFrameworkImpl mLockoutTracker;
+    private final BiometricTaskStackListener mTaskStackListener;
+    private final ClientMonitor.LazyDaemon<IBiometricsFingerprint> mLazyDaemon;
+    private final Map<Integer, Long> mAuthenticatorIds;
+
+    @Nullable private IBiometricsFingerprint mDaemon;
+    @Nullable private IUdfpsOverlayController mUdfpsOverlayController;
+    private int mCurrentUserId = UserHandle.USER_NULL;
+
+    /**
+     * Static properties that never change for a given sensor.
+     */
+    private static final class SensorProperties {
+        final int sensorId;
+        final boolean isUdfps;
+
+        SensorProperties(int sensorId, boolean isUdfps) {
+            this.sensorId = sensorId;
+            this.isUdfps = isUdfps;
+        }
+    }
+
+    private final class BiometricTaskStackListener extends TaskStackListener {
+        @Override
+        public void onTaskStackChanged() {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof AuthenticationClient)) {
+                    Slog.e(TAG, "Task stack changed for client: " + client);
+                    return;
+                }
+                if (Utils.isKeyguard(mContext, client.getOwnerString())) {
+                    return; // Keyguard is always allowed
+                }
+
+                try {
+                    final List<ActivityManager.RunningTaskInfo> runningTasks =
+                            mActivityTaskManager.getTasks(1);
+                    if (!runningTasks.isEmpty()) {
+                        final String topPackage = runningTasks.get(0).topActivity.getPackageName();
+                        if (!topPackage.contentEquals(client.getOwnerString())
+                                && !client.isAlreadyDone()) {
+                            Slog.e(TAG, "Stopping background authentication, top: "
+                                    + topPackage + " currentClient: " + client);
+                            mScheduler.cancelAuthentication(client.getToken());
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(TAG, "Unable to get running tasks", e);
+                }
+            });
+        }
+    }
+
+    private final LockoutFrameworkImpl.LockoutResetCallback mLockoutResetCallback =
+            new LockoutFrameworkImpl.LockoutResetCallback() {
+        @Override
+        public void onLockoutReset(int userId) {
+            mLockoutResetDispatcher.notifyLockoutResetCallbacks(mSensorProperties.sensorId);
+        }
+    };
+
+    private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() {
+        @Override
+        public void onUserSwitching(int newUserId) {
+            scheduleInternalCleanup(newUserId);
+        }
+    };
+
+    private final IBiometricsFingerprintClientCallback mDaemonCallback =
+            new IBiometricsFingerprintClientCallback.Stub() {
+        @Override
+        public void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining) {
+            mHandler.post(() -> {
+                final CharSequence name = FingerprintUtils.getInstance()
+                        .getUniqueName(mContext, mCurrentUserId);
+                final Fingerprint fingerprint = new Fingerprint(name, groupId, fingerId, deviceId);
+
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof FingerprintEnrollClient)) {
+                    Slog.e(TAG, "onEnrollResult for non-enroll client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client;
+                enrollClient.onEnrollResult(fingerprint, remaining);
+            });
+        }
+
+        @Override
+        public void onAcquired(long deviceId, int acquiredInfo, int vendorCode) {
+            onAcquired_2_2(deviceId, acquiredInfo, vendorCode);
+        }
+
+        @Override
+        public void onAcquired_2_2(long deviceId, int acquiredInfo, int vendorCode) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof AcquisitionClient)) {
+                    Slog.e(TAG, "onAcquired for non-acquisition client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
+                acquisitionClient.onAcquired(acquiredInfo, vendorCode);
+            });
+        }
+
+        @Override
+        public void onAuthenticated(long deviceId, int fingerId, int groupId,
+                ArrayList<Byte> token) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof FingerprintAuthenticationClient)) {
+                    Slog.e(TAG, "onAuthenticated for non-authentication client: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final FingerprintAuthenticationClient authenticationClient =
+                        (FingerprintAuthenticationClient) client;
+                final boolean authenticated = fingerId != 0;
+                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
+                authenticationClient.onAuthenticated(fp, authenticated, token);
+            });
+        }
+
+        @Override
+        public void onError(long deviceId, int error, int vendorCode) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                Slog.d(TAG, "handleError"
+                        + ", client: " + (client != null ? client.getOwnerString() : null)
+                        + ", error: " + error
+                        + ", vendorCode: " + vendorCode);
+                if (!(client instanceof Interruptable)) {
+                    Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
+                    return;
+                }
+
+                final Interruptable interruptable = (Interruptable) client;
+                interruptable.onError(error, vendorCode);
+
+                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
+                    Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
+                    mDaemon = null;
+                    mCurrentUserId = UserHandle.USER_NULL;
+                }
+            });
+        }
+
+        @Override
+        public void onRemoved(long deviceId, int fingerId, int groupId, int remaining) {
+            mHandler.post(() -> {
+                Slog.d(TAG, "Removed, fingerId: " + fingerId + ", remaining: " + remaining);
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof RemovalConsumer)) {
+                    Slog.e(TAG, "onRemoved for non-removal consumer: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
+                final RemovalConsumer removalConsumer = (RemovalConsumer) client;
+                removalConsumer.onRemoved(fp, remaining);
+            });
+        }
+
+        @Override
+        public void onEnumerate(long deviceId, int fingerId, int groupId, int remaining) {
+            mHandler.post(() -> {
+                final ClientMonitor<?> client = mScheduler.getCurrentClient();
+                if (!(client instanceof EnumerateConsumer)) {
+                    Slog.e(TAG, "onEnumerate for non-enumerate consumer: "
+                            + Utils.getClientName(client));
+                    return;
+                }
+
+                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
+                final EnumerateConsumer enumerateConsumer = (EnumerateConsumer) client;
+                enumerateConsumer.onEnumerationResult(fp, remaining);
+            });
+        }
+    };
+
+    Fingerprint21(@NonNull Context context, int sensorId,
+            @NonNull LockoutResetDispatcher lockoutResetDispatcher,
+            @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
+        mContext = context;
+        mActivityTaskManager = ActivityTaskManager.getService();
+        mHandler = new Handler(Looper.getMainLooper());
+        mTaskStackListener = new BiometricTaskStackListener();
+        mAuthenticatorIds = Collections.synchronizedMap(new HashMap<>());
+        mLazyDaemon = Fingerprint21.this::getDaemon;
+        mLockoutResetDispatcher = lockoutResetDispatcher;
+        mLockoutTracker = new LockoutFrameworkImpl(context, mLockoutResetCallback);
+        mScheduler = new BiometricScheduler(TAG, gestureAvailabilityDispatcher);
+
+        try {
+            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to register user switch observer");
+        }
+
+        final IBiometricsFingerprint daemon = getDaemon();
+        boolean isUdfps = false;
+        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
+                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
+                        daemon);
+        if (extension != null) {
+            try {
+                isUdfps = extension.isUdfps(sensorId);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception while quering udfps", e);
+                isUdfps = false;
+            }
+        }
+        mSensorProperties = new SensorProperties(sensorId, isUdfps);
+    }
+
+    @Override
+    public void serviceDied(long cookie) {
+        Slog.e(TAG, "HAL died");
+        mHandler.post(() -> {
+            PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId)
+                    .incrementHALDeathCount();
+            mDaemon = null;
+            mCurrentUserId = UserHandle.USER_NULL;
+
+            final ClientMonitor<?> client = mScheduler.getCurrentClient();
+            if (client instanceof Interruptable) {
+                Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
+                final Interruptable interruptable = (Interruptable) client;
+                interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
+                        0 /* vendorCode */);
+
+                mScheduler.recordCrashState();
+
+                FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,
+                        BiometricsProtoEnums.MODALITY_FINGERPRINT,
+                        BiometricsProtoEnums.ISSUE_HAL_DEATH);
+            }
+        });
+    }
+
+    private synchronized IBiometricsFingerprint getDaemon() {
+        if (mDaemon != null) {
+            return mDaemon;
+        }
+
+        Slog.d(TAG, "Daemon was null, reconnecting, current operation: "
+                + mScheduler.getCurrentClient());
+        try {
+            mDaemon = IBiometricsFingerprint.getService();
+        } catch (java.util.NoSuchElementException e) {
+            // Service doesn't exist or cannot be opened.
+            Slog.w(TAG, "NoSuchElementException", e);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to get fingerprint HAL", e);
+        }
+
+        if (mDaemon == null) {
+            Slog.w(TAG, "Fingerprint HAL not available");
+            return null;
+        }
+
+        mDaemon.asBinder().linkToDeath(this, 0 /* flags */);
+
+        // HAL ID for these HIDL versions are only used to determine if callbacks have been
+        // successfully set.
+        long halId = 0;
+        try {
+            halId = mDaemon.setNotify(mDaemonCallback);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to set callback for fingerprint HAL", e);
+            mDaemon = null;
+        }
+
+        Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId);
+        if (halId != 0) {
+            scheduleLoadAuthenticatorIds();
+            scheduleInternalCleanup(ActivityManager.getCurrentUser());
+        } else {
+            Slog.e(TAG, "Unable to set callback");
+            mDaemon = null;
+        }
+
+        return mDaemon;
+    }
+
+    @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
+        return mLockoutTracker.getLockoutModeForUser(userId);
+    }
+
+    private void scheduleLoadAuthenticatorIds() {
+        // Note that this can be performed on the scheduler (as opposed to being done immediately
+        // when the HAL is (re)loaded, since
+        // 1) If this is truly the first time it's being performed (e.g. system has just started),
+        //    this will be run very early and way before any applications need to generate keys.
+        // 2) If this is being performed to refresh the authenticatorIds (e.g. HAL crashed and has
+        //    just been reloaded), the framework already has a cache of the authenticatorIds. This
+        //    is safe because authenticatorIds only change when A) new template has been enrolled,
+        //    or B) all templates are removed.
+        mHandler.post(() -> {
+            for (UserInfo user : UserManager.get(mContext).getUsers(true /* excludeDying */)) {
+                final int targetUserId = user.id;
+                if (!mAuthenticatorIds.containsKey(targetUserId)) {
+                    scheduleUpdateActiveUserWithoutHandler(targetUserId);
+                }
+            }
+        });
+    }
+
+    /**
+     * Schedules the {@link FingerprintUpdateActiveUserClient} without posting the work onto the
+     * handler. Many/most APIs are user-specific. However, the HAL requires explicit "setActiveUser"
+     * invocation prior to authenticate/enroll/etc. Thus, internally we usually want to schedule
+     * this operation on the same lambda/runnable as those operations so that the ordering is
+     * correct.
+     */
+    private void scheduleUpdateActiveUserWithoutHandler(int targetUserId) {
+        final boolean hasEnrolled = !getEnrolledFingerprints(targetUserId).isEmpty();
+        final FingerprintUpdateActiveUserClient client =
+                new FingerprintUpdateActiveUserClient(mContext, mLazyDaemon, targetUserId,
+                        mContext.getOpPackageName(), mSensorProperties.sensorId, mCurrentUserId,
+                        hasEnrolled, mAuthenticatorIds);
+        mScheduler.scheduleClientMonitor(client, (clientMonitor, success) -> {
+            if (success) {
+                mCurrentUserId = targetUserId;
+            }
+        });
+    }
+
+    void scheduleResetLockout(int userId, byte[] hardwareAuthToken) {
+        // Fingerprint2.1 keeps track of lockout in the framework. Let's just do it on the handler
+        // thread.
+        mHandler.post(() -> {
+            mLockoutTracker.resetFailedAttemptsForUser(true /* clearAttemptCounter */, userId);
+        });
+    }
+
+    void scheduleGenerateChallenge(@NonNull IBinder token,
+            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final FingerprintGenerateChallengeClient client =
+                    new FingerprintGenerateChallengeClient(mContext, mLazyDaemon, token,
+                            new ClientMonitorCallbackConverter(receiver), opPackageName,
+                            mSensorProperties.sensorId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleRevokeChallenge(@NonNull IBinder token, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+            final FingerprintRevokeChallengeClient client = new FingerprintRevokeChallengeClient(
+                    mContext, mLazyDaemon, token, opPackageName, mSensorProperties.sensorId);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void scheduleEnroll(@NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId,
+            @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName,
+            @Nullable Surface surface) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
+                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId,
+                    hardwareAuthToken, opPackageName, FingerprintUtils.getInstance(),
+                    ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController);
+            mScheduler.scheduleClientMonitor(client, ((clientMonitor, success) -> {
+                if (success) {
+                    // Update authenticatorIds
+                    scheduleUpdateActiveUserWithoutHandler(clientMonitor.getTargetUserId());
+                }
+            }));
+        });
+    }
+
+    void cancelEnrollment(@NonNull IBinder token) {
+        mHandler.post(() -> {
+            mScheduler.cancelEnrollment(token);
+        });
+    }
+
+    void scheduleAuthenticate(@NonNull IBinder token, long operationId, int userId, int cookie,
+            @NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName,
+            @Nullable Surface surface, boolean restricted, int statsClient) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
+            final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
+                    mContext, mLazyDaemon, token, listener, userId, operationId, restricted,
+                    opPackageName, cookie, false /* requireConfirmation */,
+                    mSensorProperties.sensorId, isStrongBiometric, surface, statsClient,
+                    mTaskStackListener, mLockoutTracker, mUdfpsOverlayController);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    void startPreparedClient(int cookie) {
+        mHandler.post(() -> {
+            mScheduler.startPreparedClient(cookie);
+        });
+    }
+
+    void cancelAuthentication(@NonNull IBinder token) {
+        mHandler.post(() -> {
+            mScheduler.cancelAuthentication(token);
+        });
+    }
+
+    void scheduleRemove(@NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver,
+            int fingerId, int userId, @NonNull String opPackageName) {
+        mHandler.post(() -> {
+           scheduleUpdateActiveUserWithoutHandler(userId);
+
+           final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
+                   mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), fingerId,
+                   userId, opPackageName, FingerprintUtils.getInstance(),
+                   mSensorProperties.sensorId, mAuthenticatorIds);
+           mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    private void scheduleInternalCleanup(int userId) {
+        mHandler.post(() -> {
+            scheduleUpdateActiveUserWithoutHandler(userId);
+
+            final List<Fingerprint> enrolledList = getEnrolledFingerprints(userId);
+            final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient(
+                    mContext, mLazyDaemon, userId, mContext.getOpPackageName(),
+                    mSensorProperties.sensorId, enrolledList, FingerprintUtils.getInstance(),
+                    mAuthenticatorIds);
+            mScheduler.scheduleClientMonitor(client);
+        });
+    }
+
+    boolean isHardwareDetected() {
+        final IBiometricsFingerprint daemon = getDaemon();
+        return daemon != null;
+    }
+
+    void rename(int fingerId, int userId, String name) {
+        mHandler.post(() -> {
+            FingerprintUtils.getInstance().renameBiometricForUser(mContext, userId, fingerId, name);
+        });
+    }
+
+    List<Fingerprint> getEnrolledFingerprints(int userId) {
+        return FingerprintUtils.getInstance().getBiometricsForUser(mContext, userId);
+    }
+
+    long getAuthenticatorId(int userId) {
+        return mAuthenticatorIds.get(userId);
+    }
+
+    void onFingerDown(int x, int y, float minor, float major) {
+        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+        if (!(client instanceof Udfps)) {
+            Slog.w(TAG, "onFingerDown received during client: " + client);
+            return;
+        }
+        final Udfps udfps = (Udfps) client;
+        udfps.onFingerDown(x, y, minor, major);
+    }
+
+    void onFingerUp() {
+        final ClientMonitor<?> client = mScheduler.getCurrentClient();
+        if (!(client instanceof Udfps)) {
+            Slog.w(TAG, "onFingerDown received during client: " + client);
+            return;
+        }
+        final Udfps udfps = (Udfps) client;
+        udfps.onFingerUp();
+    }
+
+    boolean isUdfps() {
+        return mSensorProperties.isUdfps;
+    }
+
+    void setUdfpsOverlayController(IUdfpsOverlayController controller) {
+        mUdfpsOverlayController = controller;
+    }
+
+    void dumpProto(FileDescriptor fd) {
+        PerformanceTracker tracker =
+                PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId);
+
+        final ProtoOutputStream proto = new ProtoOutputStream(fd);
+        for (UserInfo user : UserManager.get(mContext).getUsers()) {
+            final int userId = user.getUserHandle().getIdentifier();
+
+            final long userToken = proto.start(FingerprintServiceDumpProto.USERS);
+
+            proto.write(FingerprintUserStatsProto.USER_ID, userId);
+            proto.write(FingerprintUserStatsProto.NUM_FINGERPRINTS,
+                    FingerprintUtils.getInstance().getBiometricsForUser(mContext, userId).size());
+
+            // Normal fingerprint authentications (e.g. lockscreen)
+            long countsToken = proto.start(FingerprintUserStatsProto.NORMAL);
+            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptForUser(userId));
+            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectForUser(userId));
+            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireForUser(userId));
+            proto.write(PerformanceStatsProto.LOCKOUT, tracker.getTimedLockoutForUser(userId));
+            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT,
+                    tracker.getPermanentLockoutForUser(userId));
+            proto.end(countsToken);
+
+            // Statistics about secure fingerprint transactions (e.g. to unlock password
+            // storage, make secure purchases, etc.)
+            countsToken = proto.start(FingerprintUserStatsProto.CRYPTO);
+            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptCryptoForUser(userId));
+            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectCryptoForUser(userId));
+            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireCryptoForUser(userId));
+            proto.write(PerformanceStatsProto.LOCKOUT, 0); // meaningless for crypto
+            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, 0); // meaningless for crypto
+            proto.end(countsToken);
+
+            proto.end(userToken);
+        }
+        proto.flush();
+        tracker.clear();
+    }
+
+    void dumpInternal(@NonNull PrintWriter pw) {
+        PerformanceTracker performanceTracker =
+                PerformanceTracker.getInstanceForSensorId(mSensorProperties.sensorId);
+
+        JSONObject dump = new JSONObject();
+        try {
+            dump.put("service", "Fingerprint Manager");
+
+            JSONArray sets = new JSONArray();
+            for (UserInfo user : UserManager.get(mContext).getUsers()) {
+                final int userId = user.getUserHandle().getIdentifier();
+                final int N = FingerprintUtils.getInstance()
+                        .getBiometricsForUser(mContext, userId).size();
+                JSONObject set = new JSONObject();
+                set.put("id", userId);
+                set.put("count", N);
+                set.put("accept", performanceTracker.getAcceptForUser(userId));
+                set.put("reject", performanceTracker.getRejectForUser(userId));
+                set.put("acquire", performanceTracker.getAcquireForUser(userId));
+                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
+                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
+                // cryptoStats measures statistics about secure fingerprint transactions
+                // (e.g. to unlock password storage, make secure purchases, etc.)
+                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
+                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
+                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
+                sets.put(set);
+            }
+
+            dump.put("prints", sets);
+        } catch (JSONException e) {
+            Slog.e(TAG, "dump formatting failure", e);
+        }
+        pw.println(dump);
+        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
+        mScheduler.dump(pw);
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
index b01b856..1999a0f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticationClient.java
@@ -25,6 +25,7 @@
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -41,11 +42,13 @@
  * {@link android.hardware.biometrics.fingerprint.V2_1} and
  * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
  */
-class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFingerprint> {
+class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFingerprint>
+        implements Udfps {
 
     private static final String TAG = "Biometrics/FingerprintAuthClient";
 
     private final LockoutFrameworkImpl mLockoutFrameworkImpl;
+    @Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
 
     FingerprintAuthenticationClient(@NonNull Context context,
             @NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
@@ -53,12 +56,34 @@
             boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
             int sensorId, boolean isStrongBiometric, @Nullable Surface surface, int statsClient,
             @NonNull TaskStackListener taskStackListener,
-            @NonNull LockoutFrameworkImpl lockoutTracker) {
+            @NonNull LockoutFrameworkImpl lockoutTracker,
+            @Nullable IUdfpsOverlayController udfpsOverlayController) {
         super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
                 owner, cookie, requireConfirmation, sensorId, isStrongBiometric,
                 BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
                 lockoutTracker);
         mLockoutFrameworkImpl = lockoutTracker;
+        mUdfpsOverlayController = udfpsOverlayController;
+    }
+
+    private void showUdfpsOverlay() {
+        if (mUdfpsOverlayController != null) {
+            try {
+                mUdfpsOverlayController.showUdfpsOverlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
+            }
+        }
+    }
+
+    private void hideUdfpsOverlay() {
+        if (mUdfpsOverlayController != null) {
+            try {
+                mUdfpsOverlayController.hideUdfpsOverlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e);
+            }
+        }
     }
 
     @Override
@@ -73,18 +98,22 @@
 
         if (authenticated) {
             resetFailedAttempts(getTargetUserId());
+            hideUdfpsOverlay();
             mFinishCallback.onClientFinished(this, true /* success */);
         } else {
             final @LockoutTracker.LockoutMode int lockoutMode =
                     mLockoutFrameworkImpl.getLockoutModeForUser(getTargetUserId());
             if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
                 Slog.w(TAG, "Fingerprint locked out, lockoutMode(" + lockoutMode + ")");
-                cancel();
                 final int errorCode = lockoutMode == LockoutTracker.LOCKOUT_TIMED
                         ? BiometricConstants.BIOMETRIC_ERROR_LOCKOUT
                         : BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
-                onError(errorCode, 0 /* vendorCode */);
-                mFinishCallback.onClientFinished(this, true /* success */);
+                // Send the error, but do not invoke the FinishCallback yet. Since lockout is not
+                // controlled by the HAL, the framework must stop the sensor before finishing the
+                // client.
+                hideUdfpsOverlay();
+                onErrorInternal(errorCode, 0 /* vendorCode */, false /* finish */);
+                cancel();
             }
         }
     }
@@ -101,6 +130,7 @@
 
     @Override
     protected void startHalOperation() {
+        showUdfpsOverlay();
         try {
             // GroupId was never used. In fact, groupId is always the same as userId.
             getFreshDaemon().authenticate(mOperationId, getTargetUserId());
@@ -108,12 +138,14 @@
             Slog.e(TAG, "Remote exception when requesting auth", e);
             onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                     0 /* vendorCode */);
+            hideUdfpsOverlay();
             mFinishCallback.onClientFinished(this, false /* success */);
         }
     }
 
     @Override
     protected void stopHalOperation() {
+        hideUdfpsOverlay();
         try {
             getFreshDaemon().cancel();
         } catch (RemoteException e) {
@@ -123,4 +155,14 @@
             mFinishCallback.onClientFinished(this, false /* success */);
         }
     }
+
+    @Override
+    public void onFingerDown(int x, int y, float minor, float major) {
+        UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
+    }
+
+    @Override
+    public void onFingerUp() {
+        UdfpsHelper.onFingerUp(getFreshDaemon());
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
index 1d56882..25e949a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintEnrollClient.java
@@ -17,10 +17,12 @@
 package com.android.server.biometrics.sensors.fingerprint;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.biometrics.BiometricFingerprintConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Slog;
@@ -34,22 +36,61 @@
  * {@link android.hardware.biometrics.fingerprint.V2_1} and
  * {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
  */
-public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint> {
+public class FingerprintEnrollClient extends EnrollClient<IBiometricsFingerprint>
+        implements Udfps {
 
     private static final String TAG = "FingerprintEnrollClient";
 
+    @Nullable private final IUdfpsOverlayController mUdfpsOverlayController;
+
     FingerprintEnrollClient(@NonNull Context context,
             @NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
             @NonNull ClientMonitorCallbackConverter listener, int userId,
             @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils,
-            int timeoutSec, int sensorId) {
+            int timeoutSec, int sensorId,
+            @Nullable IUdfpsOverlayController udfpsOverlayController) {
         super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils,
                 timeoutSec, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId,
                 true /* shouldVibrate */);
+        mUdfpsOverlayController = udfpsOverlayController;
+    }
+
+    private void showUdfpsOverlay() {
+        if (mUdfpsOverlayController != null) {
+            try {
+                mUdfpsOverlayController.showUdfpsOverlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception when showing the UDFPS overlay", e);
+            }
+        }
+    }
+
+    private void hideUdfpsOverlay() {
+        if (mUdfpsOverlayController != null) {
+            try {
+                mUdfpsOverlayController.hideUdfpsOverlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote exception when hiding the UDFPS overlay", e);
+            }
+        }
+    }
+
+    @Override
+    protected boolean hasReachedEnrollmentLimit() {
+        final int limit = getContext().getResources().getInteger(
+                com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
+        final int enrolled = mBiometricUtils.getBiometricsForUser(getContext(), getTargetUserId())
+                .size();
+        if (enrolled >= limit) {
+            Slog.w(TAG, "Too many faces registered, user: " + getTargetUserId());
+            return true;
+        }
+        return false;
     }
 
     @Override
     protected void startHalOperation() {
+        showUdfpsOverlay();
         try {
             // GroupId was never used. In fact, groupId is always the same as userId.
             getFreshDaemon().enroll(mHardwareAuthToken, getTargetUserId(), mTimeoutSec);
@@ -57,12 +98,14 @@
             Slog.e(TAG, "Remote exception when requesting enroll", e);
             onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                     0 /* vendorCode */);
+            hideUdfpsOverlay();
             mFinishCallback.onClientFinished(this, false /* success */);
         }
     }
 
     @Override
     protected void stopHalOperation() {
+        hideUdfpsOverlay();
         try {
             getFreshDaemon().cancel();
         } catch (RemoteException e) {
@@ -72,4 +115,14 @@
             mFinishCallback.onClientFinished(this, false /* success */);
         }
     }
+
+    @Override
+    public void onFingerDown(int x, int y, float minor, float major) {
+        UdfpsHelper.onFingerDown(getFreshDaemon(), x, y, minor, major);
+    }
+
+    @Override
+    public void onFingerUp() {
+        UdfpsHelper.onFingerUp(getFreshDaemon());
+    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalCleanupClient.java
index 1d72c2e..571d2b8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintInternalCleanupClient.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
 import android.hardware.fingerprint.Fingerprint;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index b05400a..e0cb7ec9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -23,64 +23,39 @@
 import static android.Manifest.permission.USE_BIOMETRIC;
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.Manifest.permission.USE_FINGERPRINT;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
 
+import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.biometrics.IBiometricSensorReceiver;
 import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
 import android.hardware.fingerprint.Fingerprint;
 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
 import android.hardware.fingerprint.IFingerprintService;
 import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.hardware.fingerprint.IUdfpsOverlayController;
 import android.os.Binder;
-import android.os.Build;
-import android.os.Environment;
 import android.os.IBinder;
 import android.os.NativeHandle;
+import android.os.Process;
 import android.os.RemoteException;
-import android.os.SELinux;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
 import android.view.Surface;
 
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.logging.MetricsLogger;
 import com.android.internal.util.DumpUtils;
-import com.android.server.SystemServerInitThreadPool;
-import com.android.server.biometrics.fingerprint.FingerprintServiceDumpProto;
-import com.android.server.biometrics.fingerprint.FingerprintUserStatsProto;
-import com.android.server.biometrics.fingerprint.PerformanceStatsProto;
-import com.android.server.biometrics.sensors.AuthenticationClient;
-import com.android.server.biometrics.sensors.BiometricServiceBase;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.ClientMonitor;
+import com.android.server.SystemService;
+import com.android.server.biometrics.Utils;
 import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
-import com.android.server.biometrics.sensors.EnrollClient;
-import com.android.server.biometrics.sensors.GenerateChallengeClient;
-import com.android.server.biometrics.sensors.LockoutResetTracker;
+import com.android.server.biometrics.sensors.LockoutResetDispatcher;
 import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.PerformanceTracker;
-import com.android.server.biometrics.sensors.RemovalClient;
-import com.android.server.biometrics.sensors.RevokeChallengeClient;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -88,163 +63,130 @@
  * A service to manage multiple clients that want to access the fingerprint HAL API.
  * The service is responsible for maintaining a list of clients and dispatching all
  * fingerprint-related events.
- *
- * @hide
  */
-public class FingerprintService extends BiometricServiceBase<IBiometricsFingerprint> {
+public class FingerprintService extends SystemService {
 
     protected static final String TAG = "FingerprintService";
-    private static final boolean DEBUG = true;
-    private static final String FP_DATA_DIR = "fpdata";
 
-    private final LockoutResetTracker mLockoutResetTracker;
-    private final ClientMonitor.LazyDaemon<IBiometricsFingerprint> mLazyDaemon;
-    private final GestureAvailabilityTracker mGestureAvailabilityTracker;
+    private final AppOpsManager mAppOps;
+    private final LockoutResetDispatcher mLockoutResetDispatcher;
+    private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
+    private Fingerprint21 mFingerprint21;
 
     /**
      * Receives the incoming binder calls from FingerprintManager.
      */
     private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
-        private static final int ENROLL_TIMEOUT_SEC = 60;
-
-        /**
-         * The following methods contain common code which is shared in biometrics/common.
-         */
-
         @Override // Binder call
         public void generateChallenge(IBinder token, IFingerprintServiceReceiver receiver,
                 String opPackageName) {
-            checkPermission(MANAGE_FINGERPRINT);
-
-            final GenerateChallengeClient client = new FingerprintGenerateChallengeClient(
-                    getContext(), mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver),
-                    opPackageName, getSensorId());
-            generateChallengeInternal(client);
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mFingerprint21.scheduleGenerateChallenge(token, receiver, opPackageName);
         }
 
         @Override // Binder call
         public void revokeChallenge(IBinder token, String owner) {
-            checkPermission(MANAGE_FINGERPRINT);
-
-            final RevokeChallengeClient client = new FingerprintRevokeChallengeClient(getContext(),
-                    mLazyDaemon, token, owner, getSensorId());
-            revokeChallengeInternal(client);
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mFingerprint21.scheduleRevokeChallenge(token, owner);
         }
 
         @Override // Binder call
-        public void enroll(final IBinder token, final byte[] cryptoToken, final int userId,
+        public void enroll(final IBinder token, final byte[] hardwareAuthToken, final int userId,
                 final IFingerprintServiceReceiver receiver, final String opPackageName,
-                final Surface surface) {
-            checkPermission(MANAGE_FINGERPRINT);
-            updateActiveGroup(userId);
-
-            final EnrollClient client = new FingerprintEnrollClient(getContext(), mLazyDaemon,
-                    token, new ClientMonitorCallbackConverter(receiver), userId, cryptoToken,
-                    opPackageName, getBiometricUtils(), ENROLL_TIMEOUT_SEC, getSensorId());
-
-            enrollInternal(client, userId);
+                Surface surface) {
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mFingerprint21.scheduleEnroll(token, hardwareAuthToken, userId, receiver, opPackageName,
+                    surface);
         }
 
         @Override // Binder call
         public void cancelEnrollment(final IBinder token) {
-            checkPermission(MANAGE_FINGERPRINT);
-            cancelEnrollmentInternal(token);
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mFingerprint21.cancelEnrollment(token);
         }
 
         @Override // Binder call
-        public void authenticate(final IBinder token, final long opId, final int userId,
+        public void authenticate(final IBinder token, final long operationId, final int userId,
                 final IFingerprintServiceReceiver receiver, final String opPackageName,
-                final Surface surface) {
-            updateActiveGroup(userId);
+                Surface surface) {
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
+            final int callingUserId = UserHandle.getCallingUserId();
 
-            final boolean isStrongBiometric;
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                isStrongBiometric = isStrongBiometric();
-            } finally {
-                Binder.restoreCallingIdentity(ident);
+            if (!canUseFingerprint(opPackageName, true /* requireForeground */, callingUid,
+                    callingPid, callingUserId)) {
+                Slog.w(TAG, "Authenticate rejecting package: " + opPackageName);
+                return;
             }
 
-            final boolean restricted = isRestricted();
-            final int statsClient = isKeyguard(opPackageName) ? BiometricsProtoEnums.CLIENT_KEYGUARD
+            final boolean restricted = getContext().checkCallingPermission(MANAGE_FINGERPRINT)
+                    != PackageManager.PERMISSION_GRANTED;
+            final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
+                    ? BiometricsProtoEnums.CLIENT_KEYGUARD
                     : BiometricsProtoEnums.CLIENT_FINGERPRINT_MANAGER;
-            final AuthenticationClient client = new FingerprintAuthenticationClient(getContext(),
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, opId,
-                    restricted, opPackageName, 0 /* cookie */, false /* requireConfirmation */,
-                    getSensorId(), isStrongBiometric, surface, statsClient, mTaskStackListener,
-                    mLockoutTracker);
-            authenticateInternal(client, opPackageName);
+            mFingerprint21.scheduleAuthenticate(token, operationId, userId, 0 /* cookie */,
+                    new ClientMonitorCallbackConverter(receiver), opPackageName, surface,
+                    restricted, statsClient);
         }
 
         @Override // Binder call
-        public void prepareForAuthentication(IBinder token, long opId, int userId,
+        public void prepareForAuthentication(IBinder token, long operationId, int userId,
                 IBiometricSensorReceiver sensorReceiver, String opPackageName,
                 int cookie, int callingUid, int callingPid, int callingUserId,
                 Surface surface) {
-            checkPermission(MANAGE_BIOMETRIC);
-            updateActiveGroup(userId);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
 
             final boolean restricted = true; // BiometricPrompt is always restricted
-            final AuthenticationClient client = new FingerprintAuthenticationClient(getContext(),
-                    mLazyDaemon, token, new ClientMonitorCallbackConverter(sensorReceiver), userId,
-                    opId, restricted, opPackageName, cookie, false /* requireConfirmation */,
-                    getSensorId(), isStrongBiometric(), surface,
-                    BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, mTaskStackListener,
-                    mLockoutTracker);
-            authenticateInternal(client, opPackageName, callingUid, callingPid,
-                    callingUserId);
+            mFingerprint21.scheduleAuthenticate(token, operationId, userId, cookie,
+                    new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, surface,
+                    restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT);
         }
 
         @Override // Binder call
         public void startPreparedClient(int cookie) {
-            checkPermission(MANAGE_BIOMETRIC);
-            startCurrentClient(cookie);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFingerprint21.startPreparedClient(cookie);
         }
 
 
         @Override // Binder call
         public void cancelAuthentication(final IBinder token, final String opPackageName) {
-            cancelAuthenticationInternal(token, opPackageName);
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
+            final int callingUserId = UserHandle.getCallingUserId();
+
+            if (!canUseFingerprint(opPackageName, true /* requireForeground */, callingUid,
+                    callingPid, callingUserId)) {
+                Slog.w(TAG, "cancelAuthentication rejecting package: " + opPackageName);
+                return;
+            }
+
+            mFingerprint21.cancelAuthentication(token);
         }
 
         @Override // Binder call
         public void cancelAuthenticationFromService(final IBinder token, final String opPackageName,
                 int callingUid, int callingPid, int callingUserId) {
-            checkPermission(MANAGE_BIOMETRIC);
-            // Cancellation is from system server in this case.
-            cancelAuthenticationInternal(token, opPackageName, callingUid, callingPid,
-                    callingUserId, false /* fromClient */);
+            Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
+            mFingerprint21.cancelAuthentication(token);
         }
 
         @Override // Binder call
         public void remove(final IBinder token, final int fingerId, final int userId,
-                final IFingerprintServiceReceiver receiver, final String opPackageName)
-                throws RemoteException {
-            checkPermission(MANAGE_FINGERPRINT);
-            updateActiveGroup(userId);
-
-            if (token == null) {
-                Slog.w(TAG, "remove(): token is null");
-                return;
-            }
-
-            final RemovalClient client = new FingerprintRemovalClient(getContext(), mLazyDaemon,
-                    token, new ClientMonitorCallbackConverter(receiver), fingerId, userId,
-                    opPackageName, getBiometricUtils(), getSensorId(), mAuthenticatorIds);
-            removeInternal(client);
+                final IFingerprintServiceReceiver receiver, final String opPackageName) {
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mFingerprint21.scheduleRemove(token, receiver, fingerId, userId, opPackageName);
         }
 
         @Override
         public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback,
                 final String opPackageName) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            mHandler.post(() -> {
-                mLockoutResetTracker.addCallback(callback, opPackageName);
-            });
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mLockoutResetDispatcher.addCallback(callback, opPackageName);
         }
 
         @Override // Binder call
-        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, String[] args) {
             if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
                 return;
             }
@@ -252,23 +194,18 @@
             final long ident = Binder.clearCallingIdentity();
             try {
                 if (args.length > 0 && "--proto".equals(args[0])) {
-                    dumpProto(fd);
+                    mFingerprint21.dumpProto(fd);
                 } else {
-                    dumpInternal(pw);
+                    mFingerprint21.dumpInternal(pw);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
         }
 
-        /**
-         * The following methods don't use any common code from BiometricService
-         */
-
-        // TODO: refactor out common code here
         @Override // Binder call
         public boolean isHardwareDetected(String opPackageName) {
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
+            if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
                     Binder.getCallingUid(), Binder.getCallingPid(),
                     UserHandle.getCallingUserId())) {
                 return false;
@@ -276,8 +213,7 @@
 
             final long token = Binder.clearCallingIdentity();
             try {
-                IBiometricsFingerprint daemon = getFingerprintDaemon();
-                return daemon != null;
+                return mFingerprint21.isHardwareDetected();
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
@@ -285,389 +221,155 @@
 
         @Override // Binder call
         public void rename(final int fingerId, final int userId, final String name) {
-            checkPermission(MANAGE_FINGERPRINT);
-            if (!isCurrentUserOrProfile(userId)) {
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
                 return;
             }
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    getBiometricUtils().renameBiometricForUser(getContext(), userId, fingerId,
-                            name);
-                }
-            });
+
+            mFingerprint21.rename(fingerId, userId, name);
         }
 
         @Override // Binder call
         public List<Fingerprint> getEnrolledFingerprints(int userId, String opPackageName) {
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
+            if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
                     Binder.getCallingUid(), Binder.getCallingPid(),
                     UserHandle.getCallingUserId())) {
                 return Collections.emptyList();
             }
 
-            return FingerprintService.this.getEnrolledTemplates(userId);
+            if (userId != UserHandle.getCallingUserId()) {
+                Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
+            }
+            return mFingerprint21.getEnrolledFingerprints(userId);
         }
 
         @Override // Binder call
         public boolean hasEnrolledFingerprints(int userId, String opPackageName) {
-            if (!canUseBiometric(opPackageName, false /* foregroundOnly */,
+            if (!canUseFingerprint(opPackageName, false /* foregroundOnly */,
                     Binder.getCallingUid(), Binder.getCallingPid(),
                     UserHandle.getCallingUserId())) {
                 return false;
             }
 
-            return FingerprintService.this.hasEnrolledBiometrics(userId);
+            if (userId != UserHandle.getCallingUserId()) {
+                Utils.checkPermission(getContext(), INTERACT_ACROSS_USERS);
+            }
+            return mFingerprint21.getEnrolledFingerprints(userId).size() > 0;
         }
 
         @Override // Binder call
         public @LockoutTracker.LockoutMode int getLockoutModeForUser(int userId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            return mLockoutTracker.getLockoutModeForUser(userId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFingerprint21.getLockoutModeForUser(userId);
         }
 
         @Override // Binder call
-        public long getAuthenticatorId(int callingUserId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            return FingerprintService.this.getAuthenticatorId(callingUserId);
+        public long getAuthenticatorId(int userId) {
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFingerprint21.getAuthenticatorId(userId);
         }
 
         @Override // Binder call
-        public void resetLockout(int userId, byte [] hardwareAuthToken) throws RemoteException {
-            checkPermission(RESET_FINGERPRINT_LOCKOUT);
-            if (!FingerprintService.this.hasEnrolledBiometrics(userId)) {
-                Slog.w(TAG, "Ignoring lockout reset, no templates enrolled for user: " + userId);
-                return;
-            }
-
-            // TODO: confirm security token when we move timeout management into the HAL layer.
-            mHandler.post(() -> {
-                mLockoutTracker.resetFailedAttemptsForUser(true /* clearAttemptCounter */, userId);
-            });
+        public void resetLockout(int userId, byte [] hardwareAuthToken) {
+            Utils.checkPermission(getContext(), RESET_FINGERPRINT_LOCKOUT);
+            mFingerprint21.scheduleResetLockout(userId, hardwareAuthToken);
         }
 
         @Override
         public boolean isClientActive() {
-            checkPermission(MANAGE_FINGERPRINT);
-            synchronized(FingerprintService.this) {
-                return (getCurrentClient() != null) || (getPendingClient() != null);
-            }
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            return mGestureAvailabilityDispatcher.isAnySensorActive();
         }
 
         @Override
         public void addClientActiveCallback(IFingerprintClientActiveCallback callback) {
-            checkPermission(MANAGE_FINGERPRINT);
-            mGestureAvailabilityTracker.registerCallback(callback);
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mGestureAvailabilityDispatcher.registerCallback(callback);
         }
 
         @Override
         public void removeClientActiveCallback(IFingerprintClientActiveCallback callback) {
-            checkPermission(MANAGE_FINGERPRINT);
-            mGestureAvailabilityTracker.removeCallback(callback);
+            Utils.checkPermission(getContext(), MANAGE_FINGERPRINT);
+            mGestureAvailabilityDispatcher.removeCallback(callback);
         }
 
         @Override // Binder call
         public void initializeConfiguration(int sensorId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            initializeConfigurationInternal(sensorId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFingerprint21 = new Fingerprint21(getContext(), sensorId, mLockoutResetDispatcher,
+                    mGestureAvailabilityDispatcher);
         }
 
         @Override
         public void onFingerDown(int x, int y, float minor, float major) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            IBiometricsFingerprint daemon = getFingerprintDaemon();
-            if (daemon == null) {
-                Slog.e(TAG, "onFingerDown | daemon is null");
-            } else {
-                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
-                        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
-                                daemon);
-                if (extension == null) {
-                    Slog.v(TAG, "onFingerDown | failed to cast the HIDL to V2_3");
-                } else {
-                    try {
-                        extension.onFingerDown(x, y, minor, major);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "onFingerDown | RemoteException: ", e);
-                    }
-                }
-            }
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFingerprint21.onFingerDown(x, y, minor, major);
         }
 
         @Override
         public void onFingerUp() {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            IBiometricsFingerprint daemon = getFingerprintDaemon();
-            if (daemon == null) {
-                Slog.e(TAG, "onFingerUp | daemon is null");
-            } else {
-                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
-                        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
-                                daemon);
-                if (extension == null) {
-                    Slog.v(TAG, "onFingerUp | failed to cast the HIDL to V2_3");
-                } else {
-                    try {
-                        extension.onFingerUp();
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "onFingerUp | RemoteException: ", e);
-                    }
-                }
-            }
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFingerprint21.onFingerUp();
         }
 
         @Override
         public boolean isUdfps(int sensorId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            IBiometricsFingerprint daemon = getFingerprintDaemon();
-            if (daemon == null) {
-                Slog.e(TAG, "isUdfps | daemon is null");
-            } else {
-                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
-                        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
-                                daemon);
-                if (extension == null) {
-                    Slog.v(TAG, "isUdfps | failed to cast the HIDL to V2_3");
-                } else {
-                    try {
-                        return extension.isUdfps(sensorId);
-                    } catch (RemoteException e) {
-                        Slog.e(TAG, "isUdfps | RemoteException: ", e);
-                    }
-                }
-            }
-            return false;
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            return mFingerprint21.isUdfps();
         }
 
         @Override
-        public void showUdfpsOverlay() {
-            if (mUdfpsOverlayController == null) {
-                Slog.e(TAG, "showUdfpsOverlay | mUdfpsOverlayController is null");
-                return;
-            }
-            try {
-                mUdfpsOverlayController.showUdfpsOverlay();
-            } catch (RemoteException e) {
-                Slog.e(TAG, "showUdfpsOverlay | RemoteException: ", e);
-            }
-        }
-
-        @Override
-        public void hideUdfpsOverlay() {
-            if (mUdfpsOverlayController == null) {
-                Slog.e(TAG, "hideUdfpsOverlay | mUdfpsOverlayController is null");
-                return;
-            }
-            try {
-                mUdfpsOverlayController.hideUdfpsOverlay();
-            } catch (RemoteException e) {
-                Slog.e(TAG, "hideUdfpsOverlay | RemoteException: ", e);
-            }
-        }
-
         public void setUdfpsOverlayController(IUdfpsOverlayController controller) {
-            mUdfpsOverlayController = controller;
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
+            mFingerprint21.setUdfpsOverlayController(controller);
         }
     }
 
-    private final LockoutFrameworkImpl mLockoutTracker;
-    private IUdfpsOverlayController mUdfpsOverlayController;
-
-    @GuardedBy("this")
-    private IBiometricsFingerprint mDaemon;
-
-    /**
-     * Receives callbacks from the HAL.
-     */
-    private IBiometricsFingerprintClientCallback mDaemonCallback =
-            new IBiometricsFingerprintClientCallback.Stub() {
-        @Override
-        public void onEnrollResult(final long deviceId, final int fingerId, final int groupId,
-                final int remaining) {
-            mHandler.post(() -> {
-                final Fingerprint fingerprint =
-                        new Fingerprint(getBiometricUtils().getUniqueName(getContext(), groupId),
-                                groupId, fingerId, deviceId);
-                FingerprintService.super.handleEnrollResult(fingerprint, remaining);
-            });
-        }
-
-        @Override
-        public void onAcquired(final long deviceId, final int acquiredInfo, final int vendorCode) {
-            onAcquired_2_2(deviceId, acquiredInfo, vendorCode);
-        }
-
-        @Override
-        public void onAcquired_2_2(long deviceId, int acquiredInfo, int vendorCode) {
-            mHandler.post(() -> {
-                FingerprintService.super.handleAcquired(acquiredInfo, vendorCode);
-            });
-        }
-
-        @Override
-        public void onAuthenticated(final long deviceId, final int fingerId, final int groupId,
-                ArrayList<Byte> token) {
-            mHandler.post(() -> {
-                Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                FingerprintService.super.handleAuthenticated(fp, token);
-            });
-        }
-
-        @Override
-        public void onError(final long deviceId, final int error, final int vendorCode) {
-            mHandler.post(() -> {
-                FingerprintService.super.handleError(error, vendorCode);
-                // TODO: this chunk of code should be common to all biometric services
-                if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
-                    // If we get HW_UNAVAILABLE, try to connect again later...
-                    Slog.w(TAG, "Got ERROR_HW_UNAVAILABLE; try reconnecting next client.");
-                    synchronized (this) {
-                        mDaemon = null;
-                        mCurrentUserId = UserHandle.USER_NULL;
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void onRemoved(final long deviceId, final int fingerId, final int groupId,
-                final int remaining) {
-            mHandler.post(() -> {
-                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                FingerprintService.super.handleRemoved(fp, remaining);
-            });
-        }
-
-        @Override
-        public void onEnumerate(final long deviceId, final int fingerId, final int groupId,
-                final int remaining) {
-            mHandler.post(() -> {
-                final Fingerprint fp = new Fingerprint("", groupId, fingerId, deviceId);
-                FingerprintService.super.handleEnumerate(fp, remaining);
-            });
-
-        }
-    };
-
     public FingerprintService(Context context) {
         super(context);
-        mLazyDaemon = FingerprintService.this::getFingerprintDaemon;
-        mGestureAvailabilityTracker = new GestureAvailabilityTracker();
-        mLockoutResetTracker = new LockoutResetTracker(context);
-        final LockoutFrameworkImpl.LockoutResetCallback lockoutResetCallback = userId -> {
-            mLockoutResetTracker.notifyLockoutResetCallbacks();
-        };
-        mLockoutTracker = new LockoutFrameworkImpl(context, lockoutResetCallback);
+        mAppOps = context.getSystemService(AppOpsManager.class);
+        mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
+        mLockoutResetDispatcher = new LockoutResetDispatcher(context);
     }
 
     @Override
     public void onStart() {
-        super.onStart();
         publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
-        SystemServerInitThreadPool.submit(this::getFingerprintDaemon, TAG + ".onStart");
     }
 
-    @Override
-    protected String getTag() {
-        return TAG;
-    }
-
-    @Override
-    protected IBiometricsFingerprint getDaemon() {
-        return getFingerprintDaemon();
-    }
-
-    @Override
-    protected BiometricUtils getBiometricUtils() {
-        return FingerprintUtils.getInstance();
-    }
-
-    @Override
-    protected boolean hasReachedEnrollmentLimit(int userId) {
-        final int limit = getContext().getResources().getInteger(
-                com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser);
-        final int enrolled = FingerprintService.this.getEnrolledTemplates(userId).size();
-        if (enrolled >= limit) {
-            Slog.w(TAG, "Too many fingerprints registered");
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void serviceDied(long cookie) {
-        super.serviceDied(cookie);
-        mDaemon = null;
-    }
-
-    @Override
-    protected void updateActiveGroup(int userId) {
-        IBiometricsFingerprint daemon = getFingerprintDaemon();
-
-        if (daemon != null) {
-            try {
-                if (userId != mCurrentUserId) {
-                    int firstSdkInt = Build.VERSION.FIRST_SDK_INT;
-                    if (firstSdkInt < Build.VERSION_CODES.BASE) {
-                        Slog.e(TAG, "First SDK version " + firstSdkInt + " is invalid; must be " +
-                                "at least VERSION_CODES.BASE");
-                    }
-                    File baseDir;
-                    if (firstSdkInt <= Build.VERSION_CODES.O_MR1) {
-                        baseDir = Environment.getUserSystemDirectory(userId);
-                    } else {
-                        baseDir = Environment.getDataVendorDeDirectory(userId);
-                    }
-
-                    File fpDir = new File(baseDir, FP_DATA_DIR);
-                    if (!fpDir.exists()) {
-                        if (!fpDir.mkdir()) {
-                            Slog.v(TAG, "Cannot make directory: " + fpDir.getAbsolutePath());
-                            return;
-                        }
-                        // Calling mkdir() from this process will create a directory with our
-                        // permissions (inherited from the containing dir). This command fixes
-                        // the label.
-                        if (!SELinux.restorecon(fpDir)) {
-                            Slog.w(TAG, "Restorecons failed. Directory will have wrong label.");
-                            return;
-                        }
-                    }
-
-                    daemon.setActiveGroup(userId, fpDir.getAbsolutePath());
-                    mCurrentUserId = userId;
-                }
-                mAuthenticatorIds.put(userId,
-                        hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId() : 0L);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to setActiveGroup():", e);
-            }
-        }
-    }
-
-    @Override
-    protected boolean hasEnrolledBiometrics(int userId) {
-        if (userId != UserHandle.getCallingUserId()) {
-            checkPermission(INTERACT_ACROSS_USERS);
-        }
-        return getBiometricUtils().getBiometricsForUser(getContext(), userId).size() > 0;
-    }
-
-    @Override
-    protected String getManageBiometricPermission() {
-        return MANAGE_FINGERPRINT;
-    }
-
-    @Override
-    protected void checkUseBiometricPermission() {
+    /**
+     * Checks for public API invocations to ensure that permissions, etc are granted/correct.
+     */
+    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
+    private boolean canUseFingerprint(String opPackageName, boolean requireForeground, int uid,
+            int pid, int userId) {
         if (getContext().checkCallingPermission(USE_FINGERPRINT)
                 != PackageManager.PERMISSION_GRANTED) {
-            checkPermission(USE_BIOMETRIC);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC);
         }
+
+        if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+            return true; // System process (BiometricService, etc) is always allowed
+        }
+        if (Utils.isKeyguard(getContext(), opPackageName)) {
+            return true;
+        }
+        if (!Utils.isCurrentUserOrProfile(getContext(), userId)) {
+            Slog.w(TAG, "Rejecting " + opPackageName + "; not a current user or profile");
+            return false;
+        }
+        if (!checkAppOps(uid, opPackageName)) {
+            Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
+            return false;
+        }
+        if (requireForeground && !(isForegroundActivity(uid, pid))) {
+            Slog.w(TAG, "Rejecting " + opPackageName + "; not in foreground");
+            return false;
+        }
+        return true;
     }
 
-    @Override
-    protected boolean checkAppOps(int uid, String opPackageName) {
+    private boolean checkAppOps(int uid, String opPackageName) {
         boolean appOpsOk = false;
         if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, uid, opPackageName)
                 == AppOpsManager.MODE_ALLOWED) {
@@ -679,154 +381,28 @@
         return appOpsOk;
     }
 
-    @Override
-    protected List<Fingerprint> getEnrolledTemplates(int userId) {
-        if (userId != UserHandle.getCallingUserId()) {
-            checkPermission(INTERACT_ACROSS_USERS);
+    private boolean isForegroundActivity(int uid, int pid) {
+        try {
+            final List<ActivityManager.RunningAppProcessInfo> procs =
+                    ActivityManager.getService().getRunningAppProcesses();
+            if (procs == null) {
+                Slog.e(TAG, "Processes null, defaulting to true");
+                return true;
+            }
+
+            int N = procs.size();
+            for (int i = 0; i < N; i++) {
+                ActivityManager.RunningAppProcessInfo proc = procs.get(i);
+                if (proc.pid == pid && proc.uid == uid
+                        && proc.importance <= IMPORTANCE_FOREGROUND_SERVICE) {
+                    return true;
+                }
+            }
+        } catch (RemoteException e) {
+            Slog.w(TAG, "am.getRunningAppProcesses() failed");
         }
-        return FingerprintUtils.getInstance().getBiometricsForUser(getContext(), userId);
-    }
-
-    @Override
-    protected void notifyClientActiveCallbacks(boolean isActive) {
-        mGestureAvailabilityTracker.notifyClientActiveCallbacks(isActive);
-    }
-
-    @Override
-    protected int statsModality() {
-        return BiometricsProtoEnums.MODALITY_FINGERPRINT;
-    }
-
-    @Override
-    protected @LockoutTracker.LockoutMode int getLockoutMode(int userId) {
-        return mLockoutTracker.getLockoutModeForUser(userId);
-    }
-
-    @Override
-    protected void doTemplateCleanupForUser(int userId) {
-        final List<Fingerprint> enrolledList = getEnrolledTemplates(userId);
-        final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient(
-                getContext(), mLazyDaemon, userId, getContext().getOpPackageName(), getSensorId(),
-                enrolledList, getBiometricUtils(), mAuthenticatorIds);
-        cleanupInternal(client);
-    }
-
-    /** Gets the fingerprint daemon */
-    private synchronized IBiometricsFingerprint getFingerprintDaemon() {
-        if (mDaemon == null) {
-            Slog.v(TAG, "mDaemon was null, reconnect to fingerprint");
-            try {
-                mDaemon = IBiometricsFingerprint.getService();
-            } catch (java.util.NoSuchElementException e) {
-                // Service doesn't exist or cannot be opened. Logged below.
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to get biometric interface", e);
-            }
-            if (mDaemon == null) {
-                Slog.w(TAG, "fingerprint HIDL not available");
-                return null;
-            }
-
-            mDaemon.asBinder().linkToDeath(this, 0);
-
-            long halId = 0;
-            try {
-                halId = mDaemon.setNotify(mDaemonCallback);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to open fingerprint HAL", e);
-                mDaemon = null; // try again later!
-            }
-
-            if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + halId);
-            if (halId != 0) {
-                loadAuthenticatorIds();
-                final int userId = ActivityManager.getCurrentUser();
-                updateActiveGroup(userId);
-                doTemplateCleanupForUser(userId);
-            } else {
-                Slog.w(TAG, "Failed to open Fingerprint HAL!");
-                MetricsLogger.count(getContext(), "fingerprintd_openhal_error", 1);
-                mDaemon = null;
-            }
-        }
-        return mDaemon;
+        return false;
     }
 
     private native NativeHandle convertSurfaceToNativeHandle(Surface surface);
-
-    private void dumpInternal(PrintWriter pw) {
-        PerformanceTracker performanceTracker =
-                PerformanceTracker.getInstanceForSensorId(getSensorId());
-
-        JSONObject dump = new JSONObject();
-        try {
-            dump.put("service", "Fingerprint Manager");
-
-            JSONArray sets = new JSONArray();
-            for (UserInfo user : UserManager.get(getContext()).getUsers()) {
-                final int userId = user.getUserHandle().getIdentifier();
-                final int N = getBiometricUtils().getBiometricsForUser(getContext(), userId).size();
-                JSONObject set = new JSONObject();
-                set.put("id", userId);
-                set.put("count", N);
-                set.put("accept", performanceTracker.getAcceptForUser(userId));
-                set.put("reject", performanceTracker.getRejectForUser(userId));
-                set.put("acquire", performanceTracker.getAcquireForUser(userId));
-                set.put("lockout", performanceTracker.getTimedLockoutForUser(userId));
-                set.put("permanentLockout", performanceTracker.getPermanentLockoutForUser(userId));
-                // cryptoStats measures statistics about secure fingerprint transactions
-                // (e.g. to unlock password storage, make secure purchases, etc.)
-                set.put("acceptCrypto", performanceTracker.getAcceptCryptoForUser(userId));
-                set.put("rejectCrypto", performanceTracker.getRejectCryptoForUser(userId));
-                set.put("acquireCrypto", performanceTracker.getAcquireCryptoForUser(userId));
-                sets.put(set);
-            }
-
-            dump.put("prints", sets);
-        } catch (JSONException e) {
-            Slog.e(TAG, "dump formatting failure", e);
-        }
-        pw.println(dump);
-        pw.println("HAL deaths since last reboot: " + performanceTracker.getHALDeathCount());
-    }
-
-    private void dumpProto(FileDescriptor fd) {
-        PerformanceTracker tracker =
-                PerformanceTracker.getInstanceForSensorId(getSensorId());
-
-        final ProtoOutputStream proto = new ProtoOutputStream(fd);
-        for (UserInfo user : UserManager.get(getContext()).getUsers()) {
-            final int userId = user.getUserHandle().getIdentifier();
-
-            final long userToken = proto.start(FingerprintServiceDumpProto.USERS);
-
-            proto.write(FingerprintUserStatsProto.USER_ID, userId);
-            proto.write(FingerprintUserStatsProto.NUM_FINGERPRINTS,
-                    getBiometricUtils().getBiometricsForUser(getContext(), userId).size());
-
-            // Normal fingerprint authentications (e.g. lockscreen)
-            long countsToken = proto.start(FingerprintUserStatsProto.NORMAL);
-            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptForUser(userId));
-            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectForUser(userId));
-            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireForUser(userId));
-            proto.write(PerformanceStatsProto.LOCKOUT, tracker.getTimedLockoutForUser(userId));
-            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT,
-                    tracker.getPermanentLockoutForUser(userId));
-            proto.end(countsToken);
-
-            // Statistics about secure fingerprint transactions (e.g. to unlock password
-            // storage, make secure purchases, etc.)
-            countsToken = proto.start(FingerprintUserStatsProto.CRYPTO);
-            proto.write(PerformanceStatsProto.ACCEPT, tracker.getAcceptCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.REJECT, tracker.getRejectCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.ACQUIRE, tracker.getAcquireCryptoForUser(userId));
-            proto.write(PerformanceStatsProto.LOCKOUT, 0); // meaningless for crypto
-            proto.write(PerformanceStatsProto.PERMANENT_LOCKOUT, 0); // meaningless for crypto
-            proto.end(countsToken);
-
-            proto.end(userToken);
-        }
-        proto.flush();
-        tracker.clear();
-    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java
new file mode 100644
index 0000000..e1082ae
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUpdateActiveUserClient.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.os.Build;
+import android.os.Environment;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SELinux;
+import android.util.Slog;
+
+import com.android.server.biometrics.sensors.ClientMonitor;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * Sets the HAL's current active user, and updates the framework's authenticatorId cache.
+ */
+public class FingerprintUpdateActiveUserClient extends ClientMonitor<IBiometricsFingerprint> {
+
+    private static final String TAG = "FingerprintUpdateActiveUserClient";
+    private static final String FP_DATA_DIR = "fpdata";
+
+    private final int mCurrentUserId;
+    private final boolean mHasEnrolledBiometrics;
+    private final Map<Integer, Long> mAuthenticatorIds;
+    private File mDirectory;
+
+    FingerprintUpdateActiveUserClient(@NonNull Context context,
+            @NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, int userId,
+            @NonNull String owner, int sensorId, int currentUserId, boolean hasEnrolledBiometrics,
+            @NonNull Map<Integer, Long> authenticatorIds) {
+        super(context, lazyDaemon, null /* token */, null /* listener */, userId, owner,
+                0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN,
+                BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN);
+        mCurrentUserId = currentUserId;
+        mHasEnrolledBiometrics = hasEnrolledBiometrics;
+        mAuthenticatorIds = authenticatorIds;
+    }
+
+    @Override
+    public void start(@NonNull FinishCallback finishCallback) {
+        super.start(finishCallback);
+
+        if (mCurrentUserId == getTargetUserId()) {
+            Slog.d(TAG, "Already user: " + mCurrentUserId + ", refreshing authenticatorId");
+            try {
+                mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics
+                        ? getFreshDaemon().getAuthenticatorId() : 0L);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Unable to refresh authenticatorId", e);
+            }
+            finishCallback.onClientFinished(this, true /* success */);
+            return;
+        }
+
+        int firstSdkInt = Build.VERSION.FIRST_SDK_INT;
+        if (firstSdkInt < Build.VERSION_CODES.BASE) {
+            Slog.e(TAG, "First SDK version " + firstSdkInt + " is invalid; must be " +
+                    "at least VERSION_CODES.BASE");
+        }
+        File baseDir;
+        if (firstSdkInt <= Build.VERSION_CODES.O_MR1) {
+            baseDir = Environment.getUserSystemDirectory(getTargetUserId());
+        } else {
+            baseDir = Environment.getDataVendorDeDirectory(getTargetUserId());
+        }
+
+        mDirectory = new File(baseDir, FP_DATA_DIR);
+        if (!mDirectory.exists()) {
+            if (!mDirectory.mkdir()) {
+                Slog.e(TAG, "Cannot make directory: " + mDirectory.getAbsolutePath());
+                finishCallback.onClientFinished(this, false /* success */);
+                return;
+            }
+            // Calling mkdir() from this process will create a directory with our
+            // permissions (inherited from the containing dir). This command fixes
+            // the label.
+            if (!SELinux.restorecon(mDirectory)) {
+                Slog.e(TAG, "Restorecons failed. Directory will have wrong label.");
+                finishCallback.onClientFinished(this, false /* success */);
+                return;
+            }
+        }
+
+        startHalOperation();
+    }
+
+    @Override
+    public void unableToStart() {
+        // Nothing to do here
+    }
+
+    @Override
+    protected void startHalOperation() {
+        try {
+            getFreshDaemon().setActiveGroup(getTargetUserId(), mDirectory.getAbsolutePath());
+            mAuthenticatorIds.put(getTargetUserId(), mHasEnrolledBiometrics
+                    ? getFreshDaemon().getAuthenticatorId() : 0L);
+            mFinishCallback.onClientFinished(this, true /* success */);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to setActiveGroup: " + e);
+            mFinishCallback.onClientFinished(this, false /* success */);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityDispatcher.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityDispatcher.java
new file mode 100644
index 0000000..7bda33d
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityDispatcher.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint;
+
+import android.hardware.fingerprint.IFingerprintClientActiveCallback;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Keeps track of sensor gesture availability (e.g. swipe), and notifies clients when its
+ * availability changes
+ */
+public class GestureAvailabilityDispatcher {
+    private static final String TAG = "GestureAvailabilityTracker";
+
+    private final CopyOnWriteArrayList<IFingerprintClientActiveCallback> mClientActiveCallbacks;
+    private final Map<Integer, Boolean> mActiveSensors;
+
+    private boolean mIsActive;
+
+    GestureAvailabilityDispatcher() {
+        mClientActiveCallbacks = new CopyOnWriteArrayList<>();
+        mActiveSensors = new HashMap<>();
+    }
+
+    /**
+     * @return true if any sensor is active.
+     */
+    public boolean isAnySensorActive() {
+        return mIsActive;
+    }
+
+    public void markSensorActive(int sensorId, boolean active) {
+        mActiveSensors.put(sensorId, active);
+
+        final boolean wasActive = mIsActive;
+        boolean isActive = false;
+        for (Boolean b : mActiveSensors.values()) {
+            if (b) {
+                isActive = true;
+                break;
+            }
+        }
+
+        if (wasActive != isActive) {
+            Slog.d(TAG, "Notifying gesture availability, active=" + mIsActive);
+            mIsActive = isActive;
+            notifyClientActiveCallbacks(mIsActive);
+        }
+    }
+
+    void registerCallback(IFingerprintClientActiveCallback callback) {
+        mClientActiveCallbacks.add(callback);
+    }
+
+    void removeCallback(IFingerprintClientActiveCallback callback) {
+        mClientActiveCallbacks.remove(callback);
+    }
+
+    private void notifyClientActiveCallbacks(boolean isActive) {
+        for (IFingerprintClientActiveCallback callback : mClientActiveCallbacks) {
+            try {
+                callback.onClientActiveChanged(isActive);
+            } catch (RemoteException re) {
+                // If the remote is dead, stop notifying it
+                mClientActiveCallbacks.remove(callback);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityTracker.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityTracker.java
deleted file mode 100644
index 6292ecf..0000000
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/GestureAvailabilityTracker.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors.fingerprint;
-
-import android.hardware.fingerprint.IFingerprintClientActiveCallback;
-import android.os.RemoteException;
-
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Keeps track of sensor gesture availability (e.g. swipe), and notifies clients when its
- * availability changes
- */
-class GestureAvailabilityTracker {
-    private final CopyOnWriteArrayList<IFingerprintClientActiveCallback> mClientActiveCallbacks =
-            new CopyOnWriteArrayList<>();
-
-    void registerCallback(IFingerprintClientActiveCallback callback) {
-        mClientActiveCallbacks.add(callback);
-    }
-
-    void removeCallback(IFingerprintClientActiveCallback callback) {
-        mClientActiveCallbacks.remove(callback);
-    }
-
-    void notifyClientActiveCallbacks(boolean isActive) {
-        for (IFingerprintClientActiveCallback callback : mClientActiveCallbacks) {
-            try {
-                callback.onClientActiveChanged(isActive);
-            } catch (RemoteException re) {
-                // If the remote is dead, stop notifying it
-                mClientActiveCallbacks.remove(callback);
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/Cancellable.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
similarity index 61%
copy from services/core/java/com/android/server/biometrics/sensors/Cancellable.java
copy to services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
index 68a3bc6..e0806ff 100644
--- a/services/core/java/com/android/server/biometrics/sensors/Cancellable.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/Udfps.java
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors;
+package com.android.server.biometrics.sensors.fingerprint;
 
 /**
- * Interface that cancellable {@link ClientMonitor} subclasses should implement.
+ * Interface for under-display fingerprint sensors.
+ * {@link com.android.server.biometrics.sensors.ClientMonitor} subclass that require knowledge of
+ * finger position (e.g. enroll, authenticate) should implement this.
  */
-public interface Cancellable {
-    /**
-     * Requests to end the ClientMonitor's lifecycle.
-     */
-    void cancel();
+public interface Udfps {
+    void onFingerDown(int x, int y, float minor, float major);
+    void onFingerUp();
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java
new file mode 100644
index 0000000..e6e1533
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/UdfpsHelper.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.sensors.fingerprint;
+
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.os.RemoteException;
+import android.util.Slog;
+
+/**
+ * Contains helper methods for under-display fingerprint HIDL.
+ */
+public class UdfpsHelper {
+
+    private static final String TAG = "UdfpsHelper";
+
+    static void onFingerDown(IBiometricsFingerprint daemon, int x, int y, float minor,
+            float major) {
+        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
+                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
+                        daemon);
+        if (extension == null) {
+            Slog.v(TAG, "onFingerDown | failed to cast the HIDL to V2_3");
+            return;
+        }
+
+        try {
+            extension.onFingerDown(x, y, minor, major);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "onFingerDown | RemoteException: ", e);
+        }
+    }
+
+    static void onFingerUp(IBiometricsFingerprint daemon) {
+        android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint extension =
+                android.hardware.biometrics.fingerprint.V2_3.IBiometricsFingerprint.castFrom(
+                        daemon);
+        if (extension == null) {
+            Slog.v(TAG, "onFingerUp | failed to cast the HIDL to V2_3");
+            return;
+        }
+
+        try {
+            extension.onFingerUp();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "onFingerUp | RemoteException: ", e);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
index 023ed46..bcf63dc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisService.java
@@ -18,17 +18,12 @@
 
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 
+import android.annotation.NonNull;
 import android.content.Context;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.hardware.biometrics.BiometricsProtoEnums;
 import android.hardware.iris.IIrisService;
 
-import com.android.server.biometrics.sensors.BiometricServiceBase;
-import com.android.server.biometrics.sensors.BiometricUtils;
-import com.android.server.biometrics.sensors.LockoutTracker;
-import com.android.server.biometrics.sensors.fingerprint.FingerprintService;
-
-import java.util.List;
+import com.android.server.SystemService;
+import com.android.server.biometrics.Utils;
 
 /**
  * A service to manage multiple clients that want to access the Iris HAL API.
@@ -36,11 +31,9 @@
  * iris-related events.
  *
  * TODO: The vendor is expected to fill in the service. See
- * {@link FingerprintService}
- *
- * @hide
+ * {@link com.android.server.biometrics.sensors.face.FaceService}
  */
-public class IrisService extends BiometricServiceBase {
+public class IrisService extends SystemService {
 
     private static final String TAG = "IrisService";
 
@@ -50,92 +43,16 @@
     private final class IrisServiceWrapper extends IIrisService.Stub {
         @Override // Binder call
         public void initializeConfiguration(int sensorId) {
-            checkPermission(USE_BIOMETRIC_INTERNAL);
-            initializeConfigurationInternal(sensorId);
+            Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
         }
     }
 
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public IrisService(Context context) {
+    public IrisService(@NonNull Context context) {
         super(context);
     }
 
     @Override
     public void onStart() {
-        super.onStart();
         publishBinderService(Context.IRIS_SERVICE, new IrisServiceWrapper());
     }
-
-    @Override
-    protected void doTemplateCleanupForUser(int userId) {
-
-    }
-
-    @Override
-    protected String getTag() {
-        return TAG;
-    }
-
-    @Override
-    protected Object getDaemon() {
-        return null;
-    }
-
-    @Override
-    protected BiometricUtils getBiometricUtils() {
-        return null;
-    }
-
-    @Override
-    protected boolean hasReachedEnrollmentLimit(int userId) {
-        return false;
-    }
-
-    @Override
-    protected void updateActiveGroup(int userId) {
-
-    }
-
-    @Override
-    protected boolean hasEnrolledBiometrics(int userId) {
-        return false;
-    }
-
-    @Override
-    protected String getManageBiometricPermission() {
-        return null;
-    }
-
-    @Override
-    protected void checkUseBiometricPermission() {
-
-    }
-
-    @Override
-    protected boolean checkAppOps(int uid, String opPackageName) {
-        return false;
-    }
-
-    @Override
-    protected List<? extends BiometricAuthenticator.Identifier> getEnrolledTemplates(int userId) {
-        return null;
-    }
-
-    @Override
-    protected int statsModality() {
-        return BiometricsProtoEnums.MODALITY_IRIS;
-    }
-
-    @Override
-    protected int getLockoutMode(int userId) {
-        return LockoutTracker.LOCKOUT_NONE;
-    }
 }
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index b279b37..ed3a223 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -400,7 +400,7 @@
                 final int intendingUid = getIntendingUid(callingPackage, userId);
                 final int intendingUserId = UserHandle.getUserId(intendingUid);
                 if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                        intendingUid, intendingUserId)
+                        intendingUid, intendingUserId, false)
                         || isDeviceLocked(intendingUserId)) {
                     return null;
                 }
@@ -416,7 +416,7 @@
                 final int intendingUid = getIntendingUid(callingPackage, userId);
                 final int intendingUserId = UserHandle.getUserId(intendingUid);
                 if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                        intendingUid, intendingUserId)
+                        intendingUid, intendingUserId, false)
                         || isDeviceLocked(intendingUserId)) {
                     return false;
                 }
@@ -450,7 +450,7 @@
                 final int intendingUid = getIntendingUid(callingPackage, userId);
                 final int intendingUserId = UserHandle.getUserId(intendingUid);
                 if (!clipboardAccessAllowed(AppOpsManager.OP_READ_CLIPBOARD, callingPackage,
-                        intendingUid, intendingUserId)
+                        intendingUid, intendingUserId, false)
                         || isDeviceLocked(intendingUserId)) {
                     return false;
                 }
@@ -740,14 +740,21 @@
 
     private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
             @UserIdInt int userId) {
-        // Check the AppOp.
-        if (mAppOps.noteOp(op, uid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            return false;
-        }
+        return clipboardAccessAllowed(op, callingPackage, uid, userId, true);
+    }
+
+    private boolean clipboardAccessAllowed(int op, String callingPackage, int uid,
+            @UserIdInt int userId, boolean shouldNoteOp) {
+
+        boolean allowed = false;
+
+        // First, verify package ownership to ensure use below is safe.
+        mAppOps.checkPackage(uid, callingPackage);
+
         // Shell can access the clipboard for testing purposes.
         if (mPm.checkPermission(android.Manifest.permission.READ_CLIPBOARD_IN_BACKGROUND,
                     callingPackage) == PackageManager.PERMISSION_GRANTED) {
-            return true;
+            allowed = true;
         }
         // The default IME is always allowed to access the clipboard.
         String defaultIme = Settings.Secure.getStringForUser(getContext().getContentResolver(),
@@ -755,7 +762,7 @@
         if (!TextUtils.isEmpty(defaultIme)) {
             final String imePkg = ComponentName.unflattenFromString(defaultIme).getPackageName();
             if (imePkg.equals(callingPackage)) {
-                return true;
+                allowed = true;
             }
         }
 
@@ -766,8 +773,10 @@
                 // at the same time. e.x. SystemUI. It needs to check the window focus of
                 // Binder.getCallingUid(). Without checking, the user X can't copy any thing from
                 // INTERNAL_SYSTEM_WINDOW to the other applications.
-                boolean allowed = mWm.isUidFocused(uid)
-                        || isInternalSysWindowAppWithWindowFocus(callingPackage);
+                if (!allowed) {
+                    allowed = mWm.isUidFocused(uid)
+                            || isInternalSysWindowAppWithWindowFocus(callingPackage);
+                }
                 if (!allowed && mContentCaptureInternal != null) {
                     // ...or the Content Capture Service
                     // The uid parameter of mContentCaptureInternal.isContentCaptureServiceForUser
@@ -786,17 +795,28 @@
                     // userId must pass intending userId. i.e. user#10.
                     allowed = mAutofillInternal.isAugmentedAutofillServiceForUser(uid, userId);
                 }
-                if (!allowed) {
-                    Slog.e(TAG, "Denying clipboard access to " + callingPackage
-                            + ", application is not in focus neither is a system service for "
-                            + "user " + userId);
-                }
-                return allowed;
+                break;
             case AppOpsManager.OP_WRITE_CLIPBOARD:
                 // Writing is allowed without focus.
-                return true;
+                allowed = true;
+                break;
             default:
                 throw new IllegalArgumentException("Unknown clipboard appop " + op);
         }
+        if (!allowed) {
+            Slog.e(TAG, "Denying clipboard access to " + callingPackage
+                    + ", application is not in focus nor is it a system service for "
+                    + "user " + userId);
+            return false;
+        }
+        // Finally, check the app op.
+        int appOpsResult;
+        if (shouldNoteOp) {
+            appOpsResult = mAppOps.noteOp(op, uid, callingPackage);
+        } else {
+            appOpsResult = mAppOps.checkOp(op, uid, callingPackage);
+        }
+
+        return appOpsResult == AppOpsManager.MODE_ALLOWED;
     }
 }
diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java
index 533392a..fd5f48c 100644
--- a/services/core/java/com/android/server/input/InputShellCommand.java
+++ b/services/core/java/com/android/server/input/InputShellCommand.java
@@ -199,7 +199,7 @@
                     + " (Default: touchscreen)");
             out.println("      press (Default: trackball)");
             out.println("      roll <dx> <dy> (Default: trackball)");
-            out.println("      motionevent <DOWN|UP|MOVE> <x> <y> (Default: touchscreen)");
+            out.println("      motionevent <DOWN|UP|MOVE|CANCEL> <x> <y> (Default: touchscreen)");
         }
     }
 
@@ -357,32 +357,50 @@
                 displayId);
     }
 
-    private void runMotionEvent(int inputSource, int displayId) {
-        inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
-        sendMotionEvent(inputSource, getNextArgRequired(), Float.parseFloat(getNextArgRequired()),
-                Float.parseFloat(getNextArgRequired()), displayId);
+    private int getAction() {
+        String actionString = getNextArgRequired();
+        switch (actionString.toUpperCase()) {
+            case "DOWN":
+                return MotionEvent.ACTION_DOWN;
+            case "UP":
+                return MotionEvent.ACTION_UP;
+            case "MOVE":
+                return MotionEvent.ACTION_MOVE;
+            case "CANCEL":
+                return MotionEvent.ACTION_CANCEL;
+            default:
+                throw new IllegalArgumentException("Unknown action: " + actionString);
+        }
     }
 
-    private void sendMotionEvent(int inputSource, String motionEventType, float x, float y,
-            int displayId) {
-        final int action;
-        final float pressure;
+    private void runMotionEvent(int inputSource, int displayId) {
+        inputSource = getSource(inputSource, InputDevice.SOURCE_TOUCHSCREEN);
+        int action = getAction();
+        float x = 0, y = 0;
+        if (action == MotionEvent.ACTION_DOWN
+                || action == MotionEvent.ACTION_MOVE
+                || action == MotionEvent.ACTION_UP) {
+            x = Float.parseFloat(getNextArgRequired());
+            y = Float.parseFloat(getNextArgRequired());
+        } else {
+            // For ACTION_CANCEL, the positions are optional
+            String xString = getNextArg();
+            String yString = getNextArg();
+            if (xString != null && yString != null) {
+                x = Float.parseFloat(xString);
+                y = Float.parseFloat(yString);
+            }
+        }
 
-        switch (motionEventType.toUpperCase()) {
-            case "DOWN":
-                action = MotionEvent.ACTION_DOWN;
-                pressure = DEFAULT_PRESSURE;
-                break;
-            case "UP":
-                action = MotionEvent.ACTION_UP;
-                pressure = NO_PRESSURE;
-                break;
-            case "MOVE":
-                action = MotionEvent.ACTION_MOVE;
-                pressure = DEFAULT_PRESSURE;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown motionevent " + motionEventType);
+        sendMotionEvent(inputSource, action, x, y, displayId);
+    }
+
+    private void sendMotionEvent(int inputSource, int action, float x, float y,
+            int displayId) {
+        float pressure = NO_PRESSURE;
+
+        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
+            pressure = DEFAULT_PRESSURE;
         }
 
         final long now = SystemClock.uptimeMillis();
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d8ee32e..0154fe0 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -18,8 +18,6 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.internal.inputmethod.StartInputReason.WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR;
-
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.Manifest;
@@ -719,11 +717,6 @@
      */
     int mImeWindowVis;
 
-    /**
-     * Checks if the client needs to start input.
-     */
-    private boolean mCurClientNeedStartInput = false;
-
     private AlertDialog.Builder mDialogBuilder;
     private AlertDialog mSwitchingDialog;
     private IBinder mSwitchingDialogToken = new Binder();
@@ -3467,20 +3460,14 @@
         if (mCurFocusedWindow == windowToken) {
             if (DEBUG) {
                 Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client
-                        + " attribute=" + attribute + ", token = " + windowToken);
+                        + " attribute=" + attribute + ", token = " + windowToken
+                        + ", startInputReason="
+                        + InputMethodDebug.startInputReasonToString(startInputReason));
             }
-            // Needs to start input when the same window focus gain but not with the same editor,
-            // or when the current client needs to start input (e.g. when focusing the same
-            // window after device turned screen on).
-            if (attribute != null && (startInputReason != WINDOW_FOCUS_GAIN_REPORT_WITH_SAME_EDITOR
-                    || mCurClientNeedStartInput)) {
-                if (mIsInteractive) {
-                    mCurClientNeedStartInput = false;
-                }
+            if (attribute != null) {
                 return startInputUncheckedLocked(cs, inputContext, missingMethods,
                         attribute, startInputFlags, startInputReason);
             }
-
             return new InputBindResult(
                     InputBindResult.ResultCode.SUCCESS_REPORT_WINDOW_FOCUS_ONLY,
                     null, null, null, -1, null);
@@ -4459,9 +4446,6 @@
     private void handleSetInteractive(final boolean interactive) {
         synchronized (mMethodMap) {
             mIsInteractive = interactive;
-            if (!interactive) {
-                mCurClientNeedStartInput = true;
-            }
             updateSystemUiLocked(interactive ? mImeWindowVis : 0, mBackDisposition);
 
             // Inform the current client of the change in active status
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 8843e52..2bcee2f 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -22,6 +22,7 @@
 import android.content.Context;
 import android.location.Location;
 import android.location.util.identity.CallerIdentity;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -128,27 +129,38 @@
         mServiceWatcher.dump(fd, pw, args);
     }
 
+    private static String guessPackageName(Context context, int uid) {
+        String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
+        if (packageNames == null || packageNames.length == 0) {
+            // illegal state exception will propagate back through binders
+            throw new IllegalStateException(
+                    "location provider from uid " + uid + " has no package information");
+        } else {
+            return packageNames[0];
+        }
+    }
+
     private class Proxy extends ILocationProviderManager.Stub {
 
         Proxy() {}
 
         // executed on binder thread
         @Override
-        public void onSetAttributionTag(String attributionTag) {
+        public void onSetIdentity(@Nullable String packageName, @Nullable String attributionTag) {
             synchronized (mLock) {
                 if (mProxy != this) {
                     return;
                 }
 
-                String packageName = mServiceWatcher.getBoundService().getPackageName();
+                CallerIdentity identity;
                 if (packageName == null) {
-                    return;
+                    packageName = guessPackageName(mContext, Binder.getCallingUid());
+                    // unsafe is ok since the package is coming direct from the package manager here
+                    identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag);
+                } else {
+                    identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag);
                 }
 
-                // we don't need to verify the package name because we're getting it straight from
-                // the service watcher
-                CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName,
-                        attributionTag);
                 setIdentity(identity);
             }
         }
@@ -163,12 +175,9 @@
 
                 // if no identity is set yet, set it now
                 if (getIdentity() == null) {
-                    String packageName = mServiceWatcher.getBoundService().getPackageName();
-                    if (packageName != null) {
-                        // we don't need to verify the package name because we're getting it
-                        // straight from the service watcher
-                        setIdentity(CallerIdentity.fromBinderUnsafe(packageName, null));
-                    }
+                    String packageName = guessPackageName(mContext, Binder.getCallingUid());
+                    // unsafe is ok since the package is coming direct from the package manager here
+                    setIdentity(CallerIdentity.fromBinderUnsafe(packageName, null));
                 }
 
                 setProperties(properties);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 9a83242..0eba69e 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -16,7 +16,8 @@
 
 package com.android.server.media;
 
-import static android.os.UserHandle.USER_ALL;
+import static android.os.UserHandle.ALL;
+import static android.os.UserHandle.CURRENT;
 
 import static com.android.server.media.MediaKeyDispatcher.KEY_EVENT_LONG_PRESS;
 import static com.android.server.media.MediaKeyDispatcher.isDoubleTapOverridden;
@@ -251,7 +252,7 @@
 
     private List<MediaSessionRecord> getActiveSessionsLocked(int userId) {
         List<MediaSessionRecord> records = new ArrayList<>();
-        if (userId == USER_ALL) {
+        if (userId == ALL.getIdentifier()) {
             int size = mUserRecords.size();
             for (int i = 0; i < size; i++) {
                 records.addAll(mUserRecords.valueAt(i).mPriorityStack.getActiveSessions(userId));
@@ -267,7 +268,8 @@
 
         // Return global priority session at the first whenever it's asked.
         if (isGlobalPriorityActiveLocked()
-                && (userId == USER_ALL || userId == mGlobalPrioritySession.getUserId())) {
+                && (userId == ALL.getIdentifier()
+                        || userId == mGlobalPrioritySession.getUserId())) {
             records.add(0, mGlobalPrioritySession);
         }
         return records;
@@ -275,7 +277,7 @@
 
     List<Session2Token> getSession2TokensLocked(int userId) {
         List<Session2Token> list = new ArrayList<>();
-        if (userId == USER_ALL) {
+        if (userId == ALL.getIdentifier()) {
             int size = mUserRecords.size();
             for (int i = 0; i < size; i++) {
                 list.addAll(mUserRecords.valueAt(i).mPriorityStack.getSession2Tokens(userId));
@@ -351,7 +353,7 @@
             FullUserRecord user = getFullUserRecordLocked(userId);
             if (user != null) {
                 if (user.mFullUserId == userId) {
-                    user.destroySessionsForUserLocked(USER_ALL);
+                    user.destroySessionsForUserLocked(ALL.getIdentifier());
                     mUserRecords.remove(userId);
                 } else {
                     user.destroySessionsForUserLocked(userId);
@@ -653,7 +655,7 @@
             pushRemoteVolumeUpdateLocked(userId);
             for (int i = mSessionsListeners.size() - 1; i >= 0; i--) {
                 SessionsListenerRecord record = mSessionsListeners.get(i);
-                if (record.userId == USER_ALL || record.userId == userId) {
+                if (record.userId == ALL.getIdentifier() || record.userId == userId) {
                     try {
                         record.listener.onActiveSessionsChanged(tokens);
                     } catch (RemoteException e) {
@@ -668,13 +670,13 @@
 
     void pushSession2Changed(int userId) {
         synchronized (mLock) {
-            List<Session2Token> allSession2Tokens = getSession2TokensLocked(USER_ALL);
+            List<Session2Token> allSession2Tokens = getSession2TokensLocked(ALL.getIdentifier());
             List<Session2Token> session2Tokens = getSession2TokensLocked(userId);
 
             for (int i = mSession2TokensListenerRecords.size() - 1; i >= 0; i--) {
                 Session2TokensListenerRecord listenerRecord = mSession2TokensListenerRecords.get(i);
                 try {
-                    if (listenerRecord.userId == USER_ALL) {
+                    if (listenerRecord.userId == ALL.getIdentifier()) {
                         listenerRecord.listener.onSession2TokensChanged(allSession2Tokens);
                     } else if (listenerRecord.userId == userId) {
                         listenerRecord.listener.onSession2TokensChanged(session2Tokens);
@@ -760,7 +762,8 @@
     }
 
     private MediaSessionRecord getMediaSessionRecordLocked(MediaSession.Token sessionToken) {
-        FullUserRecord user = getFullUserRecordLocked(UserHandle.getUserId(sessionToken.getUid()));
+        FullUserRecord user = getFullUserRecordLocked(
+                UserHandle.getUserHandleForUid(sessionToken.getUid()).getIdentifier());
         if (user != null) {
             return user.mPriorityStack.getMediaSessionRecord(sessionToken);
         }
@@ -1089,7 +1092,7 @@
 
         private void observe() {
             mContentResolver.registerContentObserver(mSecureSettingsUri,
-                    false, this, USER_ALL);
+                    false, this, ALL.getIdentifier());
         }
 
         @Override
@@ -1435,7 +1438,7 @@
                 final IOnMediaKeyEventDispatchedListener listener) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
             final long token = Binder.clearCallingIdentity();
             try {
                 if (!hasMediaControlPermission(pid, uid)) {
@@ -1463,7 +1466,7 @@
                 final IOnMediaKeyEventDispatchedListener listener) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
             final long token = Binder.clearCallingIdentity();
             try {
                 if (!hasMediaControlPermission(pid, uid)) {
@@ -1491,7 +1494,7 @@
                 final IOnMediaKeyEventSessionChangedListener listener) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
             final long token = Binder.clearCallingIdentity();
             try {
                 if (!hasMediaControlPermission(pid, uid)) {
@@ -1519,7 +1522,7 @@
                 final IOnMediaKeyEventSessionChangedListener listener) {
             final int pid = Binder.getCallingPid();
             final int uid = Binder.getCallingUid();
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
             final long token = Binder.clearCallingIdentity();
             try {
                 if (!hasMediaControlPermission(pid, uid)) {
@@ -1557,7 +1560,7 @@
                 }
 
                 synchronized (mLock) {
-                    int userId = UserHandle.getUserId(uid);
+                    int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
                     FullUserRecord user = getFullUserRecordLocked(userId);
                     if (user == null || user.mFullUserId != userId) {
                         Log.w(TAG, "Only the full user can set the volume key long-press listener"
@@ -1616,7 +1619,7 @@
                 }
 
                 synchronized (mLock) {
-                    int userId = UserHandle.getUserId(uid);
+                    int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
                     FullUserRecord user = getFullUserRecordLocked(userId);
                     if (user == null || user.mFullUserId != userId) {
                         Log.w(TAG, "Only the full user can set the media key listener"
@@ -1742,10 +1745,7 @@
             }
             if (down || up) {
                 int flags = AudioManager.FLAG_FROM_KEY;
-                if (musicOnly) {
-                    // This flag is used when the screen is off to only affect active media.
-                    flags |= AudioManager.FLAG_ACTIVE_MEDIA_ONLY;
-                } else {
+                if (!musicOnly) {
                     // These flags are consistent with the home screen
                     if (up) {
                         flags |= AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE;
@@ -1759,11 +1759,12 @@
                         direction = 0;
                     }
                     dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid,
-                            asSystemService, stream, direction, flags);
+                            asSystemService, stream, direction, flags, musicOnly);
                 } else if (isMute) {
                     if (down && keyEvent.getRepeatCount() == 0) {
                         dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid,
-                                asSystemService, stream, AudioManager.ADJUST_TOGGLE_MUTE, flags);
+                                asSystemService, stream, AudioManager.ADJUST_TOGGLE_MUTE, flags,
+                                musicOnly);
                     }
                 }
             }
@@ -1846,7 +1847,7 @@
             try {
                 synchronized (mLock) {
                     dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid, false,
-                            suggestedStream, delta, flags);
+                            suggestedStream, delta, flags, false);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -1924,7 +1925,7 @@
         public boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid)
                 throws RemoteException {
             final int uid = Binder.getCallingUid();
-            final int userId = UserHandle.getUserId(uid);
+            final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
             final long token = Binder.clearCallingIdentity();
             try {
                 // Don't perform sanity check between controllerPackageName and controllerUid.
@@ -2003,7 +2004,7 @@
         private boolean hasEnabledNotificationListener(int resolvedUserId, String packageName)
                 throws RemoteException {
             // You may not access another user's content as an enabled listener.
-            final int userId = UserHandle.getUserId(resolvedUserId);
+            final int userId = UserHandle.getUserHandleForUid(resolvedUserId).getIdentifier();
             if (resolvedUserId != userId) {
                 return false;
             }
@@ -2028,7 +2029,8 @@
         }
 
         private void dispatchAdjustVolumeLocked(String packageName, String opPackageName, int pid,
-                int uid, boolean asSystemService, int suggestedStream, int direction, int flags) {
+                int uid, boolean asSystemService, int suggestedStream, int direction, int flags,
+                boolean musicOnly) {
             MediaSessionRecordImpl session = isGlobalPriorityActiveLocked() ? mGlobalPrioritySession
                     : mCurrentFullUserRecord.mPriorityStack.getDefaultVolumeSession();
 
@@ -2043,8 +2045,7 @@
                             + ". flags=" + flags + ", preferSuggestedStream="
                             + preferSuggestedStream + ", session=" + session);
                 }
-                if ((flags & AudioManager.FLAG_ACTIVE_MEDIA_ONLY) != 0
-                        && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
+                if (musicOnly && !AudioSystem.isStreamActive(AudioManager.STREAM_MUSIC, 0)) {
                     if (DEBUG_KEY_EVENT) {
                         Log.d(TAG, "Nothing is playing on the music stream. Skipping volume event,"
                                 + " flags=" + flags);
@@ -2220,7 +2221,7 @@
 
         private boolean isUserSetupComplete() {
             return Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+                    Settings.Secure.USER_SETUP_COMPLETE, 0, CURRENT.getIdentifier()) != 0;
         }
 
         // we only handle public stream types, which are 0-5
diff --git a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
index 5c45e67..db553ee 100644
--- a/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ b/services/core/java/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.os.Looper;
 import android.telephony.Annotation;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -197,19 +196,7 @@
 
         @Override
         public void onServiceStateChanged(@NonNull ServiceState ss) {
-            // In 5G SA (Stand Alone) mode, the primary cell itself will be 5G hence telephony
-            // would report RAT = 5G_NR.
-            // However, in 5G NSA (Non Stand Alone) mode, the primary cell is still LTE and
-            // network allocates a secondary 5G cell so telephony reports RAT = LTE along with
-            // NR state as connected. In such case, attributes the data usage to NR.
-            // See b/160727498.
-            final boolean is5GNsa = (ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE
-                    || ss.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA)
-                    && ss.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED;
-
-            final int networkType =
-                    (is5GNsa ? TelephonyManager.NETWORK_TYPE_NR : ss.getDataNetworkType());
-
+            final int networkType = ss.getDataNetworkType();
             final int collapsedRatType = getCollapsedRatType(networkType);
             if (collapsedRatType == mLastCollapsedRatType) return;
 
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e2be193..88964e0 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4674,10 +4674,11 @@
         @Override
         public void setNotificationPolicy(String pkg, Policy policy) {
             enforcePolicyAccess(pkg, "setNotificationPolicy");
+            int callingUid = Binder.getCallingUid();
             final long identity = Binder.clearCallingIdentity();
             try {
                 final ApplicationInfo applicationInfo = mPackageManager.getApplicationInfo(pkg,
-                        0, UserHandle.getUserId(MY_UID));
+                        0, UserHandle.getUserId(callingUid));
                 Policy currPolicy = mZenModeHelper.getNotificationPolicy();
 
                 if (applicationInfo.targetSdkVersion < Build.VERSION_CODES.P) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index dd6a83b..9cf9545 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -75,6 +75,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -172,6 +173,8 @@
 
     private boolean mAllowInvalidShortcuts = false;
 
+    private Map<String, List<String>> mOemLockedApps = new HashMap();
+
     public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
             ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
             AppOpsManager appOpsManager,
@@ -314,6 +317,12 @@
                                         }
                                         channel.setImportanceLockedByCriticalDeviceFunction(
                                                 r.defaultAppLockedImportance);
+                                        channel.setImportanceLockedByOEM(r.oemLockedImportance);
+                                        if (!channel.isImportanceLockedByOEM()) {
+                                            if (r.oemLockedChannels.contains(channel.getId())) {
+                                                channel.setImportanceLockedByOEM(true);
+                                            }
+                                        }
                                         boolean isInvalidShortcutChannel =
                                                 channel.getConversationId() != null &&
                                                         channel.getConversationId().contains(
@@ -396,6 +405,14 @@
             r.visibility = visibility;
             r.showBadge = showBadge;
             r.bubblePreference = bubblePreference;
+            if (mOemLockedApps.containsKey(r.pkg)) {
+                List<String> channels = mOemLockedApps.get(r.pkg);
+                if (channels == null || channels.isEmpty()) {
+                    r.oemLockedImportance = true;
+                } else {
+                    r.oemLockedChannels = channels;
+                }
+            }
 
             try {
                 createDefaultChannelIfNeededLocked(r);
@@ -1149,8 +1166,10 @@
                     String channelId = appSplit.length == 2 ? appSplit[1] : null;
 
                     synchronized (mPackagePreferences) {
+                        boolean foundApp = false;
                         for (PackagePreferences r : mPackagePreferences.values()) {
                             if (r.pkg.equals(appName)) {
+                                foundApp = true;
                                 if (channelId == null) {
                                     // lock all channels for the app
                                     r.oemLockedImportance = true;
@@ -1168,6 +1187,14 @@
                                 }
                             }
                         }
+                        if (!foundApp) {
+                            List<String> channels =
+                                    mOemLockedApps.getOrDefault(appName, new ArrayList<>());
+                            if (channelId != null) {
+                                channels.add(channelId);
+                            }
+                            mOemLockedApps.put(appName, channels);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index ca16d57..a864aa6 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -403,6 +403,7 @@
     @GuardedBy("mLock")
     private boolean mVerityFound;
 
+    @GuardedBy("mLock")
     private boolean mDataLoaderFinished = false;
 
     @GuardedBy("mLock")
@@ -1118,7 +1119,7 @@
         if (hasParentSessionId()) {
             throw new IllegalStateException(
                     "Session " + sessionId + " is a child of multi-package session "
-                            + mParentSessionId +  " and may not be committed directly.");
+                            + getParentSessionId() +  " and may not be committed directly.");
         }
 
         if (!markAsSealed(statusReceiver, forTransfer)) {
@@ -1589,12 +1590,12 @@
     }
 
     private void onStorageUnhealthy() {
-        if (TextUtils.isEmpty(mPackageName)) {
+        final String packageName = getPackageName();
+        if (TextUtils.isEmpty(packageName)) {
             // The package has not been installed.
             return;
         }
         final PackageManagerService packageManagerService = mPm;
-        final String packageName = mPackageName;
         mHandler.post(() -> {
             if (packageManagerService.deletePackageX(packageName,
                     PackageManager.VERSION_CODE_HIGHEST, UserHandle.USER_SYSTEM,
@@ -1686,7 +1687,11 @@
     }
 
     private void handleInstall() {
-        if (isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked()) {
+        final boolean needsLogging;
+        synchronized (mLock) {
+            needsLogging = isInstallerDeviceOwnerOrAffiliatedProfileOwnerLocked();
+        }
+        if (needsLogging) {
             DevicePolicyEventLogger
                     .createEvent(DevicePolicyEnums.INSTALL_PACKAGE)
                     .setAdmin(mInstallSource.installerPackageName)
@@ -1929,19 +1934,20 @@
         // Skip logging the side-loaded app installations, as those are private and aren't reported
         // anywhere; app stores already have a record of the installation and that's why reporting
         // it here is fine
+        final String packageName = getPackageName();
         final String packageNameToLog =
-                (params.installFlags & PackageManager.INSTALL_FROM_ADB) == 0 ? mPackageName : "";
+                (params.installFlags & PackageManager.INSTALL_FROM_ADB) == 0 ? packageName : "";
         final long currentTimestamp = System.currentTimeMillis();
         FrameworkStatsLog.write(FrameworkStatsLog.PACKAGE_INSTALLER_V2_REPORTED,
                 isIncrementalInstallation(),
                 packageNameToLog,
                 currentTimestamp - createdMillis,
                 returnCode,
-                getApksSize());
+                getApksSize(packageName));
     }
 
-    private long getApksSize() {
-        final PackageSetting ps = mPm.getPackageSetting(mPackageName);
+    private long getApksSize(String packageName) {
+        final PackageSetting ps = mPm.getPackageSetting(packageName);
         if (ps == null) {
             return 0;
         }
@@ -2577,7 +2583,7 @@
     }
 
     void setPermissionsResult(boolean accepted) {
-        if (!mSealed) {
+        if (!isSealed()) {
             throw new SecurityException("Must be sealed to accept permissions");
         }
 
@@ -2653,7 +2659,7 @@
         if (hasParentSessionId()) {
             throw new IllegalStateException(
                     "Session " + sessionId + " is a child of multi-package session "
-                            + mParentSessionId +  " and may not be abandoned directly.");
+                            + getParentSessionId() +  " and may not be abandoned directly.");
         }
 
         List<PackageInstallerSession> childSessions = getChildSessionsNotLocked();
@@ -2823,7 +2829,11 @@
                         return;
                 }
 
-                if (mDestroyed || mDataLoaderFinished) {
+                final boolean isDestroyedOrDataLoaderFinished;
+                synchronized (mLock) {
+                    isDestroyedOrDataLoaderFinished = mDestroyed || mDataLoaderFinished;
+                }
+                if (isDestroyedOrDataLoaderFinished) {
                     switch (status) {
                         case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
                             onStorageUnhealthy();
@@ -2835,7 +2845,9 @@
                 try {
                     IDataLoader dataLoader = dataLoaderManager.getDataLoader(dataLoaderId);
                     if (dataLoader == null) {
-                        mDataLoaderFinished = true;
+                        synchronized (mLock) {
+                            mDataLoaderFinished = true;
+                        }
                         dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                 "Failure to obtain data loader");
                         return;
@@ -2868,10 +2880,12 @@
                             break;
                         }
                         case IDataLoaderStatusListener.DATA_LOADER_IMAGE_READY: {
-                            mDataLoaderFinished = true;
+                            synchronized (mLock) {
+                                mDataLoaderFinished = true;
+                            }
                             if (hasParentSessionId()) {
                                 mSessionProvider.getSession(
-                                        mParentSessionId).dispatchStreamValidateAndCommit();
+                                        getParentSessionId()).dispatchStreamValidateAndCommit();
                             } else {
                                 dispatchStreamValidateAndCommit();
                             }
@@ -2881,7 +2895,9 @@
                             break;
                         }
                         case IDataLoaderStatusListener.DATA_LOADER_IMAGE_NOT_READY: {
-                            mDataLoaderFinished = true;
+                            synchronized (mLock) {
+                                mDataLoaderFinished = true;
+                            }
                             dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                     "Failed to prepare image.");
                             if (manualStartAndDestroy) {
@@ -2895,7 +2911,9 @@
                             break;
                         }
                         case IDataLoaderStatusListener.DATA_LOADER_UNRECOVERABLE:
-                            mDataLoaderFinished = true;
+                            synchronized (mLock) {
+                                mDataLoaderFinished = true;
+                            }
                             dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                     "DataLoader reported unrecoverable failure.");
                             break;
@@ -2919,7 +2937,11 @@
             final IStorageHealthListener healthListener = new IStorageHealthListener.Stub() {
                 @Override
                 public void onHealthStatus(int storageId, int status) {
-                    if (mDestroyed || mDataLoaderFinished) {
+                    final boolean isDestroyedOrDataLoaderFinished;
+                    synchronized (mLock) {
+                        isDestroyedOrDataLoaderFinished = mDestroyed || mDataLoaderFinished;
+                    }
+                    if (isDestroyedOrDataLoaderFinished) {
                         // App's installed.
                         switch (status) {
                             case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY:
@@ -2941,7 +2963,9 @@
                             // fallthrough
                         case IStorageHealthListener.HEALTH_STATUS_UNHEALTHY:
                             // Even ADB installation can't wait for missing pages for too long.
-                            mDataLoaderFinished = true;
+                            synchronized (mLock) {
+                                mDataLoaderFinished = true;
+                            }
                             dispatchSessionVerificationFailure(INSTALL_FAILED_MEDIA_UNAVAILABLE,
                                     "Image is missing pages required for installation.");
                             break;
@@ -2984,13 +3008,17 @@
         return EMPTY_CHILD_SESSION_ARRAY;
     }
 
+    private boolean canBeAddedAsChild(int parentCandidate) {
+        synchronized (mLock) {
+            return (!hasParentSessionId() || mParentSessionId == parentCandidate)
+                    && !mCommitted && !mDestroyed;
+        }
+    }
+
     @Override
     public void addChildSessionId(int childSessionId) {
         final PackageInstallerSession childSession = mSessionProvider.getSession(childSessionId);
-        if (childSession == null
-                || (childSession.hasParentSessionId() && childSession.mParentSessionId != sessionId)
-                || childSession.mCommitted
-                || childSession.mDestroyed) {
+        if (childSession == null || !childSession.canBeAddedAsChild(sessionId)) {
             throw new IllegalStateException("Unable to add child session " + childSessionId
                             + " as it does not exist or is in an invalid state.");
         }
@@ -3039,12 +3067,16 @@
     }
 
     boolean hasParentSessionId() {
-        return mParentSessionId != SessionInfo.INVALID_ID;
+        synchronized (mLock) {
+            return mParentSessionId != SessionInfo.INVALID_ID;
+        }
     }
 
     @Override
     public int getParentSessionId() {
-        return mParentSessionId;
+        synchronized (mLock) {
+            return mParentSessionId;
+        }
     }
 
     private void dispatchSessionFinished(int returnCode, String msg, Bundle extras) {
@@ -3134,27 +3166,37 @@
 
     /** {@hide} */
     boolean isStagedSessionReady() {
-        return mStagedSessionReady;
+        synchronized (mLock) {
+            return mStagedSessionReady;
+        }
     }
 
     /** {@hide} */
     boolean isStagedSessionApplied() {
-        return mStagedSessionApplied;
+        synchronized (mLock) {
+            return mStagedSessionApplied;
+        }
     }
 
     /** {@hide} */
     boolean isStagedSessionFailed() {
-        return mStagedSessionFailed;
+        synchronized (mLock) {
+            return mStagedSessionFailed;
+        }
     }
 
     /** {@hide} */
     @StagedSessionErrorCode int getStagedSessionErrorCode() {
-        return mStagedSessionErrorCode;
+        synchronized (mLock) {
+            return mStagedSessionErrorCode;
+        }
     }
 
     /** {@hide} */
     String getStagedSessionErrorMessage() {
-        return mStagedSessionErrorMessage;
+        synchronized (mLock) {
+            return mStagedSessionErrorMessage;
+        }
     }
 
     private void destroyInternal() {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index fd73d68..668f375 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1376,7 +1376,7 @@
         long timeoutMs = -1;
         while ((opt = getNextOption()) != null) {
             switch (opt) {
-                case "--wait":
+                case "--wait-for-staged-ready":
                     waitForStagedSessionReady = true;
                     // If there is only one remaining argument, then it represents the sessionId, we
                     // shouldn't try to parse it as timeoutMs.
@@ -2864,7 +2864,7 @@
                     }
                     sessionParams.installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
                     break;
-                case "--wait":
+                case "--wait-for-staged-ready":
                     params.mWaitForStagedSessionReady = true;
                     try {
                         params.timeoutMs = Long.parseLong(peekNextArg());
@@ -3597,7 +3597,7 @@
         pw.println("       [--preload] [--instant] [--full] [--dont-kill]");
         pw.println("       [--enable-rollback]");
         pw.println("       [--force-uuid internal|UUID] [--pkg PACKAGE] [-S BYTES]");
-        pw.println("       [--apex] [--wait TIMEOUT]");
+        pw.println("       [--apex] [--wait-for-staged-ready TIMEOUT]");
         pw.println("       [PATH [SPLIT...]|-]");
         pw.println("    Install an application.  Must provide the apk data to install, either as");
         pw.println("    file path(s) or '-' to read from stdin.  Options are:");
@@ -3625,8 +3625,8 @@
         pw.println("          3=device setup, 4=user request");
         pw.println("      --force-uuid: force install on to disk volume with given UUID");
         pw.println("      --apex: install an .apex file, not an .apk");
-        pw.println("      --wait: when performing staged install, wait TIMEOUT milliseconds");
-        pw.println("          for pre-reboot verification to complete. If TIMEOUT is not");
+        pw.println("      --wait-for-staged-ready: when performing staged install, wait TIMEOUT");
+        pw.println("          ms for pre-reboot verification to complete. If TIMEOUT is not");
         pw.println("          specified it will wait for " + DEFAULT_WAIT_MS + " milliseconds.");
         pw.println("");
         pw.println("  install-existing [--user USER_ID|all|current]");
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 018a1da..710185d 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -395,6 +395,14 @@
             return false;
         }
 
+        /**
+         * Returns true if the window has a letterbox and any part of that letterbox overlaps with
+         * the given {@code rect}.
+         */
+        default boolean isLetterboxedOverlappingWith(Rect rect) {
+            return false;
+        }
+
         /** @return the current windowing mode of this window. */
         int getWindowingMode();
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4c4680b..7b06759 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -44,8 +44,8 @@
 import android.hardware.display.AmbientDisplayConfiguration;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
-import android.hardware.power.Boost;
 import android.hardware.power.Mode;
+import android.hardware.power.V1_0.PowerHint;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.BatteryManagerInternal;
@@ -203,6 +203,9 @@
     // How long a partial wake lock must be held until we consider it a long wake lock.
     static final long MIN_LONG_WAKE_CHECK_INTERVAL = 60*1000;
 
+    // Power features defined in hardware/libhardware/include/hardware/power.h.
+    private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1;
+
     // Default setting for double tap to wake.
     private static final int DEFAULT_DOUBLE_TAP_TO_WAKE = 0;
 
@@ -322,7 +325,7 @@
     private long mLastUserActivityTime;
     private long mLastUserActivityTimeNoChangeLights;
 
-    // Timestamp of last time power boost interaction was sent.
+    // Timestamp of last interactive power hint.
     private long mLastInteractivePowerHintTime;
 
     // Timestamp of the last screen brightness boost.
@@ -716,11 +719,21 @@
             PowerManagerService.nativeReleaseSuspendBlocker(name);
         }
 
+        /** Wrapper for PowerManager.nativeSetInteractive */
+        public void nativeSetInteractive(boolean enable) {
+            PowerManagerService.nativeSetInteractive(enable);
+        }
+
         /** Wrapper for PowerManager.nativeSetAutoSuspend */
         public void nativeSetAutoSuspend(boolean enable) {
             PowerManagerService.nativeSetAutoSuspend(enable);
         }
 
+        /** Wrapper for PowerManager.nativeSendPowerHint */
+        public void nativeSendPowerHint(int hintId, int data) {
+            PowerManagerService.nativeSendPowerHint(hintId, data);
+        }
+
         /** Wrapper for PowerManager.nativeSetPowerBoost */
         public void nativeSetPowerBoost(int boost, int durationMs) {
             PowerManagerService.nativeSetPowerBoost(boost, durationMs);
@@ -731,6 +744,11 @@
             return PowerManagerService.nativeSetPowerMode(mode, enabled);
         }
 
+        /** Wrapper for PowerManager.nativeSetFeature */
+        public void nativeSetFeature(int featureId, int data) {
+            PowerManagerService.nativeSetFeature(featureId, data);
+        }
+
         /** Wrapper for PowerManager.nativeForceSuspend */
         public boolean nativeForceSuspend() {
             return PowerManagerService.nativeForceSuspend();
@@ -833,9 +851,12 @@
     private native void nativeInit();
     private static native void nativeAcquireSuspendBlocker(String name);
     private static native void nativeReleaseSuspendBlocker(String name);
+    private static native void nativeSetInteractive(boolean enable);
     private static native void nativeSetAutoSuspend(boolean enable);
+    private static native void nativeSendPowerHint(int hintId, int data);
     private static native void nativeSetPowerBoost(int boost, int durationMs);
     private static native boolean nativeSetPowerMode(int mode, boolean enabled);
+    private static native void nativeSetFeature(int featureId, int data);
     private static native boolean nativeForceSuspend();
 
     public PowerManagerService(Context context) {
@@ -979,8 +1000,8 @@
 
             mNativeWrapper.nativeInit(this);
             mNativeWrapper.nativeSetAutoSuspend(false);
-            mNativeWrapper.nativeSetPowerMode(Mode.INTERACTIVE, true);
-            mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, false);
+            mNativeWrapper.nativeSetInteractive(true);
+            mNativeWrapper.nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
             mInjector.invalidateIsInteractiveCaches();
         }
     }
@@ -1231,7 +1252,8 @@
                             UserHandle.USER_CURRENT) != 0;
             if (doubleTapWakeEnabled != mDoubleTapWakeEnabled) {
                 mDoubleTapWakeEnabled = doubleTapWakeEnabled;
-                mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled);
+                mNativeWrapper.nativeSetFeature(
+                        POWER_FEATURE_DOUBLE_TAP_TO_WAKE, mDoubleTapWakeEnabled ? 1 : 0);
             }
         }
 
@@ -1590,7 +1612,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
         try {
             if (eventTime > mLastInteractivePowerHintTime) {
-                setPowerBoostInternal(Boost.INTERACTION, 0);
+                powerHintInternal(PowerHint.INTERACTION, 0);
                 mLastInteractivePowerHintTime = eventTime;
             }
 
@@ -3149,7 +3171,7 @@
             mHalInteractiveModeEnabled = enable;
             Trace.traceBegin(Trace.TRACE_TAG_POWER, "setHalInteractive(" + enable + ")");
             try {
-                mNativeWrapper.nativeSetPowerMode(Mode.INTERACTIVE, enable);
+                mNativeWrapper.nativeSetInteractive(enable);
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_POWER);
             }
@@ -3623,6 +3645,19 @@
         mIsVrModeEnabled = enabled;
     }
 
+    private void powerHintInternal(int hintId, int data) {
+        // Maybe filter the event.
+        switch (hintId) {
+            case PowerHint.LAUNCH: // 1: activate launch boost 0: deactivate.
+                if (data == 1 && mBatterySaverController.isLaunchBoostDisabled()) {
+                    return;
+                }
+                break;
+        }
+
+        mNativeWrapper.nativeSendPowerHint(hintId, data);
+    }
+
     private void setPowerBoostInternal(int boost, int durationMs) {
         // Maybe filter the event.
         mNativeWrapper.nativeSetPowerBoost(boost, durationMs);
@@ -4369,7 +4404,7 @@
     private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
         @Override
         public void onVrStateChanged(boolean enabled) {
-            setPowerModeInternal(Mode.VR, enabled);
+            powerHintInternal(PowerHint.VR_MODE, enabled ? 1 : 0);
 
             synchronized (mLock) {
                 if (mIsVrModeEnabled != enabled) {
@@ -4680,6 +4715,16 @@
         }
 
         @Override // Binder call
+        public void powerHint(int hintId, int data) {
+            if (!mSystemReady) {
+                // Service not ready yet, so who the heck cares about power hints, bah.
+                return;
+            }
+            mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
+            powerHintInternal(hintId, data);
+        }
+
+        @Override // Binder call
         public void setPowerBoost(int boost, int durationMs) {
             if (!mSystemReady) {
                 // Service not ready yet, so who the heck cares about power hints, bah.
@@ -5514,6 +5559,11 @@
         }
 
         @Override
+        public void powerHint(int hintId, int data) {
+            powerHintInternal(hintId, data);
+        }
+
+        @Override
         public void setPowerBoost(int boost, int durationMs) {
             setPowerBoostInternal(boost, durationMs);
         }
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index 6ff069b..2a4a69d 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -23,7 +23,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
-import android.hardware.power.Mode;
+import android.hardware.power.V1_0.PowerHint;
 import android.os.BatteryManager;
 import android.os.BatterySaverPolicyConfig;
 import android.os.Handler;
@@ -474,7 +474,7 @@
 
         final PowerManagerInternal pmi = LocalServices.getService(PowerManagerInternal.class);
         if (pmi != null) {
-            pmi.setPowerMode(Mode.LOW_POWER, isEnabled());
+            pmi.powerHint(PowerHint.LOW_POWER, isEnabled() ? 1 : 0);
         }
 
         updateBatterySavingStats();
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
index 72f8027..761858c 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerHw2Enforcer.java
@@ -192,10 +192,7 @@
     }
 
     private static RuntimeException handleException(RuntimeException e) {
-        // TODO(b/160169016): There is currently no other way to distinguish dead object from other
-        //   exceptions.
-        if (e.getCause() instanceof RemoteException &&
-                e.getCause().getMessage().equals("HwBinder Error: (-32)")) {
+        if (e.getCause() instanceof DeadObjectException) {
             // Server is dead, no need to reboot.
             Log.e(TAG, "HAL died");
         } else {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index a87fe61..4e355f0 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1394,10 +1394,11 @@
     }
 
     /**
-     * @see Letterbox#notIntersectsOrFullyContains(Rect)
+     * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
+     * the given {@code rect}.
      */
-    boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
-        return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
+    boolean isLetterboxOverlappingWith(Rect rect) {
+        return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
     }
 
     static class Token extends IApplicationToken.Stub {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index ea9aab7..686e016 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -2793,7 +2793,6 @@
 
         Task task = child.asTask();
         try {
-
             if (task != null) {
                 task.setForceShowForAllUsers(showForAllUsers);
             }
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 26e0790..123fb6c 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -175,7 +175,7 @@
         }
         final Rect rotatedContentFrame = win.mToken.getFixedRotationBarContentFrame(mWindowType);
         final Rect contentFrame = rotatedContentFrame != null ? rotatedContentFrame : mContentFrame;
-        return win.letterboxNotIntersectsOrFullyContains(contentFrame);
+        return !win.isLetterboxedOverlappingWith(contentFrame);
     }
 
     boolean setBarShowingLw(final boolean show) {
diff --git a/services/core/java/com/android/server/wm/DisplayArea.java b/services/core/java/com/android/server/wm/DisplayArea.java
index 201473e..fbb2fcb 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -109,6 +109,66 @@
     }
 
     @Override
+    void positionChildAt(int position, T child, boolean includingParents) {
+        if (child.asDisplayArea() == null) {
+            // Reposition other window containers as normal.
+            super.positionChildAt(position, child, includingParents);
+            return;
+        }
+
+        final int targetPosition = findPositionForChildDisplayArea(position, child.asDisplayArea());
+        super.positionChildAt(targetPosition, child, false /* includingParents */);
+
+        final WindowContainer parent = getParent();
+        if (includingParents && parent != null
+                && (position == POSITION_TOP || position == POSITION_BOTTOM)) {
+            parent.positionChildAt(position, this /* child */, true /* includingParents */);
+        }
+    }
+
+    /**
+     * When a {@link DisplayArea} is repositioned, it should only be moved among its siblings of the
+     * same {@link Type}.
+     * For example, when a {@link DisplayArea} of {@link Type#ANY} is repositioned, it shouldn't be
+     * moved above any {@link Type#ABOVE_TASKS} siblings, or below any {@link Type#BELOW_TASKS}
+     * siblings.
+     */
+    private int findPositionForChildDisplayArea(int requestPosition, DisplayArea child) {
+        if (child.getParent() != this) {
+            throw new IllegalArgumentException("positionChildAt: container=" + child.getName()
+                    + " is not a child of container=" + getName()
+                    + " current parent=" + child.getParent());
+        }
+
+        // The max possible position we can insert the child at.
+        int maxPosition = findMaxPositionForChildDisplayArea(child);
+        // The min possible position we can insert the child at.
+        int minPosition = findMinPositionForChildDisplayArea(child);
+
+        return Math.max(Math.min(requestPosition, maxPosition), minPosition);
+    }
+
+    private int findMaxPositionForChildDisplayArea(DisplayArea child) {
+        final Type childType = Type.typeOf(child);
+        for (int i = mChildren.size() - 1; i > 0; i--) {
+            if (Type.typeOf(getChildAt(i)) == childType) {
+                return i;
+            }
+        }
+        return 0;
+    }
+
+    private int findMinPositionForChildDisplayArea(DisplayArea child) {
+        final Type childType = Type.typeOf(child);
+        for (int i = 0; i < mChildren.size(); i++) {
+            if (Type.typeOf(getChildAt(i)) == childType) {
+                return i;
+            }
+        }
+        return mChildren.size() - 1;
+    }
+
+    @Override
     boolean needsZBoost() {
         // Z Boost should only happen at or below the ActivityStack level.
         return false;
@@ -423,7 +483,7 @@
         }
 
         static Type typeOf(WindowContainer c) {
-            if (c instanceof DisplayArea) {
+            if (c.asDisplayArea() != null) {
                 return ((DisplayArea) c).mType;
             } else if (c instanceof WindowToken && !(c instanceof ActivityRecord)) {
                 return typeOf((WindowToken) c);
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
index a161aca..59c3204 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicy.java
@@ -63,6 +63,11 @@
      */
     public abstract List<DisplayArea<? extends WindowContainer>> getDisplayAreas(int featureId);
 
+    /**
+     * @return the default/fallback {@link TaskDisplayArea} on the display.
+     */
+    public abstract TaskDisplayArea getDefaultTaskDisplayArea();
+
     /** Provider for platform-default display area policy. */
     static final class DefaultProvider implements DisplayAreaPolicy.Provider {
         @Override
diff --git a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
index 465d089..681b21c 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaPolicyBuilder.java
@@ -70,7 +70,7 @@
  *
  * </pre>
  *
- * // TODO(b/157683117): document more complex scenarios where we need multiple areas per feature.
+ * // TODO(b/158713595): document more complex scenarios where we need multiple areas per feature.
  */
 class DisplayAreaPolicyBuilder {
     @Nullable private HierarchyBuilder mRootHierarchyBuilder;
@@ -123,8 +123,14 @@
             }
 
             containsImeContainer = containsImeContainer || hierarchyBuilder.mImeContainer != null;
-            containsDefaultTda = containsDefaultTda
-                    || containsDefaultTaskDisplayArea(hierarchyBuilder);
+            if (containsDefaultTda) {
+                if (containsDefaultTaskDisplayArea(hierarchyBuilder)) {
+                    throw new IllegalStateException("Only one TaskDisplayArea can have the feature "
+                            + "of FEATURE_DEFAULT_TASK_CONTAINER");
+                }
+            } else {
+                containsDefaultTda = containsDefaultTaskDisplayArea(hierarchyBuilder);
+            }
         }
 
         if (!containsImeContainer) {
@@ -506,6 +512,7 @@
     static class Result extends DisplayAreaPolicy {
         final List<RootDisplayArea> mDisplayAreaGroupRoots;
         final BiFunction<WindowToken, Bundle, RootDisplayArea> mSelectRootForWindowFunc;
+        private final TaskDisplayArea mDefaultTaskDisplayArea;
 
         Result(WindowManagerService wmService, RootDisplayArea root,
                 List<RootDisplayArea> displayAreaGroupRoots,
@@ -518,6 +525,16 @@
                     // not specified.
                     ? (window, options) -> mRoot
                     : selectRootForWindowFunc;
+
+            // Cache the default TaskDisplayArea for quick access.
+            mDefaultTaskDisplayArea = mRoot.getItemFromTaskDisplayAreas(taskDisplayArea ->
+                    taskDisplayArea.mFeatureId == FEATURE_DEFAULT_TASK_CONTAINER
+                            ? taskDisplayArea
+                            : null);
+            if (mDefaultTaskDisplayArea == null) {
+                throw new IllegalStateException(
+                        "No display area with FEATURE_DEFAULT_TASK_CONTAINER");
+            }
         }
 
         @Override
@@ -561,6 +578,11 @@
                 }
             }
         }
+
+        @Override
+        public TaskDisplayArea getDefaultTaskDisplayArea() {
+            return mDefaultTaskDisplayArea;
+        }
     }
 
     static class PendingArea {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 0a3b884..de91af7 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2512,8 +2512,7 @@
      * or for cases when multi-instance is not supported yet (like Split-screen, PiP or Recents).
      */
     TaskDisplayArea getDefaultTaskDisplayArea() {
-        return getItemFromTaskDisplayAreas(taskDisplayArea -> taskDisplayArea,
-                false /* traverseTopToBottom */);
+        return mDisplayAreaPolicy.getDefaultTaskDisplayArea();
     }
 
     void positionDisplayAt(int position, boolean includingParents) {
@@ -2545,9 +2544,11 @@
      * Find the task whose outside touch area (for resizing) (x, y) falls within.
      * Returns null if the touch doesn't fall into a resizing area.
      */
+    @Nullable
     Task findTaskForResizePoint(int x, int y) {
         final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
-        return mTmpTaskForResizePointSearchResult.process(getDefaultTaskDisplayArea(), x, y, delta);
+        return getItemFromTaskDisplayAreas(taskDisplayArea ->
+                mTmpTaskForResizePointSearchResult.process(taskDisplayArea, x, y, delta));
     }
 
     void updateTouchExcludeRegion() {
@@ -2615,7 +2616,7 @@
         // to exclude the docked stack from touch so we need the entire screen area and not just a
         // small portion which the home stack currently is resized to.
         if (task.isActivityTypeHome() && task.isVisible() && task.isResizeable()) {
-            mDisplayContent.getBounds(mTmpRect);
+            task.getDisplayArea().getBounds(mTmpRect);
         } else {
             task.getDimBounds(mTmpRect);
         }
@@ -3426,12 +3427,13 @@
     }
 
     private boolean isImeControlledByApp() {
-        return mInputMethodTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
-                mInputMethodTarget.getWindowingMode());
+        return mInputMethodInputTarget != null && !WindowConfiguration.isSplitScreenWindowingMode(
+                        mInputMethodInputTarget.getWindowingMode());
     }
 
     boolean isImeAttachedToApp() {
         return isImeControlledByApp()
+                && mInputMethodTarget != null
                 && mInputMethodTarget.mActivityRecord != null
                 && mInputMethodTarget.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
                 // An activity with override bounds should be letterboxed inside its parent bounds,
@@ -3457,9 +3459,9 @@
     InsetsControlTarget getImeFallback() {
         // host is in non-default display that doesn't support system decor, default to
         // default display's StatusBar to control IME (when available), else let system control it.
-        WindowState statusBar = 
-                mWmService.getDefaultDisplayContentLocked().getDisplayPolicy().getStatusBar();
-        return statusBar != null ? statusBar : mRemoteInsetsControlTarget;
+        final DisplayContent defaultDc = mWmService.getDefaultDisplayContentLocked();
+        WindowState statusBar = defaultDc.getDisplayPolicy().getStatusBar();
+        return statusBar != null ? statusBar : defaultDc.mRemoteInsetsControlTarget;
     }
 
     boolean canShowIme() {
@@ -3519,7 +3521,10 @@
      */
     @VisibleForTesting
     InsetsControlTarget computeImeControlTarget() {
-        if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null) {
+        if (!isImeControlledByApp() && mRemoteInsetsControlTarget != null
+                || (mInputMethodInputTarget != null
+                        && getImeHostOrFallback(mInputMethodInputTarget.getWindow())
+                                == mRemoteInsetsControlTarget)) {
             return mRemoteInsetsControlTarget;
         } else {
             // Now, a special case -- if the last target's window is in the process of exiting, but
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index d2f5d2d..b4ead8e 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -139,7 +139,7 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
-import android.hardware.power.Boost;
+import android.hardware.power.V1_0.PowerHint;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
@@ -544,8 +544,8 @@
                     @Override
                     public void onFling(int duration) {
                         if (mService.mPowerManagerInternal != null) {
-                            mService.mPowerManagerInternal.setPowerBoost(
-                                    Boost.INTERACTION, duration);
+                            mService.mPowerManagerInternal.powerHint(
+                                    PowerHint.INTERACTION, duration);
                         }
                     }
 
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index c63128c..0747e24 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -42,7 +42,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.hardware.power.Boost;
+import android.hardware.power.V1_0.PowerHint;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -1473,7 +1473,7 @@
             @Override
             public void run() {
                 // Send interaction power boost to improve redraw performance.
-                mService.mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
+                mService.mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
                 if (isRotationChoicePossible(mCurrentAppOrientation)) {
                     final boolean isValid = isValidRotationChoice(mRotation);
                     sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 99ee5e1..e7fbc334 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -32,7 +32,7 @@
  */
 class ImeInsetsSourceProvider extends InsetsSourceProvider {
 
-    private WindowState mImeTargetFromIme;
+    private InsetsControlTarget mImeTargetFromIme;
     private Runnable mShowImeRunner;
     private boolean mIsImeLayoutDrawn;
 
@@ -47,10 +47,12 @@
      *
      * @param imeTarget imeTarget on which IME request is coming from.
      */
-    void scheduleShowImePostLayout(WindowState imeTarget) {
+    void scheduleShowImePostLayout(InsetsControlTarget imeTarget) {
         boolean targetChanged = mImeTargetFromIme != imeTarget
                 && mImeTargetFromIme != null && imeTarget != null && mShowImeRunner != null
-                && mImeTargetFromIme.mActivityRecord == imeTarget.mActivityRecord;
+                && imeTarget.getWindow() != null && mImeTargetFromIme.getWindow() != null
+                && mImeTargetFromIme.getWindow().mActivityRecord
+                        == imeTarget.getWindow().mActivityRecord;
         mImeTargetFromIme = imeTarget;
         if (targetChanged) {
             // target changed, check if new target can show IME.
@@ -62,7 +64,8 @@
             return;
         }
 
-        ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeTargetFromIme.getName());
+        ProtoLog.d(WM_DEBUG_IME, "Schedule IME show for %s", mImeTargetFromIme.getWindow() == null
+                ? mImeTargetFromIme : mImeTargetFromIme.getWindow().getName());
         mShowImeRunner = () -> {
             ProtoLog.d(WM_DEBUG_IME, "Run showImeRunner");
             // Target should still be the same.
@@ -127,13 +130,17 @@
             return false;
         }
         ProtoLog.d(WM_DEBUG_IME, "dcTarget: %s mImeTargetFromIme: %s",
-                dcTarget.getName(), mImeTargetFromIme.getName());
+                dcTarget.getName(), mImeTargetFromIme.getWindow() == null
+                        ? mImeTargetFromIme : mImeTargetFromIme.getWindow().getName());
 
         return (!dcTarget.isClosing() && mImeTargetFromIme == dcTarget)
-                || (mImeTargetFromIme != null && dcTarget.getParentWindow() == mImeTargetFromIme
-                        && dcTarget.mSubLayer > mImeTargetFromIme.mSubLayer)
+                || (mImeTargetFromIme != null && mImeTargetFromIme.getWindow() != null
+                        && dcTarget.getParentWindow() == mImeTargetFromIme
+                        && dcTarget.mSubLayer > mImeTargetFromIme.getWindow().mSubLayer)
                 || mImeTargetFromIme == mDisplayContent.getImeFallback()
-                || (!mImeTargetFromIme.isClosing() && controlTarget == mImeTargetFromIme);
+                || controlTarget == mImeTargetFromIme
+                        && (mImeTargetFromIme.getWindow() == null 
+                                || !mImeTargetFromIme.getWindow().isClosing());
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 5d1c85d..a685886 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -77,10 +77,10 @@
         mOuter.set(outer);
         mInner.set(inner);
 
-        mTop.layout(outer.left, outer.top, outer.right, inner.top, surfaceOrigin);
-        mLeft.layout(outer.left, outer.top, inner.left, outer.bottom, surfaceOrigin);
-        mBottom.layout(outer.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
-        mRight.layout(inner.right, outer.top, outer.right, outer.bottom, surfaceOrigin);
+        mTop.layout(outer.left, outer.top, inner.right, inner.top, surfaceOrigin);
+        mLeft.layout(outer.left, inner.top, inner.left, outer.bottom, surfaceOrigin);
+        mBottom.layout(inner.left, inner.bottom, outer.right, outer.bottom, surfaceOrigin);
+        mRight.layout(inner.right, outer.top, outer.right, inner.bottom, surfaceOrigin);
     }
 
 
@@ -101,29 +101,17 @@
     }
 
     /**
-     * Returns {@code true} if the letterbox does not overlap with the bar, or the letterbox can
-     * fully cover the window frame.
-     *
-     * @param rect The area of the window frame.
+     * Returns true if any part of the letterbox overlaps with the given {@code rect}.
      */
-    boolean notIntersectsOrFullyContains(Rect rect) {
-        int emptyCount = 0;
-        int noOverlappingCount = 0;
+    public boolean isOverlappingWith(Rect rect) {
         for (LetterboxSurface surface : mSurfaces) {
-            final Rect surfaceRect = surface.mLayoutFrameGlobal;
-            if (surfaceRect.isEmpty()) {
-                // empty letterbox
-                emptyCount++;
-            } else if (!Rect.intersects(surfaceRect, rect)) {
-                // no overlapping
-                noOverlappingCount++;
-            } else if (surfaceRect.contains(rect)) {
-                // overlapping and covered
+            if (surface.isOverlappingWith(rect)) {
                 return true;
             }
         }
-        return (emptyCount + noOverlappingCount) == mSurfaces.length;
+        return false;
     }
+
     /**
      * Hides the letterbox.
      *
@@ -298,6 +286,17 @@
             return Math.max(0, mLayoutFrameGlobal.height());
         }
 
+        /**
+         * Returns if the given {@code rect} overlaps with this letterbox piece.
+         * @param rect the area to check for overlap in global coordinates
+         */
+        public boolean isOverlappingWith(Rect rect) {
+            if (mLayoutFrameGlobal.isEmpty()) {
+                return false;
+            }
+            return Rect.intersects(rect, mLayoutFrameGlobal);
+        }
+
         public void applySurfaceChanges(SurfaceControl.Transaction t) {
             if (mSurfaceFrameRelative.equals(mLayoutFrameRelative)) {
                 // Nothing changed.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 40f8fab..ab21519 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -111,7 +111,7 @@
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
-import android.hardware.power.Mode;
+import android.hardware.power.V1_0.PowerHint;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Debug;
@@ -950,9 +950,9 @@
 
         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
-            mWmService.mPowerManagerInternal.setPowerMode(
-                    Mode.SUSTAINED_PERFORMANCE,
-                    mSustainedPerformanceModeEnabled);
+            mWmService.mPowerManagerInternal.powerHint(
+                    PowerHint.SUSTAINED_PERFORMANCE,
+                    mSustainedPerformanceModeEnabled ? 1 : 0);
         }
 
         if (mUpdateRotation) {
@@ -3478,7 +3478,7 @@
         }
 
         if (sendPowerModeLaunch && mService.mPowerManagerInternal != null) {
-            mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
             mPowerModeLaunchStarted = true;
         }
     }
@@ -3486,7 +3486,7 @@
     void endPowerModeLaunchIfNeeded() {
         // Trigger launch power mode off if activity is launched
         if (mPowerModeLaunchStarted && mService.mPowerManagerInternal != null) {
-            mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false);
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
             mPowerModeLaunchStarted = false;
         }
     }
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 34d084a..837f1b5 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -26,7 +26,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
-import android.hardware.power.Boost;
+import android.hardware.power.V1_0.PowerHint;
 import android.os.Handler;
 import android.os.PowerManagerInternal;
 import android.util.ArrayMap;
@@ -246,7 +246,7 @@
         synchronized (mLock) {
             startPendingAnimationsLocked();
         }
-        mPowerManagerInternal.setPowerBoost(Boost.INTERACTION, 0);
+        mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
     }
 
     private void scheduleApplyTransaction() {
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 8bab106..aba5b99 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -331,7 +331,7 @@
     @Override
     void positionChildAt(int position, ActivityStack child, boolean includingParents) {
         final boolean moveToTop = position >= getChildCount() - 1;
-        final boolean moveToBottom = (position == POSITION_BOTTOM || position == 0);
+        final boolean moveToBottom = position <= 0;
 
         if (child.getWindowConfiguration().isAlwaysOnTop() && !moveToTop) {
             // This stack is always-on-top, override the default behavior.
@@ -351,12 +351,9 @@
         final int targetPosition = findPositionForStack(position, child, false /* adding */);
         super.positionChildAt(targetPosition, child, false /* includingParents */);
 
-        if (includingParents && (moveToTop || moveToBottom)) {
-            // The DisplayContent children do not re-order, but we still want to move the
-            // display of this stack container because the intention of positioning is to have
-            // higher z-order to gain focus.
-            mDisplayContent.positionDisplayAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
-                    true /* includingParents */);
+        if (includingParents && getParent() != null && (moveToTop || moveToBottom)) {
+            getParent().positionChildAt(moveToTop ? POSITION_TOP : POSITION_BOTTOM,
+                    this /* child */, true /* includingParents */);
         }
 
         child.updateTaskMovement(moveToTop);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 7b92c28..f1e965b 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -685,7 +685,6 @@
      */
     @CallSuper
     void positionChildAt(int position, E child, boolean includingParents) {
-
         if (child.getParent() != this) {
             throw new IllegalArgumentException("positionChildAt: container=" + child.getName()
                     + " is not a child of container=" + getName()
@@ -995,11 +994,13 @@
      * changes (eg. a transition animation might play out first).
      */
     void onChildVisibilityRequested(boolean visible) {
-        // If we are changing visibility, then a snapshot isn't necessary and we are no-longer
+        // If we are losing visibility, then a snapshot isn't necessary and we are no-longer
         // part of a change transition.
-        mSurfaceFreezer.unfreeze(getSyncTransaction());
-        if (mDisplayContent != null) {
-            mDisplayContent.mChangingContainers.remove(this);
+        if (!visible) {
+            mSurfaceFreezer.unfreeze(getSyncTransaction());
+            if (mDisplayContent != null) {
+                mDisplayContent.mChangingContainers.remove(this);
+            }
         }
         WindowContainer parent = getParent();
         if (parent != null) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 85972bf..4df48dc 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7599,13 +7599,14 @@
                 if (imeTarget == null) {
                     return;
                 }
-                imeTarget = imeTarget.getImeControlTarget().getWindow();
+                final InsetsControlTarget controlTarget = imeTarget.getImeControlTarget();
+                imeTarget = controlTarget.getWindow();
                 // If InsetsControlTarget doesn't have a window, its using remoteControlTarget which
                 // is controlled by default display
                 final DisplayContent dc = imeTarget != null
                         ? imeTarget.getDisplayContent() : getDefaultDisplayContentLocked();
                 dc.getInsetsStateController().getImeSourceProvider()
-                        .scheduleShowImePostLayout(imeTarget);
+                        .scheduleShowImePostLayout(controlTarget);
             }
         }
 
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 10bcbeb..24ad853 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -324,12 +324,13 @@
                     (task.isRootTask() && !task.mCreatedByOrganizer)
                             || task.getParent().asTask().mCreatedByOrganizer;
             if (isNonOrganizedRootableTask) {
-                Task newParent = hop.getNewParent() == null ? null
-                        : WindowContainer.fromBinder(hop.getNewParent()).asTask();
+                WindowContainer newParent = hop.getNewParent() == null
+                        ? dc.getDefaultTaskDisplayArea()
+                        : WindowContainer.fromBinder(hop.getNewParent());
                 if (task.getParent() != newParent) {
-                    if (newParent == null) {
-                        // Re-parent task to display as a root task.
-                        as.reparent(dc.getDefaultTaskDisplayArea(), hop.getToTop());
+                    if (newParent instanceof TaskDisplayArea) {
+                        // For now, reparenting to displayarea is different from other reparents...
+                        as.reparent((TaskDisplayArea) newParent, hop.getToTop());
                     } else if (newParent.inMultiWindowMode() && !task.isResizeable()
                             && task.isLeafTask()) {
                         Slog.w(TAG, "Can't support task that doesn't support multi-window mode in"
@@ -341,8 +342,9 @@
                                 false /*moveParents*/, "sanitizeAndApplyHierarchyOp");
                     }
                 } else {
-                    final ActivityStack rootTask =
-                            (ActivityStack) (newParent != null ? newParent : task.getRootTask());
+                    final ActivityStack rootTask = (ActivityStack) (
+                            (newParent != null && !(newParent instanceof TaskDisplayArea))
+                                    ? newParent : task.getRootTask());
                     if (hop.getToTop()) {
                         as.getDisplayArea().positionStackAtTop(rootTask,
                                 false /* includingParents */);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 86bc0a2..27c4bf4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3819,12 +3819,9 @@
         return mActivityRecord.getBounds().equals(mTmpRect);
     }
 
-    /**
-     * @see Letterbox#notIntersectsOrFullyContains(Rect)
-     */
-    boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
-        return mActivityRecord == null
-                || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect);
+    @Override
+    public boolean isLetterboxedOverlappingWith(Rect rect) {
+        return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect);
     }
 
     boolean isDragResizeChanged() {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 5f1895a..0e1b2f2 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -14,7 +14,6 @@
     ],
 
     srcs: [
-        ":lib_alarmManagerService_native",
         "BroadcastRadio/JavaRef.cpp",
         "BroadcastRadio/NativeCallbackThread.cpp",
         "BroadcastRadio/BroadcastRadioService.cpp",
@@ -72,17 +71,6 @@
     header_libs: [
         "bionic_libc_platform_headers",
     ],
-
-    product_variables: {
-        arc: {
-            exclude_srcs: [
-                "com_android_server_alarm_AlarmManagerService.cpp",
-            ],
-            srcs: [
-                ":arctimersrcs",
-            ],
-        }
-    }
 }
 
 cc_defaults {
@@ -198,10 +186,3 @@
         "com_android_server_net_NetworkStatsFactory.cpp",
     ],
 }
-
-filegroup {
-    name: "lib_alarmManagerService_native",
-    srcs: [
-        "com_android_server_alarm_AlarmManagerService.cpp",
-    ],
-}
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index d11c4bc..6140531 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -29,6 +29,7 @@
 
 #include <nativehelper/ScopedUtfChars.h>
 #include <powermanager/PowerHalController.h>
+#include <powermanager/PowerHalLoader.h>
 
 #include <limits.h>
 
@@ -47,13 +48,17 @@
 
 #include "com_android_server_power_PowerManagerService.h"
 
+using android::String8;
+using android::hardware::Return;
+using android::hardware::Void;
 using android::hardware::power::Boost;
 using android::hardware::power::Mode;
-using android::String8;
+using android::hardware::power::V1_0::Feature;
+using android::hardware::power::V1_0::PowerHint;
+using android::system::suspend::ISuspendControlService;
 using android::system::suspend::V1_0::ISystemSuspend;
 using android::system::suspend::V1_0::IWakeLock;
 using android::system::suspend::V1_0::WakeLockType;
-using android::system::suspend::ISuspendControlService;
 using IPowerV1_1 = android::hardware::power::V1_1::IPower;
 using IPowerV1_0 = android::hardware::power::V1_0::IPower;
 using IPowerAidl = android::hardware::power::IPower;
@@ -69,7 +74,18 @@
 // ----------------------------------------------------------------------------
 
 static jobject gPowerManagerServiceObj;
-static power::PowerHalController gPowerHalController;
+static sp<IPowerV1_0> gPowerHalHidlV1_0_ = nullptr;
+static sp<IPowerV1_1> gPowerHalHidlV1_1_ = nullptr;
+static sp<IPowerAidl> gPowerHalAidl_ = nullptr;
+static std::mutex gPowerHalMutex;
+
+enum class HalVersion {
+    NONE,
+    HIDL_1_0,
+    HIDL_1_1,
+    AIDL,
+};
+
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
 // Throttling interval for user activity calls.
@@ -87,19 +103,208 @@
     return false;
 }
 
+// Check validity of current handle to the power HAL service, and connect to it if necessary.
+// The caller must be holding gPowerHalMutex.
+static HalVersion connectPowerHalLocked() {
+    static bool gPowerHalHidlExists = true;
+    static bool gPowerHalAidlExists = true;
+    if (!gPowerHalHidlExists && !gPowerHalAidlExists) {
+        return HalVersion::NONE;
+    }
+    if (gPowerHalAidlExists) {
+        if (!gPowerHalAidl_) {
+            gPowerHalAidl_ = waitForVintfService<IPowerAidl>();
+        }
+        if (gPowerHalAidl_) {
+            ALOGV("Successfully connected to Power HAL AIDL service.");
+            return HalVersion::AIDL;
+        } else {
+            gPowerHalAidlExists = false;
+        }
+    }
+    if (gPowerHalHidlExists && gPowerHalHidlV1_0_ == nullptr) {
+        gPowerHalHidlV1_0_ = IPowerV1_0::getService();
+        if (gPowerHalHidlV1_0_) {
+            ALOGV("Successfully connected to Power HAL HIDL 1.0 service.");
+            // Try cast to powerHAL HIDL V1_1
+            gPowerHalHidlV1_1_ = IPowerV1_1::castFrom(gPowerHalHidlV1_0_);
+            if (gPowerHalHidlV1_1_) {
+                ALOGV("Successfully connected to Power HAL HIDL 1.1 service.");
+            }
+        } else {
+            ALOGV("Couldn't load power HAL HIDL service");
+            gPowerHalHidlExists = false;
+            return HalVersion::NONE;
+        }
+    }
+    if (gPowerHalHidlV1_1_) {
+        return HalVersion::HIDL_1_1;
+    } else if (gPowerHalHidlV1_0_) {
+        return HalVersion::HIDL_1_0;
+    }
+    return HalVersion::NONE;
+}
+
+// Check if a call to a power HAL function failed; if so, log the failure and invalidate the
+// current handle to the power HAL service.
+bool processPowerHalReturn(bool isOk, const char* functionName) {
+    if (!isOk) {
+        ALOGE("%s() failed: power HAL service not available.", functionName);
+        gPowerHalMutex.lock();
+        gPowerHalHidlV1_0_ = nullptr;
+        gPowerHalHidlV1_1_ = nullptr;
+        gPowerHalAidl_ = nullptr;
+        gPowerHalMutex.unlock();
+    }
+    return isOk;
+}
+
+enum class HalSupport {
+    UNKNOWN = 0,
+    ON,
+    OFF,
+};
+
+static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) {
+    // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
+    // Need to increase the array size if more boost supported.
+    static std::array<std::atomic<HalSupport>,
+                      static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1>
+            boostSupportedArray = {HalSupport::UNKNOWN};
+
+    // Quick return if boost is not supported by HAL
+    if (boost > Boost::DISPLAY_UPDATE_IMMINENT ||
+        boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
+        ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
+        return;
+    }
+
+    if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
+        bool isSupported = false;
+        handle->isBoostSupported(boost, &isSupported);
+        boostSupportedArray[static_cast<int32_t>(boost)] =
+                isSupported ? HalSupport::ON : HalSupport::OFF;
+        if (!isSupported) {
+            ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
+                  toString(boost).c_str());
+            return;
+        }
+    }
+
+    auto ret = handle->setBoost(boost, durationMs);
+    processPowerHalReturn(ret.isOk(), "setPowerBoost");
+}
+
 static void setPowerBoost(Boost boost, int32_t durationMs) {
-    gPowerHalController.setBoost(boost, durationMs);
-    SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(boost));
+    std::unique_lock<std::mutex> lock(gPowerHalMutex);
+    if (connectPowerHalLocked() != HalVersion::AIDL) {
+        ALOGV("Power HAL AIDL not available");
+        return;
+    }
+    sp<IPowerAidl> handle = gPowerHalAidl_;
+    lock.unlock();
+    setPowerBoostWithHandle(handle, boost, durationMs);
+}
+
+static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) {
+    // Android framework only sends mode upto DISPLAY_INACTIVE.
+    // Need to increase the array if more mode supported.
+    static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
+            modeSupportedArray = {HalSupport::UNKNOWN};
+
+    // Quick return if mode is not supported by HAL
+    if (mode > Mode::DISPLAY_INACTIVE ||
+        modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
+        ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
+        return false;
+    }
+
+    if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
+        bool isSupported = false;
+        handle->isModeSupported(mode, &isSupported);
+        modeSupportedArray[static_cast<int32_t>(mode)] =
+                isSupported ? HalSupport::ON : HalSupport::OFF;
+        if (!isSupported) {
+            ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
+            return false;
+        }
+    }
+
+    auto ret = handle->setMode(mode, enabled);
+    processPowerHalReturn(ret.isOk(), "setPowerMode");
+    return ret.isOk();
 }
 
 static bool setPowerMode(Mode mode, bool enabled) {
-    android::base::Timer t;
-    auto result = gPowerHalController.setMode(mode, enabled);
-    if (mode == Mode::INTERACTIVE && t.duration() > 20ms) {
-        ALOGD("Excessive delay in setting interactive mode to %s while turning screen %s",
-              enabled ? "true" : "false", enabled ? "on" : "off");
+    std::unique_lock<std::mutex> lock(gPowerHalMutex);
+    if (connectPowerHalLocked() != HalVersion::AIDL) {
+        ALOGV("Power HAL AIDL not available");
+        return false;
     }
-    return result == power::HalResult::SUCCESSFUL;
+    sp<IPowerAidl> handle = gPowerHalAidl_;
+    lock.unlock();
+    return setPowerModeWithHandle(handle, mode, enabled);
+}
+
+static void sendPowerHint(PowerHint hintId, uint32_t data) {
+    std::unique_lock<std::mutex> lock(gPowerHalMutex);
+    switch (connectPowerHalLocked()) {
+        case HalVersion::NONE:
+            return;
+        case HalVersion::HIDL_1_0: {
+            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
+            lock.unlock();
+            auto ret = handle->powerHint(hintId, data);
+            processPowerHalReturn(ret.isOk(), "powerHint");
+            break;
+        }
+        case HalVersion::HIDL_1_1: {
+            sp<IPowerV1_1> handle = gPowerHalHidlV1_1_;
+            lock.unlock();
+            auto ret = handle->powerHintAsync(hintId, data);
+            processPowerHalReturn(ret.isOk(), "powerHintAsync");
+            break;
+        }
+        case HalVersion::AIDL: {
+            if (hintId == PowerHint::INTERACTION) {
+                sp<IPowerAidl> handle = gPowerHalAidl_;
+                lock.unlock();
+                setPowerBoostWithHandle(handle, Boost::INTERACTION, data);
+                break;
+            } else if (hintId == PowerHint::LAUNCH) {
+                sp<IPowerAidl> handle = gPowerHalAidl_;
+                lock.unlock();
+                setPowerModeWithHandle(handle, Mode::LAUNCH, static_cast<bool>(data));
+                break;
+            } else if (hintId == PowerHint::LOW_POWER) {
+                sp<IPowerAidl> handle = gPowerHalAidl_;
+                lock.unlock();
+                setPowerModeWithHandle(handle, Mode::LOW_POWER, static_cast<bool>(data));
+                break;
+            } else if (hintId == PowerHint::SUSTAINED_PERFORMANCE) {
+                sp<IPowerAidl> handle = gPowerHalAidl_;
+                lock.unlock();
+                setPowerModeWithHandle(handle, Mode::SUSTAINED_PERFORMANCE,
+                                       static_cast<bool>(data));
+                break;
+            } else if (hintId == PowerHint::VR_MODE) {
+                sp<IPowerAidl> handle = gPowerHalAidl_;
+                lock.unlock();
+                setPowerModeWithHandle(handle, Mode::VR, static_cast<bool>(data));
+                break;
+            } else {
+                ALOGE("Unsupported power hint: %s.", toString(hintId).c_str());
+                return;
+            }
+        }
+        default: {
+            ALOGE("Unknown power HAL state");
+            return;
+        }
+    }
+    if (hintId == PowerHint::INTERACTION) {
+        SurfaceComposerClient::notifyPowerBoost(static_cast<int32_t>(Boost::INTERACTION));
+    }
 }
 
 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
@@ -119,7 +324,7 @@
             gLastEventTime[eventType] = eventTime;
 
             // Tell the power HAL when user activity occurs.
-            setPowerBoost(Boost::INTERACTION, 0);
+            sendPowerHint(PowerHint::INTERACTION, 0);
         }
 
         JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -186,7 +391,10 @@
 
 static void nativeInit(JNIEnv* env, jobject obj) {
     gPowerManagerServiceObj = env->NewGlobalRef(obj);
-    gPowerHalController.init();
+
+    gPowerHalMutex.lock();
+    connectPowerHalLocked();
+    gPowerHalMutex.unlock();
 }
 
 static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
@@ -199,6 +407,38 @@
     release_wake_lock(name.c_str());
 }
 
+static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
+    std::unique_lock<std::mutex> lock(gPowerHalMutex);
+    switch (connectPowerHalLocked()) {
+        case HalVersion::NONE:
+            return;
+        case HalVersion::HIDL_1_0:
+            FALLTHROUGH_INTENDED;
+        case HalVersion::HIDL_1_1: {
+            android::base::Timer t;
+            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
+            lock.unlock();
+            auto ret = handle->setInteractive(enable);
+            processPowerHalReturn(ret.isOk(), "setInteractive");
+            if (t.duration() > 20ms) {
+                ALOGD("Excessive delay in setInteractive(%s) while turning screen %s",
+                      enable ? "true" : "false", enable ? "on" : "off");
+            }
+            return;
+        }
+        case HalVersion::AIDL: {
+            sp<IPowerAidl> handle = gPowerHalAidl_;
+            lock.unlock();
+            setPowerModeWithHandle(handle, Mode::INTERACTIVE, enable);
+            return;
+        }
+        default: {
+            ALOGE("Unknown power HAL state");
+            return;
+        }
+    }
+}
+
 static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
     if (enable) {
         android::base::Timer t;
@@ -215,6 +455,10 @@
     }
 }
 
+static void nativeSendPowerHint(JNIEnv* /* env */, jclass /* clazz */, jint hintId, jint data) {
+    sendPowerHint(static_cast<PowerHint>(hintId), data);
+}
+
 static void nativeSetPowerBoost(JNIEnv* /* env */, jclass /* clazz */, jint boost,
                                 jint durationMs) {
     setPowerBoost(static_cast<Boost>(boost), durationMs);
@@ -225,6 +469,33 @@
     return setPowerMode(static_cast<Mode>(mode), enabled);
 }
 
+static void nativeSetFeature(JNIEnv* /* env */, jclass /* clazz */, jint featureId, jint data) {
+    std::unique_lock<std::mutex> lock(gPowerHalMutex);
+    switch (connectPowerHalLocked()) {
+        case HalVersion::NONE:
+            return;
+        case HalVersion::HIDL_1_0:
+            FALLTHROUGH_INTENDED;
+        case HalVersion::HIDL_1_1: {
+            sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
+            lock.unlock();
+            auto ret = handle->setFeature(static_cast<Feature>(featureId), static_cast<bool>(data));
+            processPowerHalReturn(ret.isOk(), "setFeature");
+            return;
+        }
+        case HalVersion::AIDL: {
+            sp<IPowerAidl> handle = gPowerHalAidl_;
+            lock.unlock();
+            setPowerModeWithHandle(handle, Mode::DOUBLE_TAP_TO_WAKE, static_cast<bool>(data));
+            return;
+        }
+        default: {
+            ALOGE("Unknown power HAL state");
+            return;
+        }
+    }
+}
+
 static bool nativeForceSuspend(JNIEnv* /* env */, jclass /* clazz */) {
     bool retval = false;
     getSuspendControl()->forceSuspend(&retval);
@@ -241,9 +512,12 @@
         {"nativeForceSuspend", "()Z", (void*)nativeForceSuspend},
         {"nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
          (void*)nativeReleaseSuspendBlocker},
+        {"nativeSetInteractive", "(Z)V", (void*)nativeSetInteractive},
         {"nativeSetAutoSuspend", "(Z)V", (void*)nativeSetAutoSuspend},
+        {"nativeSendPowerHint", "(II)V", (void*)nativeSendPowerHint},
         {"nativeSetPowerBoost", "(II)V", (void*)nativeSetPowerBoost},
         {"nativeSetPowerMode", "(IZ)Z", (void*)nativeSetPowerMode},
+        {"nativeSetFeature", "(II)V", (void*)nativeSetFeature},
 };
 
 #define FIND_CLASS(var, className) \
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 39e7249..6f24e3b 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -24,7 +24,6 @@
 #include "BroadcastRadio/Tuner.h"
 
 namespace android {
-int register_android_server_alarm_AlarmManagerService(JNIEnv* env);
 int register_android_server_BatteryStatsService(JNIEnv* env);
 int register_android_server_ConsumerIrService(JNIEnv *env);
 int register_android_server_InputManager(JNIEnv* env);
@@ -86,7 +85,6 @@
     register_android_server_SerialService(env);
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);
-    register_android_server_alarm_AlarmManagerService(env);
     register_android_server_UsbDeviceManager(env);
     register_android_server_UsbMidiDevice(env);
     register_android_server_UsbAlsaJackDetector(env);
diff --git a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
index a1bfcdf..4a73efe 100644
--- a/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/BackupManagerServiceRoboTest.java
@@ -38,6 +38,8 @@
 
 import android.annotation.UserIdInt;
 import android.app.Application;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManager.OperationType;
 import android.app.backup.IBackupManagerMonitor;
 import android.app.backup.IBackupObserver;
 import android.app.backup.IFullBackupRestoreObserver;
@@ -871,7 +873,8 @@
                 SecurityException.class,
                 () ->
                         backupManagerService.requestBackup(
-                                mUserTwoId, packages, observer, monitor, 0));
+                                mUserTwoId, packages, observer, monitor, 0,
+                                OperationType.BACKUP));
     }
 
     /**
@@ -889,9 +892,11 @@
         IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
         setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ true);
 
-        backupManagerService.requestBackup(mUserTwoId, packages, observer, monitor, /* flags */ 0);
+        backupManagerService.requestBackup(mUserTwoId, packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
 
-        verify(mUserTwoService).requestBackup(packages, observer, monitor, /* flags */ 0);
+        verify(mUserTwoService).requestBackup(packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
     }
 
     /** Test that the backup service routes methods correctly to the user that requests it. */
@@ -904,9 +909,11 @@
         IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
         setCallerAndGrantInteractUserPermission(mUserOneId, /* shouldGrantPermission */ false);
 
-        backupManagerService.requestBackup(mUserOneId, packages, observer, monitor, /* flags */ 0);
+        backupManagerService.requestBackup(mUserOneId, packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
 
-        verify(mUserOneService).requestBackup(packages, observer, monitor, /* flags */ 0);
+        verify(mUserOneService).requestBackup(packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
     }
 
     /** Test that the backup service routes methods correctly to the user that requests it. */
@@ -919,9 +926,11 @@
         IBackupManagerMonitor monitor = mock(IBackupManagerMonitor.class);
         setCallerAndGrantInteractUserPermission(mUserTwoId, /* shouldGrantPermission */ false);
 
-        backupManagerService.requestBackup(mUserTwoId, packages, observer, monitor, /* flags */ 0);
+        backupManagerService.requestBackup(mUserTwoId, packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
 
-        verify(mUserOneService, never()).requestBackup(packages, observer, monitor, /* flags */ 0);
+        verify(mUserOneService, never()).requestBackup(packages, observer, monitor, /* flags */ 0,
+                OperationType.BACKUP);
     }
 
     /**
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
index 33b8aa7..aa1c668 100644
--- a/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowAppBackupUtils.java
@@ -62,12 +62,13 @@
     }
 
     @Implementation
-    protected static boolean appIsEligibleForBackup(ApplicationInfo app, int userId) {
+    protected static boolean appIsEligibleForBackup(ApplicationInfo app, int userId,
+            int operationType) {
         return sAppsEligibleForBackup.contains(app.packageName);
     }
 
     @Implementation
-    protected static boolean appGetsFullBackup(PackageInfo packageInfo) {
+    protected static boolean appGetsFullBackup(PackageInfo packageInfo, int operationType) {
         return sAppsGetFullBackup.contains(packageInfo.packageName);
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 730f303..a462dc3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -39,6 +39,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.IActivityManager;
 import android.app.job.JobInfo;
+import android.app.job.JobScheduler;
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.ComponentName;
 import android.content.Context;
@@ -56,6 +57,7 @@
 import com.android.server.AppStateTracker;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
+import com.android.server.SystemServiceManager;
 import com.android.server.job.controllers.JobStatus;
 import com.android.server.usage.AppStandbyInternal;
 
@@ -82,6 +84,7 @@
     private class TestJobSchedulerService extends JobSchedulerService {
         TestJobSchedulerService(Context context) {
             super(context);
+            mAppStateTracker = mock(AppStateTracker.class);
         }
 
         @Override
@@ -136,6 +139,9 @@
         } catch (RemoteException e) {
             fail("registerUidObserver threw exception: " + e.getMessage());
         }
+        // Called by QuotaTracker
+        doReturn(mock(SystemServiceManager.class))
+                .when(() -> LocalServices.getService(SystemServiceManager.class));
 
         JobSchedulerService.sSystemClock = Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
         JobSchedulerService.sElapsedRealtimeClock =
@@ -750,4 +756,90 @@
         maybeQueueFunctor.postProcess();
         assertEquals(3, mService.mPendingJobs.size());
     }
+
+    /** Tests that jobs scheduled by the app itself are counted towards scheduling limits. */
+    @Test
+    public void testScheduleLimiting_RegularSchedule_Blocked() {
+        mService.mConstants.ENABLE_API_QUOTAS = true;
+        mService.mConstants.API_QUOTA_SCHEDULE_COUNT = 300;
+        mService.mConstants.API_QUOTA_SCHEDULE_WINDOW_MS = 300000;
+        mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+        mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = true;
+        mService.updateQuotaTracker();
+
+        final JobInfo job = createJobInfo().setPersisted(true).build();
+        for (int i = 0; i < 500; ++i) {
+            final int expected =
+                    i < 300 ? JobScheduler.RESULT_SUCCESS : JobScheduler.RESULT_FAILURE;
+            assertEquals("Got unexpected result for schedule #" + (i + 1),
+                    expected,
+                    mService.scheduleAsPackage(job, null, 10123, null, 0, ""));
+        }
+    }
+
+    /**
+     * Tests that jobs scheduled by the app itself succeed even if the app is above the scheduling
+     * limit.
+     */
+    @Test
+    public void testScheduleLimiting_RegularSchedule_Allowed() {
+        mService.mConstants.ENABLE_API_QUOTAS = true;
+        mService.mConstants.API_QUOTA_SCHEDULE_COUNT = 300;
+        mService.mConstants.API_QUOTA_SCHEDULE_WINDOW_MS = 300000;
+        mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+        mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false;
+        mService.updateQuotaTracker();
+
+        final JobInfo job = createJobInfo().setPersisted(true).build();
+        for (int i = 0; i < 500; ++i) {
+            assertEquals("Got unexpected result for schedule #" + (i + 1),
+                    JobScheduler.RESULT_SUCCESS,
+                    mService.scheduleAsPackage(job, null, 10123, null, 0, ""));
+        }
+    }
+
+    /**
+     * Tests that jobs scheduled through a proxy (eg. system server) don't count towards scheduling
+     * limits.
+     */
+    @Test
+    public void testScheduleLimiting_Proxy() {
+        mService.mConstants.ENABLE_API_QUOTAS = true;
+        mService.mConstants.API_QUOTA_SCHEDULE_COUNT = 300;
+        mService.mConstants.API_QUOTA_SCHEDULE_WINDOW_MS = 300000;
+        mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+        mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = true;
+        mService.updateQuotaTracker();
+
+        final JobInfo job = createJobInfo().setPersisted(true).build();
+        for (int i = 0; i < 500; ++i) {
+            assertEquals("Got unexpected result for schedule #" + (i + 1),
+                    JobScheduler.RESULT_SUCCESS,
+                    mService.scheduleAsPackage(job, null, 10123, "proxied.package", 0, ""));
+        }
+    }
+
+    /**
+     * Tests that jobs scheduled by an app for itself as if through a proxy are counted towards
+     * scheduling limits.
+     */
+    @Test
+    public void testScheduleLimiting_SelfProxy() {
+        mService.mConstants.ENABLE_API_QUOTAS = true;
+        mService.mConstants.API_QUOTA_SCHEDULE_COUNT = 300;
+        mService.mConstants.API_QUOTA_SCHEDULE_WINDOW_MS = 300000;
+        mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+        mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = true;
+        mService.updateQuotaTracker();
+
+        final JobInfo job = createJobInfo().setPersisted(true).build();
+        for (int i = 0; i < 500; ++i) {
+            final int expected =
+                    i < 300 ? JobScheduler.RESULT_SUCCESS : JobScheduler.RESULT_FAILURE;
+            assertEquals("Got unexpected result for schedule #" + (i + 1),
+                    expected,
+                    mService.scheduleAsPackage(job, null, 10123, job.getService().getPackageName(),
+                            0, ""));
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 5327bf7..cfa2086 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -91,6 +91,7 @@
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 
 import com.android.server.accessibility.AccessibilityWindowManager.RemoteAccessibilityConnection;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -167,7 +168,7 @@
     @Mock private IAccessibilityInteractionConnection mMockIA11yInteractionConnection;
     @Mock private IAccessibilityInteractionConnectionCallback mMockCallback;
     @Mock private FingerprintGestureDispatcher mMockFingerprintGestureDispatcher;
-    @Mock private MagnificationController mMockMagnificationController;
+    @Mock private FullScreenMagnificationController mMockFullScreenMagnificationController;
     @Mock private RemoteCallback.OnResultListener mMockListener;
 
     @Before
@@ -178,8 +179,8 @@
         when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher);
         when(mMockSystemSupport.getFingerprintGestureDispatcher())
                 .thenReturn(mMockFingerprintGestureDispatcher);
-        when(mMockSystemSupport.getMagnificationController())
-                .thenReturn(mMockMagnificationController);
+        when(mMockSystemSupport.getFullScreenMagnificationController())
+                .thenReturn(mMockFullScreenMagnificationController);
 
         PowerManager powerManager =
                 new PowerManager(mMockContext, mMockIPowerManager, mMockIThermalService, mHandler);
@@ -553,7 +554,7 @@
     public void getMagnificationScale() {
         final int displayId = 1;
         final float scale = 2.0f;
-        when(mMockMagnificationController.getScale(displayId)).thenReturn(scale);
+        when(mMockFullScreenMagnificationController.getScale(displayId)).thenReturn(scale);
 
         final float result = mServiceConnection.getMagnificationScale(displayId);
         assertThat(result, is(scale));
@@ -563,7 +564,7 @@
     public void getMagnificationScale_serviceNotBelongCurrentUser_returnNoScale() {
         final int displayId = 1;
         final float scale = 2.0f;
-        when(mMockMagnificationController.getScale(displayId)).thenReturn(scale);
+        when(mMockFullScreenMagnificationController.getScale(displayId)).thenReturn(scale);
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
         final float result = mServiceConnection.getMagnificationScale(displayId);
@@ -577,13 +578,14 @@
         doAnswer((invocation) -> {
             ((Region) invocation.getArguments()[1]).set(region);
             return null;
-        }).when(mMockMagnificationController).getMagnificationRegion(eq(displayId), any());
-        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+        }).when(mMockFullScreenMagnificationController).getMagnificationRegion(eq(displayId),
+                any());
+        when(mMockFullScreenMagnificationController.isRegistered(displayId)).thenReturn(false);
 
         final Region result = mServiceConnection.getMagnificationRegion(displayId);
         assertThat(result, is(region));
-        verify(mMockMagnificationController).register(displayId);
-        verify(mMockMagnificationController).unregister(displayId);
+        verify(mMockFullScreenMagnificationController).register(displayId);
+        verify(mMockFullScreenMagnificationController).unregister(displayId);
     }
 
     @Test
@@ -593,7 +595,8 @@
         doAnswer((invocation) -> {
             ((Region) invocation.getArguments()[1]).set(region);
             return null;
-        }).when(mMockMagnificationController).getMagnificationRegion(eq(displayId), any());
+        }).when(mMockFullScreenMagnificationController).getMagnificationRegion(eq(displayId),
+                any());
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
         final Region result = mServiceConnection.getMagnificationRegion(displayId);
@@ -604,20 +607,20 @@
     public void getMagnificationCenterX_notRegistered_shouldRegisterThenUnregister() {
         final int displayId = 1;
         final float centerX = 480.0f;
-        when(mMockMagnificationController.getCenterX(displayId)).thenReturn(centerX);
-        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+        when(mMockFullScreenMagnificationController.getCenterX(displayId)).thenReturn(centerX);
+        when(mMockFullScreenMagnificationController.isRegistered(displayId)).thenReturn(false);
 
         final float result = mServiceConnection.getMagnificationCenterX(displayId);
         assertThat(result, is(centerX));
-        verify(mMockMagnificationController).register(displayId);
-        verify(mMockMagnificationController).unregister(displayId);
+        verify(mMockFullScreenMagnificationController).register(displayId);
+        verify(mMockFullScreenMagnificationController).unregister(displayId);
     }
 
     @Test
     public void getMagnificationCenterX_serviceNotBelongCurrentUser_returnZero() {
         final int displayId = 1;
         final float centerX = 480.0f;
-        when(mMockMagnificationController.getCenterX(displayId)).thenReturn(centerX);
+        when(mMockFullScreenMagnificationController.getCenterX(displayId)).thenReturn(centerX);
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
         final float result = mServiceConnection.getMagnificationCenterX(displayId);
@@ -628,20 +631,20 @@
     public void getMagnificationCenterY_notRegistered_shouldRegisterThenUnregister() {
         final int displayId = 1;
         final float centerY = 640.0f;
-        when(mMockMagnificationController.getCenterY(displayId)).thenReturn(centerY);
-        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+        when(mMockFullScreenMagnificationController.getCenterY(displayId)).thenReturn(centerY);
+        when(mMockFullScreenMagnificationController.isRegistered(displayId)).thenReturn(false);
 
         final float result = mServiceConnection.getMagnificationCenterY(displayId);
         assertThat(result, is(centerY));
-        verify(mMockMagnificationController).register(displayId);
-        verify(mMockMagnificationController).unregister(displayId);
+        verify(mMockFullScreenMagnificationController).register(displayId);
+        verify(mMockFullScreenMagnificationController).unregister(displayId);
     }
 
     @Test
     public void getMagnificationCenterY_serviceNotBelongCurrentUser_returnZero() {
         final int displayId = 1;
         final float centerY = 640.0f;
-        when(mMockMagnificationController.getCenterY(displayId)).thenReturn(centerY);
+        when(mMockFullScreenMagnificationController.getCenterY(displayId)).thenReturn(centerY);
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
         final float result = mServiceConnection.getMagnificationCenterY(displayId);
@@ -651,7 +654,7 @@
     @Test
     public void resetMagnification() {
         final int displayId = 1;
-        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+        when(mMockFullScreenMagnificationController.reset(displayId, true)).thenReturn(true);
 
         final boolean result = mServiceConnection.resetMagnification(displayId, true);
         assertThat(result, is(true));
@@ -660,7 +663,7 @@
     @Test
     public void resetMagnification_cantControlMagnification_returnFalse() {
         final int displayId = 1;
-        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+        when(mMockFullScreenMagnificationController.reset(displayId, true)).thenReturn(true);
         when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false);
 
         final boolean result = mServiceConnection.resetMagnification(displayId, true);
@@ -670,7 +673,7 @@
     @Test
     public void resetMagnification_serviceNotBelongCurrentUser_returnFalse() {
         final int displayId = 1;
-        when(mMockMagnificationController.reset(displayId, true)).thenReturn(true);
+        when(mMockFullScreenMagnificationController.reset(displayId, true)).thenReturn(true);
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
         final boolean result = mServiceConnection.resetMagnification(displayId, true);
@@ -683,14 +686,14 @@
         final float scale = 1.8f;
         final float centerX = 50.5f;
         final float centerY = 100.5f;
-        when(mMockMagnificationController.setScaleAndCenter(displayId,
+        when(mMockFullScreenMagnificationController.setScaleAndCenter(displayId,
                 scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
-        when(mMockMagnificationController.isRegistered(displayId)).thenReturn(false);
+        when(mMockFullScreenMagnificationController.isRegistered(displayId)).thenReturn(false);
 
         final boolean result = mServiceConnection.setMagnificationScaleAndCenter(
                 displayId, scale, centerX, centerY, true);
         assertThat(result, is(true));
-        verify(mMockMagnificationController).register(displayId);
+        verify(mMockFullScreenMagnificationController).register(displayId);
     }
 
     @Test
@@ -699,7 +702,7 @@
         final float scale = 1.8f;
         final float centerX = 50.5f;
         final float centerY = 100.5f;
-        when(mMockMagnificationController.setScaleAndCenter(displayId,
+        when(mMockFullScreenMagnificationController.setScaleAndCenter(displayId,
                 scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
         when(mMockSecurityPolicy.canControlMagnification(mServiceConnection)).thenReturn(false);
 
@@ -714,7 +717,7 @@
         final float scale = 1.8f;
         final float centerX = 50.5f;
         final float centerY = 100.5f;
-        when(mMockMagnificationController.setScaleAndCenter(displayId,
+        when(mMockFullScreenMagnificationController.setScaleAndCenter(displayId,
                 scale, centerX, centerY, true, SERVICE_ID)).thenReturn(true);
         when(mMockSystemSupport.getCurrentUserIdLocked()).thenReturn(USER_ID2);
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
index e166935..4b2a9fc 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInputFilterTest.java
@@ -52,6 +52,8 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.accessibility.gestures.TouchExplorer;
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
+import com.android.server.accessibility.magnification.FullScreenMagnificationGestureHandler;
 import com.android.server.accessibility.magnification.MagnificationGestureHandler;
 import com.android.server.accessibility.magnification.WindowMagnificationGestureHandler;
 
@@ -89,7 +91,7 @@
                     FullScreenMagnificationGestureHandler.class, TouchExplorer.class,
                     AutoclickController.class, AccessibilityInputFilter.class};
 
-    private MagnificationController mMockMagnificationController;
+    private FullScreenMagnificationController mMockFullScreenMagnificationController;
     private AccessibilityManagerService mAms;
     private AccessibilityInputFilter mA11yInputFilter;
     private EventCaptor mCaptor1;
@@ -135,12 +137,13 @@
 
         setDisplayCount(1);
         mAms = spy(new AccessibilityManagerService(context));
-        mMockMagnificationController = mock(MagnificationController.class);
+        mMockFullScreenMagnificationController = mock(FullScreenMagnificationController.class);
         mA11yInputFilter = new AccessibilityInputFilter(context, mAms, mEventHandler);
         mA11yInputFilter.onInstalled();
 
         when(mAms.getValidDisplayList()).thenReturn(mDisplayList);
-        when(mAms.getMagnificationController()).thenReturn(mMockMagnificationController);
+        when(mAms.getFullScreenMagnificationController()).thenReturn(
+                mMockFullScreenMagnificationController);
     }
 
     @After
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index b6cf278..27edfd4 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -44,6 +44,7 @@
 import android.testing.DexmakerShareClassLoaderRule;
 import android.view.Display;
 
+import com.android.server.accessibility.magnification.FullScreenMagnificationController;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
@@ -87,7 +88,8 @@
     @Mock WindowManagerInternal mMockWindowManagerInternal;
     @Mock SystemActionPerformer mMockSystemActionPerformer;
     @Mock KeyEventDispatcher mMockKeyEventDispatcher;
-    @Mock MagnificationController mMockMagnificationController;
+    @Mock
+    FullScreenMagnificationController mMockFullScreenMagnificationController;
     @Mock IBinder mMockIBinder;
     @Mock IAccessibilityServiceClient mMockServiceClient;
     @Mock MotionEventInjector mMockMotionEventInjector;
@@ -98,8 +100,8 @@
     public void setup() {
         MockitoAnnotations.initMocks(this);
         when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher);
-        when(mMockSystemSupport.getMagnificationController())
-                .thenReturn(mMockMagnificationController);
+        when(mMockSystemSupport.getFullScreenMagnificationController())
+                .thenReturn(mMockFullScreenMagnificationController);
         when(mMockSystemSupport.getMotionEventInjectorForDisplayLocked(
                 Display.DEFAULT_DISPLAY)).thenReturn(mMockMotionEventInjector);
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
similarity index 82%
rename from services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
rename to services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
index 82c6498..a9f2e4a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.accessibility;
+package com.android.server.accessibility.magnification;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -47,6 +47,7 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accessibility.test.MessageCapturingHandler;
 import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.WindowManagerInternal.MagnificationCallbacks;
@@ -66,7 +67,7 @@
 import java.util.Locale;
 
 @RunWith(AndroidJUnit4.class)
-public class MagnificationControllerTest {
+public class FullScreenMagnificationControllerTest {
     static final Rect INITIAL_MAGNIFICATION_BOUNDS = new Rect(0, 0, 100, 200);
     static final PointF INITIAL_MAGNIFICATION_BOUNDS_CENTER = new PointF(
             INITIAL_MAGNIFICATION_BOUNDS.centerX(), INITIAL_MAGNIFICATION_BOUNDS.centerY());
@@ -85,8 +86,8 @@
     static final int DISPLAY_COUNT = 2;
     static final int INVALID_DISPLAY = 2;
 
-    final MagnificationController.ControllerContext mMockControllerCtx =
-            mock(MagnificationController.ControllerContext.class);
+    final FullScreenMagnificationController.ControllerContext mMockControllerCtx =
+            mock(FullScreenMagnificationController.ControllerContext.class);
     final Context mMockContext = mock(Context.class);
     final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
     final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
@@ -95,7 +96,7 @@
     ValueAnimator mMockValueAnimator;
     ValueAnimator.AnimatorUpdateListener mTargetAnimationListener;
 
-    MagnificationController mMagnificationController;
+    FullScreenMagnificationController mFullScreenMagnificationController;
 
     @Before
     public void setUp() {
@@ -109,7 +110,8 @@
         when(mMockControllerCtx.getAnimationDuration()).thenReturn(1000L);
         initMockWindowManager();
 
-        mMagnificationController = new MagnificationController(mMockControllerCtx, new Object());
+        mFullScreenMagnificationController = new FullScreenMagnificationController(
+                mMockControllerCtx, new Object());
     }
 
     @After
@@ -131,23 +133,23 @@
                 eq(DISPLAY_1), (MagnificationCallbacks) anyObject());
         verify(mMockWindowManager).setMagnificationCallbacks(
                 eq(INVALID_DISPLAY), (MagnificationCallbacks) anyObject());
-        assertTrue(mMagnificationController.isRegistered(DISPLAY_0));
-        assertTrue(mMagnificationController.isRegistered(DISPLAY_1));
-        assertFalse(mMagnificationController.isRegistered(INVALID_DISPLAY));
+        assertTrue(mFullScreenMagnificationController.isRegistered(DISPLAY_0));
+        assertTrue(mFullScreenMagnificationController.isRegistered(DISPLAY_1));
+        assertFalse(mFullScreenMagnificationController.isRegistered(INVALID_DISPLAY));
     }
 
     @Test
     public void testRegister_WindowManagerAndContextUnregisterListeners() {
         register(DISPLAY_0);
         register(DISPLAY_1);
-        mMagnificationController.unregister(DISPLAY_0);
+        mFullScreenMagnificationController.unregister(DISPLAY_0);
         verify(mMockContext, times(0)).unregisterReceiver((BroadcastReceiver) anyObject());
-        mMagnificationController.unregister(DISPLAY_1);
+        mFullScreenMagnificationController.unregister(DISPLAY_1);
         verify(mMockContext).unregisterReceiver((BroadcastReceiver) anyObject());
         verify(mMockWindowManager).setMagnificationCallbacks(eq(DISPLAY_0), eq(null));
         verify(mMockWindowManager).setMagnificationCallbacks(eq(DISPLAY_1), eq(null));
-        assertFalse(mMagnificationController.isRegistered(DISPLAY_0));
-        assertFalse(mMagnificationController.isRegistered(DISPLAY_1));
+        assertFalse(mFullScreenMagnificationController.isRegistered(DISPLAY_0));
+        assertFalse(mFullScreenMagnificationController.isRegistered(DISPLAY_1));
     }
 
     @Test
@@ -166,14 +168,14 @@
         Rect initialBounds = new Rect();
 
         assertEquals(expectedInitialSpec, getCurrentMagnificationSpec(displayId));
-        mMagnificationController.getMagnificationRegion(displayId, initialMagRegion);
-        mMagnificationController.getMagnificationBounds(displayId, initialBounds);
+        mFullScreenMagnificationController.getMagnificationRegion(displayId, initialMagRegion);
+        mFullScreenMagnificationController.getMagnificationBounds(displayId, initialBounds);
         assertEquals(INITIAL_MAGNIFICATION_REGION, initialMagRegion);
         assertEquals(INITIAL_MAGNIFICATION_BOUNDS, initialBounds);
         assertEquals(INITIAL_MAGNIFICATION_BOUNDS.centerX(),
-                mMagnificationController.getCenterX(displayId), 0.0f);
+                mFullScreenMagnificationController.getCenterX(displayId), 0.0f);
         assertEquals(INITIAL_MAGNIFICATION_BOUNDS.centerY(),
-                mMagnificationController.getCenterY(displayId), 0.0f);
+                mFullScreenMagnificationController.getCenterY(displayId), 0.0f);
     }
 
     @Test
@@ -185,24 +187,26 @@
     }
 
     private void notRegistered_publicMethodsShouldBeBenign(int displayId) {
-        assertFalse(mMagnificationController.isMagnifying(displayId));
-        assertFalse(mMagnificationController.magnificationRegionContains(displayId, 100, 100));
-        assertFalse(mMagnificationController.reset(displayId, true));
-        assertFalse(mMagnificationController.setScale(displayId, 2, 100, 100, true, 0));
-        assertFalse(mMagnificationController.setCenter(displayId, 100, 100, false, 1));
-        assertFalse(mMagnificationController.setScaleAndCenter(displayId,
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
+        assertFalse(
+                mFullScreenMagnificationController.magnificationRegionContains(displayId, 100,
+                        100));
+        assertFalse(mFullScreenMagnificationController.reset(displayId, true));
+        assertFalse(mFullScreenMagnificationController.setScale(displayId, 2, 100, 100, true, 0));
+        assertFalse(mFullScreenMagnificationController.setCenter(displayId, 100, 100, false, 1));
+        assertFalse(mFullScreenMagnificationController.setScaleAndCenter(displayId,
                 1.5f, 100, 100, false, 2));
-        assertTrue(mMagnificationController.getIdOfLastServiceToMagnify(displayId) < 0);
+        assertTrue(mFullScreenMagnificationController.getIdOfLastServiceToMagnify(displayId) < 0);
 
-        mMagnificationController.getMagnificationRegion(displayId, new Region());
-        mMagnificationController.getMagnificationBounds(displayId, new Rect());
-        mMagnificationController.getScale(displayId);
-        mMagnificationController.getOffsetX(displayId);
-        mMagnificationController.getOffsetY(displayId);
-        mMagnificationController.getCenterX(displayId);
-        mMagnificationController.getCenterY(displayId);
-        mMagnificationController.offsetMagnifiedRegion(displayId, 50, 50, 1);
-        mMagnificationController.unregister(displayId);
+        mFullScreenMagnificationController.getMagnificationRegion(displayId, new Region());
+        mFullScreenMagnificationController.getMagnificationBounds(displayId, new Rect());
+        mFullScreenMagnificationController.getScale(displayId);
+        mFullScreenMagnificationController.getOffsetX(displayId);
+        mFullScreenMagnificationController.getOffsetY(displayId);
+        mFullScreenMagnificationController.getCenterX(displayId);
+        mFullScreenMagnificationController.getCenterY(displayId);
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId, 50, 50, 1);
+        mFullScreenMagnificationController.unregister(displayId);
     }
 
     @Test
@@ -218,7 +222,7 @@
         final float scale = 2.0f;
         final PointF center = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
         final PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, center, scale);
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScale(displayId, scale, center.x, center.y, false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
@@ -226,8 +230,8 @@
         verify(mMockWindowManager).setMagnificationSpec(
                 eq(displayId), argThat(closeTo(expectedSpec)));
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(expectedSpec));
-        assertEquals(center.x, mMagnificationController.getCenterX(displayId), 0.0);
-        assertEquals(center.y, mMagnificationController.getCenterY(displayId), 0.0);
+        assertEquals(center.x, mFullScreenMagnificationController.getCenterX(displayId), 0.0);
+        assertEquals(center.y, mFullScreenMagnificationController.getCenterY(displayId), 0.0);
         verify(mMockValueAnimator, times(0)).start();
     }
 
@@ -244,7 +248,7 @@
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
         float scale = 2.0f;
         PointF pivotPoint = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScale(displayId, scale, pivotPoint.x, pivotPoint.y, true, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
@@ -254,8 +258,8 @@
         PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
         MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
 
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(endSpec));
         verify(mMockValueAnimator).start();
 
@@ -291,13 +295,13 @@
         register(displayId);
         // First zoom in
         float scale = 2.0f;
-        assertTrue(mMagnificationController.setScale(displayId, scale,
+        assertTrue(mFullScreenMagnificationController.setScale(displayId, scale,
                 INITIAL_MAGNIFICATION_BOUNDS.centerX(), INITIAL_MAGNIFICATION_BOUNDS.centerY(),
                 false, SERVICE_ID_1));
         Mockito.reset(mMockWindowManager);
 
         PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setCenter(displayId, newCenter.x, newCenter.y, false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
         PointF expectedOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
@@ -305,8 +309,8 @@
 
         verify(mMockWindowManager).setMagnificationSpec(
                 eq(displayId), argThat(closeTo(expectedSpec)));
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.0);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.0);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.0);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.0);
         verify(mMockValueAnimator, times(0)).start();
     }
 
@@ -326,12 +330,12 @@
         PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
         MagnificationSpec endSpec = getMagnificationSpec(scale, offsets);
 
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId, scale, newCenter.x,
-                newCenter.y, true, SERVICE_ID_1));
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, scale,
+                newCenter.x, newCenter.y, true, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(endSpec));
         verify(mMockAms).notifyMagnificationChanged(displayId,
                 INITIAL_MAGNIFICATION_REGION, scale, newCenter.x, newCenter.y);
@@ -370,30 +374,30 @@
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
         PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
         PointF offsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter,
-                MagnificationController.MAX_SCALE);
+                FullScreenMagnificationController.MAX_SCALE);
         MagnificationSpec endSpec = getMagnificationSpec(
-                MagnificationController.MAX_SCALE, offsets);
+                FullScreenMagnificationController.MAX_SCALE, offsets);
 
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId,
-                MagnificationController.MAX_SCALE + 1.0f,
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
+                FullScreenMagnificationController.MAX_SCALE + 1.0f,
                 newCenter.x, newCenter.y, false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(endSpec)));
         Mockito.reset(mMockWindowManager);
 
         // Verify that we can't zoom below 1x
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId, 0.5f,
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, 0.5f,
                 INITIAL_MAGNIFICATION_BOUNDS_CENTER.x, INITIAL_MAGNIFICATION_BOUNDS_CENTER.y,
                 false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
         assertEquals(INITIAL_MAGNIFICATION_BOUNDS_CENTER.x,
-                mMagnificationController.getCenterX(displayId), 0.5);
+                mFullScreenMagnificationController.getCenterX(displayId), 0.5);
         assertEquals(INITIAL_MAGNIFICATION_BOUNDS_CENTER.y,
-                mMagnificationController.getCenterY(displayId), 0.5);
+                mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(startSpec)));
     }
 
@@ -410,27 +414,27 @@
         float scale = 2.0f;
 
         // Off the edge to the top and left
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId,
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
                 scale, -100f, -200f, false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
         PointF newCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
         PointF newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId),
                 argThat(closeTo(getMagnificationSpec(scale, newOffsets))));
         Mockito.reset(mMockWindowManager);
 
         // Off the edge to the bottom and right
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId, scale,
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId, scale,
                 INITIAL_MAGNIFICATION_BOUNDS.right + 1, INITIAL_MAGNIFICATION_BOUNDS.bottom + 1,
                 false, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
         newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
         newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId),
                 argThat(closeTo(getMagnificationSpec(scale, newOffsets))));
     }
@@ -466,7 +470,7 @@
         float scale = 2.0f;
         PointF startOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, startCenter, scale);
         // First zoom in
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScaleAndCenter(displayId, scale, startCenter.x, startCenter.y, false,
                         SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
@@ -474,7 +478,7 @@
 
         PointF newCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
         PointF newOffsets = computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale);
-        mMagnificationController.offsetMagnifiedRegion(displayId,
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId,
                 startOffsets.x - newOffsets.x, startOffsets.y - newOffsets.y,
                 SERVICE_ID_1);
         mMessageCapturingHandler.sendAllMessages();
@@ -482,8 +486,8 @@
         MagnificationSpec expectedSpec = getMagnificationSpec(scale, newOffsets);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId),
                 argThat(closeTo(expectedSpec)));
-        assertEquals(newCenter.x, mMagnificationController.getCenterX(displayId), 0.0);
-        assertEquals(newCenter.y, mMagnificationController.getCenterY(displayId), 0.0);
+        assertEquals(newCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.0);
+        assertEquals(newCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.0);
         verify(mMockValueAnimator, times(0)).start();
     }
 
@@ -499,9 +503,9 @@
         register(displayId);
         Mockito.reset(mMockWindowManager);
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
-        mMagnificationController.offsetMagnifiedRegion(displayId, 10, 10, SERVICE_ID_1);
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId, 10, 10, SERVICE_ID_1);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(startSpec));
-        mMagnificationController.offsetMagnifiedRegion(displayId, -10, -10, SERVICE_ID_1);
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId, -10, -10, SERVICE_ID_1);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(startSpec));
         verifyNoMoreInteractions(mMockWindowManager);
     }
@@ -520,24 +524,24 @@
 
         // Upper left edges
         PointF ulCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScaleAndCenter(displayId, scale, ulCenter.x, ulCenter.y, false,
                         SERVICE_ID_1));
         Mockito.reset(mMockWindowManager);
         MagnificationSpec ulSpec = getCurrentMagnificationSpec(displayId);
-        mMagnificationController.offsetMagnifiedRegion(displayId, -10, -10,
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId, -10, -10,
                 SERVICE_ID_1);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(ulSpec));
         verifyNoMoreInteractions(mMockWindowManager);
 
         // Lower right edges
         PointF lrCenter = INITIAL_BOUNDS_LOWER_RIGHT_2X_CENTER;
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScaleAndCenter(displayId, scale, lrCenter.x, lrCenter.y, false,
                         SERVICE_ID_1));
         Mockito.reset(mMockWindowManager);
         MagnificationSpec lrSpec = getCurrentMagnificationSpec(displayId);
-        mMagnificationController.offsetMagnifiedRegion(displayId, 10, 10,
+        mFullScreenMagnificationController.offsetMagnifiedRegion(displayId, 10, 10,
                 SERVICE_ID_1);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(lrSpec));
         verifyNoMoreInteractions(mMockWindowManager);
@@ -554,14 +558,16 @@
     private void getIdOfLastServiceToChange_returnsCorrectValue(int displayId) {
         register(displayId);
         PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
-        assertTrue(mMagnificationController
+        assertTrue(mFullScreenMagnificationController
                 .setScale(displayId, 2.0f, startCenter.x, startCenter.y, false,
                         SERVICE_ID_1));
-        assertEquals(SERVICE_ID_1, mMagnificationController.getIdOfLastServiceToMagnify(displayId));
-        assertTrue(mMagnificationController
+        assertEquals(SERVICE_ID_1,
+                mFullScreenMagnificationController.getIdOfLastServiceToMagnify(displayId));
+        assertTrue(mFullScreenMagnificationController
                 .setScale(displayId, 1.5f, startCenter.x, startCenter.y, false,
                         SERVICE_ID_2));
-        assertEquals(SERVICE_ID_2, mMagnificationController.getIdOfLastServiceToMagnify(displayId));
+        assertEquals(SERVICE_ID_2,
+                mFullScreenMagnificationController.getIdOfLastServiceToMagnify(displayId));
     }
 
     @Test
@@ -575,16 +581,16 @@
     private void resetIfNeeded_resetsOnlyIfLastMagnifyingServiceIsDisabled(int displayId) {
         register(displayId);
         PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
-        mMagnificationController
+        mFullScreenMagnificationController
                 .setScale(displayId, 2.0f, startCenter.x, startCenter.y, false,
                         SERVICE_ID_1);
-        mMagnificationController
+        mFullScreenMagnificationController
                 .setScale(displayId, 1.5f, startCenter.x, startCenter.y, false,
                         SERVICE_ID_2);
-        assertFalse(mMagnificationController.resetIfNeeded(displayId, SERVICE_ID_1));
-        assertTrue(mMagnificationController.isMagnifying(displayId));
-        assertTrue(mMagnificationController.resetIfNeeded(displayId, SERVICE_ID_2));
-        assertFalse(mMagnificationController.isMagnifying(displayId));
+        assertFalse(mFullScreenMagnificationController.resetIfNeeded(displayId, SERVICE_ID_1));
+        assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
+        assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, SERVICE_ID_2));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
     }
 
     @Test
@@ -600,16 +606,16 @@
         final int userId2 = 2;
 
         register(displayId);
-        mMagnificationController.setUserId(userId1);
+        mFullScreenMagnificationController.setUserId(userId1);
         PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
         float scale = 2.0f;
-        mMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y, false,
-                SERVICE_ID_1);
+        mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
+                false, SERVICE_ID_1);
 
-        mMagnificationController.setUserId(userId1);
-        assertTrue(mMagnificationController.isMagnifying(displayId));
-        mMagnificationController.setUserId(userId2);
-        assertFalse(mMagnificationController.isMagnifying(displayId));
+        mFullScreenMagnificationController.setUserId(userId1);
+        assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
+        mFullScreenMagnificationController.setUserId(userId2);
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
     }
 
     @Test
@@ -625,11 +631,11 @@
         zoomIn2xToMiddle(displayId);
         mMessageCapturingHandler.sendAllMessages();
         reset(mMockAms);
-        assertTrue(mMagnificationController.resetIfNeeded(displayId, false));
+        assertTrue(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
         verify(mMockAms).notifyMagnificationChanged(eq(displayId),
                 eq(INITIAL_MAGNIFICATION_REGION), eq(1.0f), anyFloat(), anyFloat());
-        assertFalse(mMagnificationController.isMagnifying(displayId));
-        assertFalse(mMagnificationController.resetIfNeeded(displayId, false));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
+        assertFalse(mFullScreenMagnificationController.resetIfNeeded(displayId, false));
     }
 
     @Test
@@ -646,8 +652,8 @@
         mMessageCapturingHandler.sendAllMessages();
         br.onReceive(mMockContext, null);
         mMessageCapturingHandler.sendAllMessages();
-        assertFalse(mMagnificationController.isMagnifying(DISPLAY_0));
-        assertFalse(mMagnificationController.isMagnifying(DISPLAY_1));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_0));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(DISPLAY_1));
     }
 
     @Test
@@ -665,7 +671,7 @@
         mMessageCapturingHandler.sendAllMessages();
         callbacks.onUserContextChanged();
         mMessageCapturingHandler.sendAllMessages();
-        assertFalse(mMagnificationController.isMagnifying(displayId));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
     }
 
     @Test
@@ -681,10 +687,10 @@
         MagnificationCallbacks callbacks = getMagnificationCallbacks(displayId);
         zoomIn2xToMiddle(displayId);
         mMessageCapturingHandler.sendAllMessages();
-        assertTrue(mMagnificationController.isMagnifying(displayId));
+        assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
         callbacks.onRotationChanged(0);
         mMessageCapturingHandler.sendAllMessages();
-        assertFalse(mMagnificationController.isMagnifying(displayId));
+        assertFalse(mFullScreenMagnificationController.isMagnifying(displayId));
     }
 
     @Test
@@ -722,8 +728,8 @@
         PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
         float scale = 2.0f;
         // setting animate parameter to true is differ from zoomIn2xToMiddle()
-        mMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y, true,
-                SERVICE_ID_1);
+        mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
+                true, SERVICE_ID_1);
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
         MagnificationCallbacks callbacks = getMagnificationCallbacks(displayId);
         Mockito.reset(mMockWindowManager);
@@ -750,8 +756,8 @@
         mMessageCapturingHandler.sendAllMessages();
         PointF startCenter = OTHER_BOUNDS_LOWER_RIGHT_2X_CENTER;
         float scale = 2.0f;
-        mMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y, false,
-                SERVICE_ID_1);
+        mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
+                false, SERVICE_ID_1);
         mMessageCapturingHandler.sendAllMessages();
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
         verify(mMockWindowManager).setMagnificationSpec(eq(displayId), argThat(closeTo(startSpec)));
@@ -784,8 +790,8 @@
         mMessageCapturingHandler.sendAllMessages();
         PointF startCenter = OTHER_BOUNDS_LOWER_RIGHT_2X_CENTER;
         float scale = 2.0f;
-        mMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y, true,
-                SERVICE_ID_1);
+        mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
+                true, SERVICE_ID_1);
         mMessageCapturingHandler.sendAllMessages();
         MagnificationSpec startSpec = getCurrentMagnificationSpec(displayId);
         when(mMockValueAnimator.isRunning()).thenReturn(true);
@@ -947,12 +953,12 @@
         MagnificationSpec firstEndSpec = getMagnificationSpec(
                 scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, firstCenter, scale));
 
-        assertTrue(mMagnificationController.setScaleAndCenter(displayId,
+        assertTrue(mFullScreenMagnificationController.setScaleAndCenter(displayId,
                 scale, firstCenter.x, firstCenter.y, true, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
-        assertEquals(firstCenter.x, mMagnificationController.getCenterX(displayId), 0.5);
-        assertEquals(firstCenter.y, mMagnificationController.getCenterY(displayId), 0.5);
+        assertEquals(firstCenter.x, mFullScreenMagnificationController.getCenterX(displayId), 0.5);
+        assertEquals(firstCenter.y, mFullScreenMagnificationController.getCenterY(displayId), 0.5);
         assertThat(getCurrentMagnificationSpec(displayId), closeTo(firstEndSpec));
         verify(mMockValueAnimator, times(1)).start();
 
@@ -977,7 +983,7 @@
         PointF newCenter = INITIAL_BOUNDS_UPPER_LEFT_2X_CENTER;
         MagnificationSpec newEndSpec = getMagnificationSpec(
                 scale, computeOffsets(INITIAL_MAGNIFICATION_BOUNDS, newCenter, scale));
-        assertTrue(mMagnificationController.setCenter(displayId,
+        assertTrue(mFullScreenMagnificationController.setCenter(displayId,
                 newCenter.x, newCenter.y, true, SERVICE_ID_1));
         mMessageCapturingHandler.sendAllMessages();
 
@@ -1032,7 +1038,7 @@
     private void register(int displayId) {
         mMockValueAnimator = mock(ValueAnimator.class);
         when(mMockControllerCtx.newValueAnimator()).thenReturn(mMockValueAnimator);
-        mMagnificationController.register(displayId);
+        mFullScreenMagnificationController.register(displayId);
         ArgumentCaptor<ValueAnimator.AnimatorUpdateListener> listenerArgumentCaptor =
                 ArgumentCaptor.forClass(ValueAnimator.AnimatorUpdateListener.class);
         verify(mMockValueAnimator).addUpdateListener(listenerArgumentCaptor.capture());
@@ -1043,9 +1049,9 @@
     private void zoomIn2xToMiddle(int displayId) {
         PointF startCenter = INITIAL_MAGNIFICATION_BOUNDS_CENTER;
         float scale = 2.0f;
-        mMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y, false,
-                SERVICE_ID_1);
-        assertTrue(mMagnificationController.isMagnifying(displayId));
+        mFullScreenMagnificationController.setScale(displayId, scale, startCenter.x, startCenter.y,
+                false, SERVICE_ID_1);
+        assertTrue(mFullScreenMagnificationController.isMagnifying(displayId));
     }
 
     private MagnificationCallbacks getMagnificationCallbacks(int displayId) {
@@ -1084,9 +1090,9 @@
     }
 
     private MagnificationSpec getCurrentMagnificationSpec(int displayId) {
-        return getMagnificationSpec(mMagnificationController.getScale(displayId),
-                mMagnificationController.getOffsetX(displayId),
-                mMagnificationController.getOffsetY(displayId));
+        return getMagnificationSpec(mFullScreenMagnificationController.getScale(displayId),
+                mFullScreenMagnificationController.getOffsetX(displayId),
+                mFullScreenMagnificationController.getOffsetY(displayId));
     }
 
     private MagSpecMatcher closeTo(MagnificationSpec spec) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
similarity index 96%
rename from services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java
rename to services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
index 3678d544..008cbed 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/FullScreenMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.server.accessibility;
+package com.android.server.accessibility.magnification;
 
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.MotionEvent.ACTION_MOVE;
@@ -51,6 +51,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.accessibility.AccessibilityManagerService;
+import com.android.server.accessibility.EventStreamTransformation;
 import com.android.server.accessibility.magnification.MagnificationGestureHandler.ScaleChangedListener;
 import com.android.server.testutils.OffsettableClock;
 import com.android.server.testutils.TestHandler;
@@ -121,7 +123,7 @@
     private static final int DISPLAY_0 = 0;
 
     private Context mContext;
-    MagnificationController mMagnificationController;
+    FullScreenMagnificationController mFullScreenMagnificationController;
     @Mock
     ScaleChangedListener mMockScaleChangedListener;
 
@@ -135,8 +137,8 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = InstrumentationRegistry.getContext();
-        final MagnificationController.ControllerContext mockController =
-                mock(MagnificationController.ControllerContext.class);
+        final FullScreenMagnificationController.ControllerContext mockController =
+                mock(FullScreenMagnificationController.ControllerContext.class);
         final WindowManagerInternal mockWindowManager = mock(WindowManagerInternal.class);
         when(mockController.getContext()).thenReturn(mContext);
         when(mockController.getAms()).thenReturn(mock(AccessibilityManagerService.class));
@@ -145,7 +147,8 @@
         when(mockController.newValueAnimator()).thenReturn(new ValueAnimator());
         when(mockController.getAnimationDuration()).thenReturn(1000L);
         when(mockWindowManager.setMagnificationCallbacks(eq(DISPLAY_0), any())).thenReturn(true);
-        mMagnificationController = new MagnificationController(mockController, new Object()) {
+        mFullScreenMagnificationController = new FullScreenMagnificationController(mockController,
+                new Object()) {
             @Override
             public boolean magnificationRegionContains(int displayId, float x, float y) {
                 return true;
@@ -154,7 +157,7 @@
             @Override
             void setForceShowMagnifiableBounds(int displayId, boolean show) {}
         };
-        mMagnificationController.register(DISPLAY_0);
+        mFullScreenMagnificationController.register(DISPLAY_0);
         mClock = new OffsettableClock.Stopped();
 
         boolean detectTripleTap = true;
@@ -164,14 +167,14 @@
 
     @After
     public void tearDown() {
-        mMagnificationController.unregister(DISPLAY_0);
+        mFullScreenMagnificationController.unregister(DISPLAY_0);
     }
 
     @NonNull
     private FullScreenMagnificationGestureHandler newInstance(boolean detectTripleTap,
             boolean detectShortcutTrigger) {
         FullScreenMagnificationGestureHandler h = new FullScreenMagnificationGestureHandler(
-                mContext, mMagnificationController, mMockScaleChangedListener,
+                mContext, mFullScreenMagnificationController, mMockScaleChangedListener,
                 detectTripleTap, detectShortcutTrigger, DISPLAY_0);
         mHandler = new TestHandler(h.mDetectingState, mClock) {
             @Override
@@ -653,7 +656,7 @@
     }
 
     private boolean isZoomed() {
-        return mMgh.mMagnificationController.isMagnifying(DISPLAY_0);
+        return mMgh.mFullScreenMagnificationController.isMagnifying(DISPLAY_0);
     }
 
     private int tapCount() {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
index c9e6284..70e6a34 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationManagerTest.java
@@ -32,7 +32,10 @@
 
 import static java.lang.Float.NaN;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.IBinder;
@@ -300,6 +303,26 @@
         assertFalse(mWindowMagnificationManager.isConnected());
     }
 
+    @Test
+    public void requestConnection_registerAndUnregisterBroadcastReceiver() {
+        assertTrue(mWindowMagnificationManager.requestConnection(true));
+        verify(mContext).registerReceiver(any(BroadcastReceiver.class),  any(IntentFilter.class));
+
+        assertTrue(mWindowMagnificationManager.requestConnection(false));
+        verify(mContext).unregisterReceiver(any(BroadcastReceiver.class));
+    }
+
+    @Test
+    public void onReceiveScreenOff_removeMagnificationButtonAndDisableWindowMagnification()
+            throws RemoteException {
+        mWindowMagnificationManager.requestConnection(true);
+        mWindowMagnificationManager.mScreenStateReceiver.onReceive(mContext,
+                new Intent(Intent.ACTION_SCREEN_OFF));
+
+        verify(mMockConnection.getConnection()).removeMagnificationButton(TEST_DISPLAY);
+        verify(mMockConnection.getConnection()).disableWindowMagnification(TEST_DISPLAY);
+    }
+
     private MotionEvent generatePointersDownEvent(PointF[] pointersLocation) {
         final int len = pointersLocation.length;
 
diff --git a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
index 3ebc315..ccb2ea3 100644
--- a/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/UserBackupManagerServiceTest.java
@@ -18,11 +18,25 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.when;
+
+import android.app.backup.BackupManager.OperationType;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.backup.internal.OnTaskFinishedListener;
+import com.android.server.backup.params.BackupParams;
+import com.android.server.backup.transport.TransportClient;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -32,15 +46,25 @@
 @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class UserBackupManagerServiceTest {
+    private static final String TEST_PACKAGE = "package1";
+    private static final String[] TEST_PACKAGES = new String[] { TEST_PACKAGE };
+
     @Mock Context mContext;
+    @Mock IBackupManagerMonitor mBackupManagerMonitor;
+    @Mock IBackupObserver mBackupObserver;
+    @Mock PackageManager mPackageManager;
+    @Mock TransportClient mTransportClient;
+
 
     private TestBackupService mService;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
-        mService = new TestBackupService(mContext);
+        mService = new TestBackupService(mContext, mPackageManager);
+        mService.setEnabled(true);
+        mService.setSetupComplete(true);
     }
 
     @Test
@@ -57,11 +81,72 @@
         assertThat(mService.isEnabledStatePersisted).isTrue();
     }
 
+    @Test
+    public void getRequestBackupParams_isMigrationAndAppGetsFullBackup() throws Exception {
+        when(mPackageManager.getPackageInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(
+                getPackageInfo(TEST_PACKAGE));
+        mService.mAppIsEligibleForBackup = true;
+        mService.mAppGetsFullBackup = true;
+
+        BackupParams params = mService.getRequestBackupParams(TEST_PACKAGES, mBackupObserver,
+                mBackupManagerMonitor, /* flags */ 0, OperationType.MIGRATION,
+                mTransportClient, /* transportDirName */ "", OnTaskFinishedListener.NOP);
+
+        assertThat(params.kvPackages).isEmpty();
+        assertThat(params.fullPackages).contains(TEST_PACKAGE);
+        assertThat(params.operationType).isEqualTo(OperationType.MIGRATION);
+        assertThat(mService.mOperationType).isEqualTo(OperationType.MIGRATION);
+    }
+
+    @Test
+    public void getRequestBackupParams_isMigrationAndAppGetsKeyValueBackup() throws Exception {
+        when(mPackageManager.getPackageInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(
+                getPackageInfo(TEST_PACKAGE));
+        mService.mAppIsEligibleForBackup = true;
+        mService.mAppGetsFullBackup = false;
+
+        BackupParams params = mService.getRequestBackupParams(TEST_PACKAGES, mBackupObserver,
+                mBackupManagerMonitor, /* flags */ 0, OperationType.MIGRATION,
+                mTransportClient, /* transportDirName */ "", OnTaskFinishedListener.NOP);
+
+        assertThat(params.kvPackages).contains(TEST_PACKAGE);
+        assertThat(params.fullPackages).isEmpty();
+        assertThat(params.operationType).isEqualTo(OperationType.MIGRATION);
+        assertThat(mService.mOperationType).isEqualTo(OperationType.MIGRATION);
+    }
+
+    @Test
+    public void getRequestBackupParams_isMigrationAndAppNotEligibleForBackup() throws Exception {
+        when(mPackageManager.getPackageInfoAsUser(anyString(), anyInt(), anyInt())).thenReturn(
+                getPackageInfo(TEST_PACKAGE));
+        mService.mAppIsEligibleForBackup = false;
+        mService.mAppGetsFullBackup = false;
+
+        BackupParams params = mService.getRequestBackupParams(TEST_PACKAGES, mBackupObserver,
+                mBackupManagerMonitor, /* flags */ 0, OperationType.MIGRATION,
+                mTransportClient, /* transportDirName */ "", OnTaskFinishedListener.NOP);
+
+        assertThat(params.kvPackages).isEmpty();
+        assertThat(params.fullPackages).isEmpty();
+        assertThat(params.operationType).isEqualTo(OperationType.MIGRATION);
+        assertThat(mService.mOperationType).isEqualTo(OperationType.MIGRATION);
+    }
+
+    private static PackageInfo getPackageInfo(String packageName) {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = new ApplicationInfo();
+        packageInfo.packageName = packageName;
+        return packageInfo;
+    }
+
     private static class TestBackupService extends UserBackupManagerService {
         boolean isEnabledStatePersisted = false;
+        boolean mAppIsEligibleForBackup = false;
+        boolean mAppGetsFullBackup = false;
+        int mOperationType = 0;
 
-        TestBackupService(Context context) {
-            super(context);
+        TestBackupService(Context context, PackageManager packageManager) {
+            super(context, packageManager);
         }
 
         @Override
@@ -76,5 +161,18 @@
 
         @Override
         void updateStateOnBackupEnabled(boolean wasEnabled, boolean enable) {}
+
+        @Override
+        boolean appIsEligibleForBackup(ApplicationInfo applicationInfo, int userId,
+                @OperationType int operationType) {
+            mOperationType = operationType;
+            return mAppIsEligibleForBackup;
+        }
+
+        @Override
+        boolean appGetsFullBackup(PackageInfo packageInfo, @OperationType int operationType) {
+            mOperationType = operationType;
+            return mAppGetsFullBackup;
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
index a901175..201211e 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -22,6 +22,8 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManager.OperationType;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
@@ -74,7 +76,7 @@
         applicationInfo.packageName = TEST_PACKAGE_NAME;
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isFalse();
     }
@@ -89,7 +91,7 @@
         applicationInfo.packageName = TEST_PACKAGE_NAME;
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isFalse();
     }
@@ -103,7 +105,7 @@
         applicationInfo.packageName = UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isFalse();
     }
@@ -120,7 +122,7 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isTrue();
     }
@@ -137,7 +139,7 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isTrue();
     }
@@ -154,7 +156,7 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isTrue();
     }
@@ -171,7 +173,7 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isFalse();
     }
@@ -188,7 +190,7 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
 
         assertThat(isEligible).isFalse();
     }
@@ -205,7 +207,31 @@
                 .thenReturn(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
 
         boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
-                mMockPackageManagerInternal, mUserId);
+                mMockPackageManagerInternal, mUserId, OperationType.BACKUP);
+
+        assertThat(isEligible).isFalse();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_backupNotAllowedAndInMigration_returnsTrue()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME);
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
+                mMockPackageManagerInternal, mUserId, OperationType.MIGRATION);
+
+        assertThat(isEligible).isTrue();
+    }
+
+    @Test
+    public void appIsEligibleForBackup_backupNotAllowedForSystemAppAndInMigration_returnsFalse()
+            throws Exception {
+        ApplicationInfo applicationInfo = getApplicationInfo(Process.SYSTEM_UID,
+                /* flags */ 0, CUSTOM_BACKUP_AGENT_NAME);
+
+        boolean isEligible = AppBackupUtils.appIsEligibleForBackup(applicationInfo,
+                mMockPackageManagerInternal, mUserId, OperationType.MIGRATION);
 
         assertThat(isEligible).isFalse();
     }
@@ -337,7 +363,7 @@
         packageInfo.applicationInfo = new ApplicationInfo();
         packageInfo.applicationInfo.backupAgentName = null;
 
-        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo, OperationType.BACKUP);
 
         assertThat(result).isTrue();
     }
@@ -350,7 +376,7 @@
         packageInfo.applicationInfo.backupAgentName = "backup.agent";
         packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
 
-        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo, OperationType.BACKUP);
 
         assertThat(result).isTrue();
     }
@@ -363,7 +389,31 @@
         packageInfo.applicationInfo.backupAgentName = "backup.agent";
         packageInfo.applicationInfo.flags = ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
 
-        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo);
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo, OperationType.BACKUP);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appGetsFullBackup_withCustomBackupAgentAndWithoutFullBackupOnlyFlagAndInMigration_returnsTrue()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = getApplicationInfo(Process.FIRST_APPLICATION_UID,
+                ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY, CUSTOM_BACKUP_AGENT_NAME);
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo, OperationType.MIGRATION);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appGetsFullBackup_systemAppWithCustomBackupAgentAndWithoutFullBackupOnlyFlagAndInMigration_returnsFalse()
+            throws Exception {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.applicationInfo = getApplicationInfo(Process.SYSTEM_UID,
+                ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY, CUSTOM_BACKUP_AGENT_NAME);
+
+        boolean result = AppBackupUtils.appGetsFullBackup(packageInfo, OperationType.MIGRATION);
 
         assertThat(result).isFalse();
     }
@@ -406,6 +456,50 @@
     }
 
     @Test
+    public void appIgnoresIncludeExcludeRules_systemAppAndInMigration_returnsFalse() {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = Process.SYSTEM_UID;
+
+        boolean result = AppBackupUtils.appIgnoresIncludeExcludeRules(applicationInfo,
+                OperationType.MIGRATION);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIgnoresIncludeExcludeRules_systemAppInBackup_returnsFalse() {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = Process.SYSTEM_UID;
+
+        boolean result = AppBackupUtils.appIgnoresIncludeExcludeRules(applicationInfo,
+                OperationType.BACKUP);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
+    public void appIgnoresIncludeExcludeRules_nonSystemAppInMigration_returnsTrue() {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+
+        boolean result = AppBackupUtils.appIgnoresIncludeExcludeRules(applicationInfo,
+                OperationType.MIGRATION);
+
+        assertThat(result).isTrue();
+    }
+
+    @Test
+    public void appIgnoresIncludeExcludeRules_nonSystemInBackup_returnsFalse() {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.uid = Process.FIRST_APPLICATION_UID;
+
+        boolean result = AppBackupUtils.appIgnoresIncludeExcludeRules(applicationInfo,
+                OperationType.BACKUP);
+
+        assertThat(result).isFalse();
+    }
+
+    @Test
     public void signaturesMatch_targetIsNull_returnsFalse() throws Exception {
         boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null,
                 mMockPackageManagerInternal);
@@ -693,4 +787,14 @@
         signatureBytes[0] = i;
         return new Signature(signatureBytes);
     }
+
+    private static ApplicationInfo getApplicationInfo(int appUid, int flags,
+            String backupAgentName) {
+        ApplicationInfo applicationInfo = new ApplicationInfo();
+        applicationInfo.flags = 0;
+        applicationInfo.packageName = TEST_PACKAGE_NAME;
+        applicationInfo.uid = appUid;
+        applicationInfo.backupAgentName = backupAgentName;
+        return applicationInfo;
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricServiceBaseTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricServiceBaseTest.java
deleted file mode 100644
index d4b299d..0000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricServiceBaseTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.biometrics.sensors;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.hardware.biometrics.BiometricAuthenticator;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.List;
-
-@Presubmit
-@SmallTest
-public class BiometricServiceBaseTest {
-    private static class TestableBiometricServiceBase extends BiometricServiceBase {
-        TestableBiometricServiceBase(Context context) {
-            super(context);
-        }
-
-        @Override
-        protected void doTemplateCleanupForUser(int userId) {
-        }
-
-        @Override
-        protected String getTag() {
-            return null;
-        }
-
-        @Override
-        protected Object getDaemon() {
-            return null;
-        }
-
-        @Override
-        protected BiometricUtils getBiometricUtils() {
-            return null;
-        }
-
-        @Override
-        protected boolean hasReachedEnrollmentLimit(int userId) {
-            return false;
-        }
-
-        @Override
-        protected void updateActiveGroup(int userId) {
-        }
-
-        @Override
-        protected boolean hasEnrolledBiometrics(int userId) {
-            return false;
-        }
-
-        @Override
-        protected String getManageBiometricPermission() {
-            return null;
-        }
-
-        @Override
-        protected void checkUseBiometricPermission() {
-        }
-
-        @Override
-        protected boolean checkAppOps(int uid, String opPackageName) {
-            return false;
-        }
-
-        @Override
-        protected List<? extends BiometricAuthenticator.Identifier> getEnrolledTemplates(
-                int userId) {
-            return null;
-        }
-
-        @Override
-        protected int statsModality() {
-            return 0;
-        }
-
-        @Override
-        protected int getLockoutMode(int userId) {
-            return 0;
-        }
-    }
-
-    private static final int CLIENT_COOKIE = 0xc00c1e;
-
-    private BiometricServiceBase mBiometricServiceBase;
-
-    @Mock
-    private Context mContext;
-    @Mock
-    private Resources mResources;
-    @Mock
-    private BiometricAuthenticator.Identifier mIdentifier;
-    @Mock
-    private ClientMonitor mClient;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        when(mContext.getResources()).thenReturn(mResources);
-        when(mResources.getString(anyInt())).thenReturn("");
-        when(mClient.getCookie()).thenReturn(CLIENT_COOKIE);
-
-        mBiometricServiceBase = new TestableBiometricServiceBase(mContext);
-    }
-
-    @Test
-    public void testHandleEnumerate_doesNotCrash_withNullClient() {
-        mBiometricServiceBase.handleEnumerate(mIdentifier, 0 /* remaining */);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index 419fb14..9669010 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -369,11 +369,9 @@
     }
 
     @Test
-    public void testCreateService_initializesNativeServiceAndSetsPowerModes() {
+    public void testCreateService_initializesNativeService() {
         PowerManagerService service = createService();
         verify(mNativeWrapperMock).nativeInit(same(service));
-        verify(mNativeWrapperMock).nativeSetPowerMode(eq(Mode.INTERACTIVE), eq(true));
-        verify(mNativeWrapperMock).nativeSetPowerMode(eq(Mode.DOUBLE_TAP_TO_WAKE), eq(false));
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index e10dfee..0be1bf3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -2686,6 +2686,96 @@
     }
 
     @Test
+    public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet() {
+        mHelper.lockChannelsForOEM(new String[] {PKG_O});
+
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
+        mHelper.createNotificationChannel(PKG_N_MR1, 30, b, false, false);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
+                .isImportanceLockedByOEM());
+        assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, 30, b.getId(), false)
+                .isImportanceLockedByOEM());
+    }
+
+    @Test
+    public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet() {
+        mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
+
+        NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
+        NotificationChannel b = new NotificationChannel("b", "b", IMPORTANCE_LOW);
+        NotificationChannel c = new NotificationChannel("c", "c", IMPORTANCE_DEFAULT);
+        // different uids, same package
+        mHelper.createNotificationChannel(PKG_O, 3, a, true, false);
+        mHelper.createNotificationChannel(PKG_O, 3, b, false, false);
+        mHelper.createNotificationChannel(PKG_O, 30, c, true, true);
+
+        assertFalse(mHelper.getNotificationChannel(PKG_O, 3, a.getId(), false)
+                .isImportanceLockedByOEM());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, 3, b.getId(), false)
+                .isImportanceLockedByOEM());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, 30, c.getId(), false)
+                .isImportanceLockedByOEM());
+    }
+
+    @Test
+    public void testLockChannelsForOEM_onlyGivenPkg_appDoesNotExistYet_restoreData()
+            throws Exception {
+        mHelper.lockChannelsForOEM(new String[] {PKG_O});
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
+                + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+                + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+                + "</package>"
+                + "<package name=\"" + PKG_N_MR1 + "\" uid=\"" + UID_N_MR1 + "\" >\n"
+                + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+                + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertTrue(mHelper.getNotificationChannel(PKG_O, UID_O, "a", false)
+                .isImportanceLockedByOEM());
+        assertFalse(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "b", false)
+                .isImportanceLockedByOEM());
+    }
+
+    @Test
+    public void testLockChannelsForOEM_channelSpecific_appDoesNotExistYet_restoreData()
+            throws Exception {
+        mHelper.lockChannelsForOEM(new String[] {PKG_O + ":b", PKG_O + ":c"});
+
+        final String xml = "<ranking version=\"1\">\n"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + 3 + "\" >\n"
+                + "<channel id=\"a\" name=\"a\" importance=\"3\"/>"
+                + "<channel id=\"b\" name=\"b\" importance=\"3\"/>"
+                + "</package>"
+                + "<package name=\"" + PKG_O + "\" uid=\"" + 30 + "\" >\n"
+                + "<channel id=\"c\" name=\"c\" importance=\"3\"/>"
+                + "</package>"
+                + "</ranking>";
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
+                null);
+        parser.nextTag();
+        mHelper.readXml(parser, false, UserHandle.USER_ALL);
+
+        assertFalse(mHelper.getNotificationChannel(PKG_O, 3, "a", false)
+                .isImportanceLockedByOEM());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, 3, "b", false)
+                .isImportanceLockedByOEM());
+        assertTrue(mHelper.getNotificationChannel(PKG_O, 30, "c", false)
+                .isImportanceLockedByOEM());
+    }
+
+    @Test
     public void testLockChannelsForOEM_channelSpecific_clearData() {
         NotificationChannel a = new NotificationChannel("a", "a", IMPORTANCE_HIGH);
         mHelper.getImportance(PKG_O, UID_O);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index f6213bd..6b613ca 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -28,6 +28,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doCallRealMethod;
 
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
@@ -56,6 +57,14 @@
         mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
     }
 
+    @Override
+    ActivityRecord createActivityRecord(DisplayContent dc, int windowingMode, int activityType) {
+        final ActivityRecord r = super.createActivityRecord(dc, windowingMode, activityType);
+        // Ensure that ActivityRecord#setOccludesParent takes effect.
+        doCallRealMethod().when(r).fillsParent();
+        return r;
+    }
+
     @Test
     @FlakyTest(bugId = 131005232)
     public void testTranslucentOpen() {
@@ -191,6 +200,9 @@
 
     @Test
     public void testGetAnimationTargets_exitingBeforeTransition() {
+        // Create another non-empty task so the animation target won't promote to task display area.
+        WindowTestUtils.createTestActivityRecord(
+                mDisplayContent.getDefaultTaskDisplayArea().getOrCreateRootHomeTask());
         final ActivityStack stack = createTaskStackOnDisplay(mDisplayContent);
         final ActivityRecord activity = WindowTestUtils.createTestActivityRecord(stack);
         activity.setVisible(false);
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index 1d13788..c8b668b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -158,6 +158,7 @@
         mActivity.removeImmediately();
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     @FlakyTest(bugId = 131005232)
     public void testLandscapeSeascapeRotationByApp() {
@@ -188,6 +189,7 @@
         appWindow.removeImmediately();
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testLandscapeSeascapeRotationByPolicy() {
         // This instance has been spied in {@link TestDisplayContent}.
@@ -295,6 +297,7 @@
         mWm.mDisplayFrozen = false;
     }
 
+    @UseTestDisplay
     @Test
     public void testRespectTopFullscreenOrientation() {
         final Configuration displayConfig = mActivity.mDisplayContent.getConfiguration();
@@ -316,6 +319,7 @@
         assertEquals(Configuration.ORIENTATION_LANDSCAPE, activityConfig.orientation);
     }
 
+    @UseTestDisplay
     @Test
     public void testReportOrientationChange() {
         mActivity.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
@@ -343,7 +347,7 @@
     @Test
     public void testAddRemoveRace() {
         // There was once a race condition between adding and removing starting windows
-        final ActivityRecord appToken = mAppWindow.mActivityRecord;
+        final ActivityRecord appToken = createIsolatedTestActivityRecord();
         for (int i = 0; i < 1000; i++) {
             appToken.addStartingWindow(mPackageName,
                     android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
new file mode 100644
index 0000000..d75b35a
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaPolicyTests.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.window.DisplayAreaOrganizer.FEATURE_DEFAULT_TASK_CONTAINER;
+import static android.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.DisplayArea.Type.ABOVE_TASKS;
+import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.wm.DisplayAreaPolicyBuilderTest.SurfacelessDisplayAreaRoot;
+
+import com.google.android.collect.Lists;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Tests for the {@link DisplayAreaPolicy}.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:DisplayAreaPolicyTests
+ */
+@SmallTest
+@Presubmit
+public class DisplayAreaPolicyTests {
+
+    @Rule
+    public final SystemServicesTestRule mSystemServices = new SystemServicesTestRule();
+
+    private DisplayAreaPolicyBuilder.Result mPolicy;
+    private TaskDisplayArea mTaskDisplayArea1;
+    private TaskDisplayArea mTaskDisplayArea2;
+    private RootDisplayArea mRoot;
+
+    @Before
+    public void setUp() throws Exception {
+        WindowManagerService wms = mSystemServices.getWindowManagerService();
+        mRoot = new SurfacelessDisplayAreaRoot(wms);
+        spyOn(mRoot);
+        DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime");
+        DisplayContent displayContent = mock(DisplayContent.class);
+        doReturn(true).when(displayContent).isTrusted();
+        mTaskDisplayArea1 = new TaskDisplayArea(displayContent, wms, "Tasks1",
+                FEATURE_DEFAULT_TASK_CONTAINER);
+        mTaskDisplayArea2 = new TaskDisplayArea(displayContent, wms, "Tasks2",
+                FEATURE_VENDOR_FIRST);
+        List<TaskDisplayArea> taskDisplayAreaList = new ArrayList<>();
+        taskDisplayAreaList.add(mTaskDisplayArea1);
+        taskDisplayAreaList.add(mTaskDisplayArea2);
+
+        mPolicy = new DisplayAreaPolicyBuilder()
+                .setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(mRoot)
+                        .setImeContainer(ime)
+                        .setTaskDisplayAreas(taskDisplayAreaList))
+                .build(wms);
+    }
+
+    @Test
+    public void testGetDefaultTaskDisplayArea() {
+        assertEquals(mTaskDisplayArea1, mPolicy.getDefaultTaskDisplayArea());
+    }
+
+    @Test
+    public void testTaskDisplayArea_taskPositionChanged_updatesTaskDisplayAreaPosition() {
+        final ActivityStack stack1 = mTaskDisplayArea1.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityStack stack2 = mTaskDisplayArea2.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        // Initial order
+        assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2);
+
+        // Move stack in tda1 to top
+        stack1.getParent().positionChildAt(POSITION_TOP, stack1, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea2, mTaskDisplayArea1);
+
+        // Move stack in tda2 to top, but not including parents
+        stack2.getParent().positionChildAt(POSITION_TOP, stack2, false /* includingParents */);
+
+        assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea2, mTaskDisplayArea1);
+
+        // Move stack in tda1 to bottom
+        stack1.getParent().positionChildAt(POSITION_BOTTOM, stack1, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2);
+
+        // Move stack in tda2 to bottom, but not including parents
+        stack2.getParent().positionChildAt(POSITION_BOTTOM, stack2, false /* includingParents */);
+
+        assertTaskDisplayAreasOrder(mPolicy, mTaskDisplayArea1, mTaskDisplayArea2);
+    }
+
+    @Test
+    public void testDisplayAreaGroup_taskPositionChanged_updatesDisplayAreaGroupPosition() {
+        final WindowManagerService wms = mSystemServices.getWindowManagerService();
+        final DisplayContent displayContent = mock(DisplayContent.class);
+        doReturn(true).when(displayContent).isTrusted();
+        final RootDisplayArea root = new SurfacelessDisplayAreaRoot(wms);
+        final RootDisplayArea group1 = new SurfacelessDisplayAreaRoot(wms, "group1",
+                FEATURE_VENDOR_FIRST + 1);
+        final RootDisplayArea group2 = new SurfacelessDisplayAreaRoot(wms, "group2",
+                FEATURE_VENDOR_FIRST + 2);
+        final TaskDisplayArea taskDisplayArea1 = new TaskDisplayArea(displayContent, wms, "Tasks1",
+                FEATURE_DEFAULT_TASK_CONTAINER);
+        final TaskDisplayArea taskDisplayArea2 = new TaskDisplayArea(displayContent, wms, "Tasks2",
+                FEATURE_VENDOR_FIRST + 3);
+        final TaskDisplayArea taskDisplayArea3 = new TaskDisplayArea(displayContent, wms, "Tasks3",
+                FEATURE_VENDOR_FIRST + 4);
+        final TaskDisplayArea taskDisplayArea4 = new TaskDisplayArea(displayContent, wms, "Tasks4",
+                FEATURE_VENDOR_FIRST + 5);
+        final TaskDisplayArea taskDisplayArea5 = new TaskDisplayArea(displayContent, wms, "Tasks5",
+                FEATURE_VENDOR_FIRST + 6);
+        final DisplayArea<WindowContainer> ime = new DisplayArea<>(wms, ABOVE_TASKS, "Ime");
+        final DisplayAreaPolicy policy = new DisplayAreaPolicyBuilder()
+                .setRootHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(root)
+                        .setImeContainer(ime)
+                        .setTaskDisplayAreas(Lists.newArrayList(taskDisplayArea1, taskDisplayArea2))
+                )
+                .addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(group1)
+                        .setTaskDisplayAreas(Lists.newArrayList(taskDisplayArea3, taskDisplayArea4))
+                )
+                .addDisplayAreaGroupHierarchy(new DisplayAreaPolicyBuilder.HierarchyBuilder(group2)
+                        .setTaskDisplayAreas(Lists.newArrayList(taskDisplayArea5)))
+                .build(wms);
+        final ActivityStack stack1 = taskDisplayArea1.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityStack stack3 = taskDisplayArea3.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityStack stack4 = taskDisplayArea4.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        // Initial order
+        assertTaskDisplayAreasOrder(policy, taskDisplayArea1, taskDisplayArea2, taskDisplayArea3,
+                taskDisplayArea4, taskDisplayArea5);
+
+        // Move bottom stack in tda1 to top
+        stack1.getParent().positionChildAt(POSITION_TOP, stack1, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(policy, taskDisplayArea2, taskDisplayArea3, taskDisplayArea4,
+                taskDisplayArea5, taskDisplayArea1);
+
+        // Move bottom stack in tda2 to top
+        stack3.getParent().positionChildAt(POSITION_TOP, stack3, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(policy, taskDisplayArea2, taskDisplayArea5, taskDisplayArea1,
+                taskDisplayArea4, taskDisplayArea3);
+
+        // Move bottom stack in tda2 to top
+        stack4.getParent().positionChildAt(POSITION_TOP, stack4, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(policy, taskDisplayArea2, taskDisplayArea5, taskDisplayArea1,
+                taskDisplayArea3, taskDisplayArea4);
+
+        // Move top stack in tda2 to bottom
+        stack4.getParent().positionChildAt(POSITION_BOTTOM, stack4, true /* includingParents */);
+
+        assertTaskDisplayAreasOrder(policy, taskDisplayArea4, taskDisplayArea3, taskDisplayArea2,
+                taskDisplayArea5, taskDisplayArea1);
+    }
+
+    private void assertTaskDisplayAreasOrder(DisplayAreaPolicy policy,
+            TaskDisplayArea... expectTdaOrder) {
+        List<TaskDisplayArea> expectOrder = new ArrayList<>();
+        Collections.addAll(expectOrder, expectTdaOrder);
+
+        // Verify hierarchy
+        List<TaskDisplayArea> actualOrder = new ArrayList<>();
+        policy.mRoot.forAllTaskDisplayAreas(taskDisplayArea -> {
+            actualOrder.add(taskDisplayArea);
+        }, false /* traverseTopToBottom */);
+        assertEquals(expectOrder, actualOrder);
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 018b302..792b597 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -133,6 +133,7 @@
 @RunWith(WindowTestRunner.class)
 public class DisplayContentTests extends WindowTestsBase {
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows() {
         final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
@@ -159,6 +160,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows_WithAppImeTarget() {
         final WindowState imeAppTarget =
@@ -180,6 +182,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
         mDisplayContent.mInputMethodTarget = mChildAppWindowAbove;
@@ -197,6 +200,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
         mDisplayContent.mInputMethodTarget = mStatusBarWindow;
@@ -214,6 +218,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows_WithNotificationShadeImeTarget() throws Exception {
         mDisplayContent.mInputMethodTarget = mNotificationShadeWindow;
@@ -231,6 +236,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testForAllWindows_WithInBetweenWindowToken() {
         // This window is set-up to be z-ordered between some windows that go in the same token like
@@ -252,6 +258,7 @@
                 mNavBarWindow));
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testComputeImeTarget() {
         // Verify that an app window can be an ime target.
@@ -271,6 +278,7 @@
         assertEquals(childWin, imeTarget);
     }
 
+    @UseTestDisplay(addAllCommonWindows = true)
     @Test
     public void testComputeImeTarget_startingWindow() {
         ActivityRecord activity = createActivityRecord(mDisplayContent,
@@ -775,6 +783,7 @@
                 .setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
     }
 
+    @UseTestDisplay
     @Test
     public void testClearLastFocusWhenReparentingFocusedWindow() {
         final DisplayContent defaultDisplay = mWm.getDefaultDisplayContentLocked();
@@ -808,6 +817,7 @@
         assertFalse(isOptionsPanelAtRight(landscapeDisplay.getDisplayId()));
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testInputMethodTargetUpdateWhenSwitchingOnDisplays() {
         final DisplayContent newDisplay = createNewDisplay();
@@ -907,6 +917,7 @@
     public void testComputeImeParent_app() throws Exception {
         final DisplayContent dc = createNewDisplay();
         dc.mInputMethodTarget = createWindow(null, TYPE_BASE_APPLICATION, "app");
+        dc.mInputMethodInputTarget = dc.mInputMethodTarget;
         assertEquals(dc.mInputMethodTarget.mActivityRecord.getSurfaceControl(),
                 dc.computeImeParent());
     }
@@ -920,6 +931,7 @@
         assertEquals(dc.getImeContainer().getParentSurfaceControl(), dc.computeImeParent());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testComputeImeParent_app_notMatchParentBounds() {
         spyOn(mAppWindow.mActivityRecord);
@@ -977,6 +989,7 @@
         assertNotEquals(dc.mInputMethodInputTarget, dc.computeImeControlTarget());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testComputeImeControlTarget_notMatchParentBounds() throws Exception {
         spyOn(mAppWindow.mActivityRecord);
@@ -1095,6 +1108,7 @@
         win.setHasSurface(false);
     }
 
+    @UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_ACTIVITY})
     @Test
     public void testRequestResizeForEmptyFrames() {
         final WindowState win = mChildAppWindowAbove;
@@ -1134,6 +1148,7 @@
                 is(Configuration.ORIENTATION_PORTRAIT));
     }
 
+    @UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER, W_STATUS_BAR, W_NAVIGATION_BAR })
     @Test
     public void testApplyTopFixedRotationTransform() {
         final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
@@ -1233,7 +1248,9 @@
 
     @Test
     public void testFinishFixedRotationNoAppTransitioningTask() {
-        final ActivityRecord app = mAppWindow.mActivityRecord;
+        unblockDisplayRotation(mDisplayContent);
+        final ActivityRecord app = createActivityRecord(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD);
         final Task task = app.getTask();
         final ActivityRecord app2 = new ActivityTestsBase.ActivityBuilder(mWm.mAtmService)
                 .setTask(task).build();
@@ -1254,6 +1271,7 @@
         assertFalse(mDisplayContent.hasTopFixedRotationLaunchingApp());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testRotateSeamlesslyWithFixedRotation() {
         final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
@@ -1274,13 +1292,14 @@
 
     @Test
     public void testNoFixedRotationWithPip() {
+        final DisplayContent displayContent = mDefaultDisplay;
+        unblockDisplayRotation(displayContent);
         // Make resume-top really update the activity state.
         setBooted(mWm.mAtmService);
         // Speed up the test by a few seconds.
         mWm.mAtmService.deferWindowLayout();
         doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
 
-        final DisplayContent displayContent = mWm.mRoot.getDefaultDisplay();
         final Configuration displayConfig = displayContent.getConfiguration();
         final ActivityRecord pinnedActivity = createActivityRecord(displayContent,
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD);
@@ -1323,11 +1342,13 @@
 
     @Test
     public void testRecentsNotRotatingWithFixedRotation() {
+        unblockDisplayRotation(mDisplayContent);
         final DisplayRotation displayRotation = mDisplayContent.getDisplayRotation();
-        doCallRealMethod().when(displayRotation).updateRotationUnchecked(anyBoolean());
         // Skip freezing so the unrelated conditions in updateRotationUnchecked won't disturb.
         doNothing().when(mWm).startFreezingDisplay(anyInt(), anyInt(), any(), anyInt());
 
+        final ActivityRecord activity = createActivityRecord(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
         final ActivityRecord recentsActivity = createActivityRecord(mDisplayContent,
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS);
         recentsActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT);
@@ -1344,12 +1365,12 @@
         // Rotation can be updated if the recents animation is animating but it is not on top, e.g.
         // switching activities in different orientations by quickstep gesture.
         mDisplayContent.mFixedRotationTransitionListener.onStartRecentsAnimation(recentsActivity);
-        mDisplayContent.setFixedRotationLaunchingAppUnchecked(mAppWindow.mActivityRecord);
+        mDisplayContent.setFixedRotationLaunchingAppUnchecked(activity);
         displayRotation.setRotation((displayRotation.getRotation() + 1) % 4);
         assertTrue(displayRotation.updateRotationUnchecked(false));
 
         // The recents activity should not apply fixed rotation if the top activity is not opaque.
-        mDisplayContent.mFocusedApp = mAppWindow.mActivityRecord;
+        mDisplayContent.mFocusedApp = activity;
         doReturn(false).when(mDisplayContent.mFocusedApp).occludesParent();
         doReturn(ROTATION_90).when(mDisplayContent).rotationForActivityInDifferentOrientation(
                 eq(recentsActivity));
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
index 39cd76a..402fd22 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyInsetsTests.java
@@ -36,6 +36,8 @@
 
 @SmallTest
 @Presubmit
+@WindowTestsBase.UseTestDisplay(
+        addWindows = { WindowTestsBase.W_STATUS_BAR, WindowTestsBase.W_NAVIGATION_BAR })
 @RunWith(WindowTestRunner.class)
 public class DisplayPolicyInsetsTests extends DisplayPolicyTestsBase {
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index da7c41a7..f9de379 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -49,7 +49,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.doCallRealMethod;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -65,14 +64,12 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.InsetsState;
-import android.view.View;
 import android.view.WindowInsets.Side;
 import android.view.WindowInsets.Type;
 import android.view.WindowManager;
 
 import androidx.test.filters.SmallTest;
 
-import com.android.server.policy.WindowManagerPolicy;
 import com.android.server.wm.utils.WmDisplayCutout;
 
 import org.junit.Before;
@@ -90,6 +87,8 @@
  */
 @SmallTest
 @Presubmit
+@WindowTestsBase.UseTestDisplay(
+        addWindows = { WindowTestsBase.W_STATUS_BAR, WindowTestsBase.W_NAVIGATION_BAR })
 @RunWith(WindowTestRunner.class)
 public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {
 
@@ -120,9 +119,6 @@
         // Disabling this call for most tests since it can override the systemUiFlags when called.
         doReturn(0).when(mDisplayPolicy).updateSystemUiVisibilityLw();
 
-        mDisplayPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT;
-        mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
-
         updateDisplayFrames();
     }
 
@@ -146,10 +142,7 @@
         mFrames = createDisplayFrames();
         mDisplayBounds.set(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight);
         mDisplayContent.mDisplayFrames = mFrames;
-
-        doReturn(mDisplayBounds).when(mStatusBarWindow).getBounds();
-        doReturn(mDisplayBounds).when(mNavBarWindow).getBounds();
-        doReturn(mDisplayBounds).when(mWindow).getBounds();
+        mDisplayContent.setBounds(mDisplayBounds);
     }
 
     private DisplayFrames createDisplayFrames() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index a3f9b2e..4483f8c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -222,6 +222,7 @@
                         opaqueDarkNavBar, imeDrawLightNavBar, imeDrawLightNavBar));
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testComputeTopFullscreenOpaqueWindow() {
         final WindowManager.LayoutParams attrs = mAppWindow.mAttrs;
@@ -320,6 +321,8 @@
         return win;
     }
 
+    @UseTestDisplay(
+            addWindows = { W_ACTIVITY, W_STATUS_BAR, W_NAVIGATION_BAR, W_NOTIFICATION_SHADE })
     @Test
     public void testUpdateHideNavInputEventReceiver() {
         final InsetsPolicy insetsPolicy = mDisplayContent.getInsetsPolicy();
@@ -358,6 +361,7 @@
         assertNull(displayPolicy.mInputConsumer);
     }
 
+    @UseTestDisplay(addWindows = { W_NAVIGATION_BAR, W_INPUT_METHOD })
     @Test
     public void testImeMinimalSourceFrame() {
         final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
index 1e1c399..b4e1c37 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java
@@ -68,6 +68,10 @@
 
     @Before
     public void setUpDisplayPolicy() {
+        // Disable surface placement because it has no direct relation to layout policy and it also
+        // avoids some noises such as the display info is modified, screen frozen, config change.
+        mWm.mWindowPlacerLocked.deferLayout();
+
         mDisplayPolicy = mDisplayContent.getDisplayPolicy();
         spyOn(mDisplayPolicy);
 
@@ -100,6 +104,9 @@
         mNavBarWindow.mAttrs.gravity = Gravity.BOTTOM;
         addWindow(mNavBarWindow);
         mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
+
+        // Update source frame and visibility of insets providers.
+        mDisplayContent.getInsetsStateController().onPostLayout();
     }
 
     void addWindow(WindowState win) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index 11c02c2..a3d3739a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -77,6 +77,7 @@
  */
 @SmallTest
 @Presubmit
+@WindowTestsBase.UseTestDisplay
 @RunWith(WindowTestRunner.class)
 public class DisplayWindowSettingsTests extends WindowTestsBase {
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
index 87bc7f1..555906d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java
@@ -225,6 +225,7 @@
         assertEquals(ITYPE_STATUS_BAR, fullscreenAppControls[0].getType());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() {
         addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
@@ -259,6 +260,7 @@
                 .getSource(ITYPE_NAVIGATION_BAR).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() {
         addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
@@ -288,6 +290,7 @@
         }
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() {
         addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar")
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 0a27e1a..5e83e66 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -147,6 +147,7 @@
         assertNull(getController().getInsetsForDispatch(app).peekSource(ITYPE_NAVIGATION_BAR));
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_independentSources() {
         getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -162,6 +163,7 @@
         assertTrue(getController().getInsetsForDispatch(app1).getSource(ITYPE_IME).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_belowIme() {
         getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -173,6 +175,7 @@
         assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_aboveIme() {
         getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -184,6 +187,7 @@
         assertFalse(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_imeOrderChanged() {
         // This can be the IME z-order target while app cannot be the IME z-order target.
@@ -232,6 +236,7 @@
         assertTrue(getController().getInsetsForDispatch(app).getSource(ITYPE_IME).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_childWindow_altFocusable() {
         getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
@@ -249,6 +254,7 @@
         assertFalse(getController().getInsetsForDispatch(child).getSource(ITYPE_IME).isVisible());
     }
 
+    @UseTestDisplay(addWindows = W_INPUT_METHOD)
     @Test
     public void testStripForDispatch_childWindow_splitScreen() {
         getController().getSourceProvider(ITYPE_IME).setWindow(mImeWindow, null, null);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
index ce3f270..bf84aec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -55,102 +54,10 @@
         mTransaction = spy(StubTransaction.class);
     }
 
-    private static final int TOP_BAR = 0x1;
-    private static final int BOTTOM_BAR = 0x2;
-    private static final int LEFT_BAR = 0x4;
-    private static final int RIGHT_BAR = 0x8;
-
     @Test
-    public void testNotIntersectsOrFullyContains_usesGlobalCoordinates() {
-        final Rect outer = new Rect(0, 0, 10, 50);
-        final Point surfaceOrig = new Point(1000, 2000);
-
-        final Rect topBar = new Rect(0, 0, 10, 2);
-        final Rect bottomBar = new Rect(0, 45, 10, 50);
-        final Rect leftBar = new Rect(0, 0, 2, 50);
-        final Rect rightBar = new Rect(8, 0, 10, 50);
-
-        final LetterboxLayoutVerifier verifier =
-                new LetterboxLayoutVerifier(outer, surfaceOrig, mLetterbox);
-        verifier.setBarRect(topBar, bottomBar, leftBar, rightBar);
-
-        // top
-        verifier.setInner(0, 2, 10, 50).verifyPositions(TOP_BAR | BOTTOM_BAR, BOTTOM_BAR);
-        // bottom
-        verifier.setInner(0, 0, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, TOP_BAR);
-        // left
-        verifier.setInner(2, 0, 10, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, RIGHT_BAR);
-        // right
-        verifier.setInner(0, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, LEFT_BAR);
-        // top + bottom
-        verifier.setInner(0, 2, 10, 45).verifyPositions(TOP_BAR | BOTTOM_BAR, 0);
-        // left + right
-        verifier.setInner(2, 0, 8, 50).verifyPositions(LEFT_BAR | RIGHT_BAR, 0);
-        // top + left
-        verifier.setInner(2, 2, 10, 50).verifyPositions(TOP_BAR | LEFT_BAR, 0);
-        // top + left + right
-        verifier.setInner(2, 2, 8, 50).verifyPositions(TOP_BAR | LEFT_BAR | RIGHT_BAR, 0);
-        // left + right + bottom
-        verifier.setInner(2, 0, 8, 45).verifyPositions(LEFT_BAR | RIGHT_BAR | BOTTOM_BAR, 0);
-        // all
-        verifier.setInner(2, 2, 8, 45)
-                .verifyPositions(TOP_BAR | BOTTOM_BAR | LEFT_BAR | RIGHT_BAR, 0);
-    }
-
-    private static class LetterboxLayoutVerifier {
-        final Rect mOuter;
-        final Rect mInner = new Rect();
-        final Point mSurfaceOrig;
-        final Letterbox mLetterbox;
-        final Rect mTempRect = new Rect();
-
-        final Rect mTop = new Rect();
-        final Rect mBottom = new Rect();
-        final Rect mLeft = new Rect();
-        final Rect mRight = new Rect();
-
-        LetterboxLayoutVerifier(Rect outer, Point surfaceOrig, Letterbox letterbox) {
-            mOuter = new Rect(outer);
-            mSurfaceOrig = new Point(surfaceOrig);
-            mLetterbox = letterbox;
-        }
-
-        LetterboxLayoutVerifier setInner(int left, int top, int right, int bottom) {
-            mInner.set(left, top, right, bottom);
-            mLetterbox.layout(mOuter, mInner, mSurfaceOrig);
-            return this;
-        }
-
-        void setBarRect(Rect top, Rect bottom, Rect left, Rect right) {
-            mTop.set(top);
-            mBottom.set(bottom);
-            mLeft.set(left);
-            mRight.set(right);
-        }
-
-        void verifyPositions(int allowedPos, int noOverlapPos) {
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mTop),
-                    (allowedPos & TOP_BAR) != 0);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mBottom),
-                    (allowedPos & BOTTOM_BAR) != 0);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mLeft),
-                    (allowedPos & LEFT_BAR) != 0);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mRight),
-                    (allowedPos & RIGHT_BAR) != 0);
-
-            mTempRect.set(mTop.left, mTop.top, mTop.right, mTop.bottom + 1);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
-                    (noOverlapPos & TOP_BAR) != 0);
-            mTempRect.set(mLeft.left, mLeft.top, mLeft.right + 1, mLeft.bottom);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
-                    (noOverlapPos & LEFT_BAR) != 0);
-            mTempRect.set(mRight.left - 1, mRight.top, mRight.right, mRight.bottom);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
-                    (noOverlapPos & RIGHT_BAR) != 0);
-            mTempRect.set(mBottom.left, mBottom.top - 1, mBottom.right, mBottom.bottom);
-            assertEquals(mLetterbox.notIntersectsOrFullyContains(mTempRect),
-                    (noOverlapPos & BOTTOM_BAR) != 0);
-        }
+    public void testOverlappingWith_usesGlobalCoordinates() {
+        mLetterbox.layout(new Rect(0, 0, 10, 50), new Rect(0, 2, 10, 45), new Point(1000, 2000));
+        assertTrue(mLetterbox.isOverlappingWith(new Rect(0, 0, 1, 1)));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 8e85e7b..4fbdd61 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -92,7 +92,6 @@
     @Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks;
     @Mock TaskSnapshot mMockTaskSnapshot;
     private RecentsAnimationController mController;
-    private DisplayContent mDefaultDisplay;
     private ActivityStack mRootHomeTask;
 
     @Before
@@ -100,7 +99,6 @@
         MockitoAnnotations.initMocks(this);
         doNothing().when(mWm.mRoot).performSurfacePlacement();
         when(mMockRunner.asBinder()).thenReturn(new Binder());
-        mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
         mController = spy(new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks,
                 DEFAULT_DISPLAY));
         mRootHomeTask = mDefaultDisplay.getDefaultTaskDisplayArea().getRootHomeTask();
@@ -321,6 +319,7 @@
 
     @Test
     public void testRecentViewInFixedPortraitWhenTopAppInLandscape() {
+        unblockDisplayRotation(mDefaultDisplay);
         mWm.setRecentsAnimationController(mController);
 
         final ActivityRecord homeActivity = createHomeActivity();
@@ -365,6 +364,7 @@
 
     @Test
     public void testClearFixedRotationLaunchingAppAfterCleanupAnimation() {
+        unblockDisplayRotation(mDefaultDisplay);
         final ActivityRecord homeActivity = createHomeActivity();
         homeActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
         final ActivityRecord activity = createActivityRecord(mDefaultDisplay,
@@ -389,6 +389,7 @@
 
     @Test
     public void testWallpaperHasFixedRotationApplied() {
+        unblockDisplayRotation(mDefaultDisplay);
         mWm.setRecentsAnimationController(mController);
 
         // Create a portrait home activity, a wallpaper and a landscape activity displayed on top.
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index d9ec0b1..4f5b3ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -292,11 +292,8 @@
         assertEquals(originalStackCount + 1, defaultTaskDisplayArea.getStackCount());
 
         final DisplayContent dc = defaultTaskDisplayArea.getDisplayContent();
-        final TaskDisplayArea secondTaskDisplayArea = new TaskDisplayArea(dc,
-                mRootWindowContainer.mWmService, "SecondaryTaskDisplayArea", FEATURE_VENDOR_FIRST);
-        // Add second display area right above the default one
-        defaultTaskDisplayArea.getParent().addChild(secondTaskDisplayArea,
-                defaultTaskDisplayArea.getParent().mChildren.indexOf(defaultTaskDisplayArea) + 1);
+        final TaskDisplayArea secondTaskDisplayArea = WindowTestsBase.createTaskDisplayArea(dc,
+                mRootWindowContainer.mWmService, "TestTaskDisplayArea", FEATURE_VENDOR_FIRST);
         final ActivityStack secondStack = secondTaskDisplayArea.createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, false /* onTop */);
         new ActivityBuilder(mService).setCreateTask(true).setStack(secondStack)
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 3c98272..a979c86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -269,6 +269,8 @@
 
         rotateDisplay(mActivity.mDisplayContent, ROTATION_90);
         mActivity.mDisplayContent.mInputMethodTarget = addWindowToActivity(mActivity);
+        mActivity.mDisplayContent.mInputMethodInputTarget =
+                mActivity.mDisplayContent.mInputMethodTarget;
         // Because the aspect ratio of display doesn't exceed the max aspect ratio of activity.
         // The activity should still fill its parent container and IME can attach to the activity.
         assertTrue(mActivity.matchParentBounds());
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index be9bf24..2233b22 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -26,6 +26,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
 
 import static java.util.concurrent.TimeUnit.SECONDS;
 
@@ -33,7 +34,7 @@
 import android.animation.ValueAnimator;
 import android.graphics.Matrix;
 import android.graphics.Point;
-import android.hardware.power.Boost;
+import android.os.Handler;
 import android.os.PowerManagerInternal;
 import android.platform.test.annotations.Presubmit;
 import android.view.Choreographer;
@@ -46,11 +47,12 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
+import com.android.server.AnimationThread;
 import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -64,8 +66,7 @@
  */
 @SmallTest
 @Presubmit
-@RunWith(WindowTestRunner.class)
-public class SurfaceAnimationRunnerTest extends WindowTestsBase {
+public class SurfaceAnimationRunnerTest {
 
     @Mock SurfaceControl mMockSurface;
     @Mock Transaction mMockTransaction;
@@ -75,6 +76,9 @@
     private SurfaceAnimationRunner mSurfaceAnimationRunner;
     private CountDownLatch mFinishCallbackLatch;
 
+    private final Handler mAnimationThreadHandler = AnimationThread.getHandler();
+    private final Handler mSurfaceAnimationHandler = SurfaceAnimationThread.getHandler();
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -84,6 +88,12 @@
                 mMockTransaction, mMockPowerManager);
     }
 
+    @After
+    public void tearDown() {
+        SurfaceAnimationThread.dispose();
+        AnimationThread.dispose();
+    }
+
     private void finishedCallback() {
         mFinishCallbackLatch.countDown();
     }
@@ -101,8 +111,7 @@
         verify(mMockTransaction, atLeastOnce()).setMatrix(eq(mMockSurface), eq(m), any());
         verify(mMockTransaction, atLeastOnce()).setAlpha(eq(mMockSurface), eq(1.0f));
 
-        waitHandlerIdle(SurfaceAnimationThread.getHandler());
-        mFinishCallbackLatch.await(1, SECONDS);
+        waitHandlerIdle(mSurfaceAnimationHandler);
         assertFinishCallbackCalled();
 
         m.setTranslate(10, 0);
@@ -120,7 +129,7 @@
                 .startAnimation(createTranslateAnimation(), mMockSurface, mMockTransaction,
                 this::finishedCallback);
         mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
-        waitUntilHandlersIdle();
+        waitHandlerIdle(mAnimationThreadHandler);
         assertTrue(mSurfaceAnimationRunner.mPendingAnimations.isEmpty());
         assertFinishCallbackNotCalled();
     }
@@ -135,7 +144,7 @@
         assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
         mSurfaceAnimationRunner.onAnimationCancelled(mMockSurface);
         assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
-        waitUntilHandlersIdle();
+        waitHandlerIdle(mAnimationThreadHandler);
         assertFinishCallbackNotCalled();
     }
 
@@ -180,9 +189,8 @@
         assertTrue(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
         mSurfaceAnimationRunner.continueStartingAnimations();
         waitUntilNextFrame();
-        waitHandlerIdle(SurfaceAnimationThread.getHandler());
+        waitHandlerIdle(mSurfaceAnimationHandler);
         assertFalse(mSurfaceAnimationRunner.mRunningAnimations.isEmpty());
-        mFinishCallbackLatch.await(1, SECONDS);
         assertFinishCallbackCalled();
     }
 
@@ -194,7 +202,7 @@
                 mMockTransaction, this::finishedCallback);
         waitUntilNextFrame();
 
-        verify(mMockPowerManager).setPowerBoost(eq(Boost.INTERACTION), eq(0));
+        verify(mMockPowerManager).powerHint(anyInt(), eq(0));
     }
 
     private void waitUntilNextFrame() throws Exception {
@@ -204,7 +212,15 @@
         latch.await();
     }
 
+    private static void waitHandlerIdle(Handler handler) {
+        handler.runWithScissors(() -> { }, 0 /* timeout */);
+    }
+
     private void assertFinishCallbackCalled() {
+        try {
+            assertTrue(mFinishCallbackLatch.await(5, SECONDS));
+        } catch (InterruptedException ignored) {
+        }
         assertEquals(0, mFinishCallbackLatch.getCount());
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 218261b..50675b0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -102,6 +102,7 @@
 
     private static final int[] TEST_USER_PROFILE_IDS = {};
 
+    private Description mDescription;
     private Context mContext;
     private StaticMockitoSession mMockitoSession;
     private ActivityManagerService mAmService;
@@ -121,6 +122,7 @@
         return new Statement() {
             @Override
             public void evaluate() throws Throwable {
+                mDescription = description;
                 Throwable throwable = null;
                 try {
                     runWithDexmakerShareClassLoader(SystemServicesTestRule.this::setUp);
@@ -373,6 +375,10 @@
         LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
     }
 
+    Description getDescription() {
+        return mDescription;
+    }
+
     WindowManagerService getWindowManagerService() {
         return mWmService;
     }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 0c4bb9f..0b99e32 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -183,6 +183,7 @@
         }
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testPrepareTaskSnapshot() {
         mAppWindow.mWinAnimator.mLastAlpha = 1f;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index b8a1c2b..bce1142 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -74,6 +74,7 @@
     private IActivityManager mService;
     private ITaskStackListener mTaskStackListener;
 
+    private static final int WAIT_TIMEOUT_MS = 5000;
     private static final Object sLock = new Object();
     @GuardedBy("sLock")
     private static boolean sTaskStackChangedCalled;
@@ -490,7 +491,8 @@
         SystemUtil.runWithShellPermissionIdentity(() -> context.startActivity(
                 new Intent(context, activityClass).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
                 options.toBundle()));
-        final TestActivity activity = (TestActivity) monitor.waitForActivityWithTimeout(1000);
+        final TestActivity activity =
+                (TestActivity) monitor.waitForActivityWithTimeout(WAIT_TIMEOUT_MS);
         if (activity == null) {
             throw new RuntimeException("Timed out waiting for Activity");
         }
@@ -508,7 +510,7 @@
 
     private void waitForCallback(CountDownLatch latch) {
         try {
-            final boolean result = latch.await(4, TimeUnit.SECONDS);
+            final boolean result = latch.await(WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
             if (!result) {
                 throw new RuntimeException("Timed out waiting for task stack change notification");
             }
@@ -560,7 +562,7 @@
                 if (mIsResumed == isResumed) {
                     return;
                 }
-                wait(5000);
+                wait(WAIT_TIMEOUT_MS);
             }
             assertEquals("The activity resume state change timed out", isResumed, mIsResumed);
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
index 53ede60..573e37a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -270,6 +270,7 @@
         assertEquals(WINDOWING_MODE_FULLSCREEN, token.getWindowingMode());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testFixedRotationRecentsAnimatingTask() {
         final RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
index 3c0dd1e..47e4559 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -46,6 +46,7 @@
 @RunWith(WindowTestRunner.class)
 public class WindowContainerTraversalTests extends WindowTestsBase {
 
+    @UseTestDisplay(addWindows = { W_DOCK_DIVIDER, W_INPUT_METHOD })
     @Test
     public void testDockedDividerPosition() {
         final WindowState splitScreenWindow = createWindowOnStack(null,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 1266c50..8fa3a12 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -145,10 +145,9 @@
     @Test
     public void testTaskFocusChange_stackHomeTypeWithDifferentTaskDisplayArea_focusChanges()
             throws RemoteException {
-        DisplayContent display = createNewDisplay();
-        TaskDisplayArea secondTda =
-                new TaskDisplayArea(display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST);
-        display.addChild(secondTda, 1);
+        final DisplayContent display = createNewDisplay();
+        final TaskDisplayArea secondTda = createTaskDisplayArea(
+                display, mWm, "Tapped TDA", FEATURE_VENDOR_FIRST);
         // Current focused window
         ActivityStack focusedStack = createTaskStackOnDisplay(
                 WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, display);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 04d52af..7cc19ad 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -521,6 +521,7 @@
         assertEquals(ACTIVITY_TYPE_UNDEFINED, info1.topActivityType);
     }
 
+    @UseTestDisplay
     @Test
     public void testTaskInfoCallback() {
         final ArrayList<RunningTaskInfo> lastReportedTiles = new ArrayList<>();
@@ -584,6 +585,7 @@
         assertEquals(ACTIVITY_TYPE_UNDEFINED, lastReportedTiles.get(0).topActivityType);
     }
 
+    @UseTestDisplay
     @Test
     public void testHierarchyTransaction() {
         final ArrayMap<IBinder, RunningTaskInfo> lastReportedTiles = new ArrayMap<>();
@@ -669,6 +671,14 @@
         assertEquals(1, lastReportedTiles.size());
         assertEquals(ACTIVITY_TYPE_HOME,
                 lastReportedTiles.get(info1.token.asBinder()).topActivityType);
+
+        // This just needs to not crash (ie. it should be possible to reparent to display twice)
+        wct = new WindowContainerTransaction();
+        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
+        wct = new WindowContainerTransaction();
+        wct.reparent(stack2.mRemoteToken.toWindowContainerToken(), null, true /* onTop */);
+        mWm.mAtmService.mWindowOrganizerController.applyTransaction(wct);
     }
 
     private List<Task> getTasksCreatedByOrganizer(DisplayContent dc) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 360d73b..ce9dd68 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -36,7 +36,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -417,10 +416,11 @@
         assertFalse(app.canAffectSystemUiFlags());
     }
 
+    @UseTestDisplay(addWindows = { W_ACTIVITY, W_STATUS_BAR })
     @Test
     public void testVisibleWithInsetsProvider() {
-        final WindowState statusBar = createWindow(null, TYPE_STATUS_BAR, "statusBar");
-        final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+        final WindowState statusBar = mStatusBarWindow;
+        final WindowState app = mAppWindow;
         statusBar.mHasSurface = true;
         assertTrue(statusBar.isVisible());
         mDisplayContent.getInsetsStateController().getSourceProvider(ITYPE_STATUS_BAR)
@@ -542,6 +542,7 @@
         assertTrue(window.isVisibleByPolicy());
     }
 
+    @UseTestDisplay(addWindows = { W_ABOVE_ACTIVITY, W_NOTIFICATION_SHADE })
     @Test
     public void testRequestDrawIfNeeded() {
         final WindowState startingApp = createWindow(null /* parent */,
@@ -567,6 +568,7 @@
         assertEquals(Arrays.asList(keyguardHostWindow, startingWindow), outWaitingForDrawn);
     }
 
+    @UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
     @Test
     public void testReportResizedWithRemoteException() {
         final WindowState win = mChildAppWindowAbove;
@@ -597,6 +599,7 @@
         assertFalse(win.getOrientationChanging());
     }
 
+    @UseTestDisplay(addWindows = W_ABOVE_ACTIVITY)
     @Test
     public void testRequestResizeForBlastSync() {
         final WindowState win = mChildAppWindowAbove;
@@ -677,6 +680,7 @@
         assertTrue(win0.cantReceiveTouchInput());
     }
 
+    @UseTestDisplay(addWindows = W_ACTIVITY)
     @Test
     public void testNeedsRelativeLayeringToIme_notAttached() {
         WindowState sameTokenWindow = createWindow(null, TYPE_BASE_APPLICATION, mAppWindow.mToken,
@@ -689,6 +693,7 @@
         assertFalse(sameTokenWindow.needsRelativeLayeringToIme());
     }
 
+    @UseTestDisplay(addWindows = { W_ACTIVITY, W_INPUT_METHOD })
     @Test
     public void testNeedsRelativeLayeringToIme_startingWindow() {
         WindowState sameTokenWindow = createWindow(null, TYPE_APPLICATION_STARTING,
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 156298c..0bbe0a0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -39,11 +39,11 @@
 
 import static org.mockito.Mockito.mock;
 
-import android.content.Context;
+import android.annotation.IntDef;
 import android.content.Intent;
+import android.hardware.display.DisplayManager;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.Log;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.IDisplayWindowInsetsController;
@@ -54,23 +54,36 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.server.AttributeCache;
 
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.runner.Description;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /** Common base class for window manager unit test classes. */
 class WindowTestsBase extends SystemServiceTestsBase {
-    private static final String TAG = WindowTestsBase.class.getSimpleName();
 
     WindowManagerService mWm;
     private final IWindow mIWindow = new TestIWindow();
     private Session mMockSession;
     static int sNextStackId = 1000;
 
-    /** Non-default display. */
-    DisplayContent mDisplayContent;
     DisplayInfo mDisplayInfo = new DisplayInfo();
+    DisplayContent mDefaultDisplay;
+
+    /**
+     * It is {@link #mDefaultDisplay} by default. If the test class or method is annotated with
+     * {@link UseTestDisplay}, it will be an additional display.
+     */
+    DisplayContent mDisplayContent;
+
+    // The following fields are only available depending on the usage of annotation UseTestDisplay.
     WindowState mWallpaperWindow;
     WindowState mImeWindow;
     WindowState mImeDialogWindow;
@@ -97,48 +110,82 @@
         mWm = mSystemServicesTestRule.getWindowManagerService();
         SystemServicesTestRule.checkHoldsLock(mWm.mGlobalLock);
 
+        mDefaultDisplay = mWm.mRoot.getDefaultDisplay();
         mTransaction = mSystemServicesTestRule.mTransaction;
         mMockSession = mock(Session.class);
-        final Context context = getInstrumentation().getTargetContext();
-        // If @Before throws an exception, the error isn't logged. This will make sure any failures
-        // in the set up are clear. This can be removed when b/37850063 is fixed.
-        try {
-            beforeCreateDisplay();
 
-            context.getDisplay().getDisplayInfo(mDisplayInfo);
-            mDisplayContent = createNewDisplay(true /* supportIme */);
+        getInstrumentation().getTargetContext().getSystemService(DisplayManager.class)
+                .getDisplay(Display.DEFAULT_DISPLAY).getDisplayInfo(mDisplayInfo);
 
-            // Set-up some common windows.
-            mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
-            mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
-            mDisplayContent.mInputMethodWindow = mImeWindow;
-            mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
-                    "mImeDialogWindow");
-            mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
-            mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
-                    "mNotificationShadeWindow");
-            mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
-            mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
-                    "mDockedDividerWindow");
-            mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
-            mChildAppWindowAbove = createCommonWindow(mAppWindow,
-                    TYPE_APPLICATION_ATTACHED_DIALOG,
-                    "mChildAppWindowAbove");
-            mChildAppWindowBelow = createCommonWindow(mAppWindow,
-                    TYPE_APPLICATION_MEDIA_OVERLAY,
-                    "mChildAppWindowBelow");
-            mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false);
-
-            // Adding a display will cause freezing the display. Make sure to wait until it's
-            // unfrozen to not run into race conditions with the tests.
-            waitUntilHandlersIdle();
-        } catch (Exception e) {
-            Log.e(TAG, "Failed to set up test", e);
-            throw e;
+        // Only create an additional test display for annotated test class/method because it may
+        // significantly increase the execution time.
+        final Description description = mSystemServicesTestRule.getDescription();
+        UseTestDisplay testDisplayAnnotation = description.getAnnotation(UseTestDisplay.class);
+        if (testDisplayAnnotation == null) {
+            testDisplayAnnotation = description.getTestClass().getAnnotation(UseTestDisplay.class);
+        }
+        if (testDisplayAnnotation != null) {
+            createTestDisplay(testDisplayAnnotation);
+        } else {
+            mDisplayContent = mDefaultDisplay;
         }
     }
 
-    void beforeCreateDisplay() {
+    private void createTestDisplay(UseTestDisplay annotation) {
+        beforeCreateTestDisplay();
+        mDisplayContent = createNewDisplay(true /* supportIme */);
+
+        final boolean addAll = annotation.addAllCommonWindows();
+        final @CommonTypes int[] requestedWindows = annotation.addWindows();
+
+        if (addAll || ArrayUtils.contains(requestedWindows, W_WALLPAPER)) {
+            mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD)) {
+            mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
+            mDisplayContent.mInputMethodWindow = mImeWindow;
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_INPUT_METHOD_DIALOG)) {
+            mImeDialogWindow = createCommonWindow(null, TYPE_INPUT_METHOD_DIALOG,
+                    "mImeDialogWindow");
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_STATUS_BAR)) {
+            mStatusBarWindow = createCommonWindow(null, TYPE_STATUS_BAR, "mStatusBarWindow");
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_NOTIFICATION_SHADE)) {
+            mNotificationShadeWindow = createCommonWindow(null, TYPE_NOTIFICATION_SHADE,
+                    "mNotificationShadeWindow");
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_NAVIGATION_BAR)) {
+            mNavBarWindow = createCommonWindow(null, TYPE_NAVIGATION_BAR, "mNavBarWindow");
+        }
+        if (addAll || ArrayUtils.contains(requestedWindows, W_DOCK_DIVIDER)) {
+            mDockedDividerWindow = createCommonWindow(null, TYPE_DOCK_DIVIDER,
+                    "mDockedDividerWindow");
+        }
+        final boolean addAboveApp = ArrayUtils.contains(requestedWindows, W_ABOVE_ACTIVITY);
+        final boolean addBelowApp = ArrayUtils.contains(requestedWindows, W_BELOW_ACTIVITY);
+        if (addAll || addAboveApp || addBelowApp
+                || ArrayUtils.contains(requestedWindows, W_ACTIVITY)) {
+            mAppWindow = createCommonWindow(null, TYPE_BASE_APPLICATION, "mAppWindow");
+        }
+        if (addAll || addAboveApp) {
+            mChildAppWindowAbove = createCommonWindow(mAppWindow, TYPE_APPLICATION_ATTACHED_DIALOG,
+                    "mChildAppWindowAbove");
+        }
+        if (addAll || addBelowApp) {
+            mChildAppWindowBelow = createCommonWindow(mAppWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
+                    "mChildAppWindowBelow");
+        }
+
+        mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(false);
+
+        // Adding a display will cause freezing the display. Make sure to wait until it's
+        // unfrozen to not run into race conditions with the tests.
+        waitUntilHandlersIdle();
+    }
+
+    void beforeCreateTestDisplay() {
         // Called before display is created.
     }
 
@@ -261,6 +308,20 @@
         }
     }
 
+    /** Creates a {@link TaskDisplayArea} right above the default one. */
+    static TaskDisplayArea createTaskDisplayArea(DisplayContent displayContent,
+            WindowManagerService service, String name, int displayAreaFeature) {
+        final TaskDisplayArea newTaskDisplayArea = new TaskDisplayArea(
+                displayContent, service, name, displayAreaFeature);
+        final TaskDisplayArea defaultTaskDisplayArea = displayContent.getDefaultTaskDisplayArea();
+
+        // Insert the new TDA to the correct position.
+        defaultTaskDisplayArea.getParent().addChild(newTaskDisplayArea,
+                defaultTaskDisplayArea.getParent().mChildren.indexOf(defaultTaskDisplayArea)
+                        + 1);
+        return newTaskDisplayArea;
+    }
+
     /** Creates a {@link ActivityStack} and adds it to the specified {@link DisplayContent}. */
     ActivityStack createTaskStackOnDisplay(DisplayContent dc) {
         return createTaskStackOnDisplay(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
@@ -378,4 +439,66 @@
     void removeGlobalMinSizeRestriction() {
         mWm.mAtmService.mRootWindowContainer.mDefaultMinSizeOfResizeableTaskDp = 1;
     }
+
+    /**
+     * Avoids rotating screen disturbed by some conditions. It is usually used for the default
+     * display that is not the instance of {@link TestDisplayContent} (it bypasses the conditions).
+     *
+     * @see DisplayRotation#updateRotationUnchecked
+     */
+    void unblockDisplayRotation(DisplayContent dc) {
+        mWm.stopFreezingDisplayLocked();
+        // The rotation animation won't actually play, it needs to be cleared manually.
+        dc.setRotationAnimation(null);
+    }
+
+    // The window definition for UseTestDisplay#addWindows. The test can declare to add only
+    // necessary windows, that avoids adding unnecessary overhead of unused windows.
+    static final int W_NOTIFICATION_SHADE = TYPE_NOTIFICATION_SHADE;
+    static final int W_STATUS_BAR = TYPE_STATUS_BAR;
+    static final int W_NAVIGATION_BAR = TYPE_NAVIGATION_BAR;
+    static final int W_INPUT_METHOD_DIALOG = TYPE_INPUT_METHOD_DIALOG;
+    static final int W_INPUT_METHOD = TYPE_INPUT_METHOD;
+    static final int W_DOCK_DIVIDER = TYPE_DOCK_DIVIDER;
+    static final int W_ABOVE_ACTIVITY = TYPE_APPLICATION_ATTACHED_DIALOG;
+    static final int W_ACTIVITY = TYPE_BASE_APPLICATION;
+    static final int W_BELOW_ACTIVITY = TYPE_APPLICATION_MEDIA_OVERLAY;
+    static final int W_WALLPAPER = TYPE_WALLPAPER;
+
+    /** The common window types supported by {@link UseTestDisplay}. */
+    @Retention(RetentionPolicy.RUNTIME)
+    @IntDef(value = {
+            W_NOTIFICATION_SHADE,
+            W_STATUS_BAR,
+            W_NAVIGATION_BAR,
+            W_INPUT_METHOD_DIALOG,
+            W_INPUT_METHOD,
+            W_DOCK_DIVIDER,
+            W_ABOVE_ACTIVITY,
+            W_ACTIVITY,
+            W_BELOW_ACTIVITY,
+            W_WALLPAPER,
+    })
+    @interface CommonTypes {
+    }
+
+    /**
+     * The annotation for class and method (higher priority) to create a non-default display that
+     * will be assigned to {@link #mDisplayContent}. It is used if the test needs
+     * <ul>
+     * <li>Pure empty display.</li>
+     * <li>Configured common windows.</li>
+     * <li>Independent and customizable orientation.</li>
+     * <li>Cross display operation.</li>
+     * </ul>
+     *
+     * @see TestDisplayContent
+     * @see #createTestDisplay
+     **/
+    @Target({ ElementType.METHOD, ElementType.TYPE })
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface UseTestDisplay {
+        boolean addAllCommonWindows() default false;
+        @CommonTypes int[] addWindows() default {};
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 5264e9a..cef202c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -142,6 +142,7 @@
         assertEquals(0, token.getWindowsCount());
     }
 
+    @UseTestDisplay(addWindows = { W_ACTIVITY, W_WALLPAPER })
     @Test
     public void testFinishFixedRotationTransform() {
         final WindowToken appToken = mAppWindow.mToken;
diff --git a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
index e6b4e0f..dfb7280 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ZOrderingTests.java
@@ -62,6 +62,7 @@
  */
 @SmallTest
 @Presubmit
+@WindowTestsBase.UseTestDisplay(addAllCommonWindows = true)
 @RunWith(WindowTestRunner.class)
 public class ZOrderingTests extends WindowTestsBase {
 
@@ -152,7 +153,7 @@
     private LayerRecordingTransaction mTransaction;
 
     @Override
-    void beforeCreateDisplay() {
+    void beforeCreateTestDisplay() {
         // We can't use @Before here because it may happen after WindowTestsBase @Before
         // which is after construction of the DisplayContent, meaning the HierarchyRecorder
         // would miss construction of the top-level layers.
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index 4b425bd..ef94c76 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -1718,7 +1718,6 @@
     ctor @Deprecated public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
-    method public final boolean isCapable(int);
     method public final void removeCapabilities(int);
   }
 
diff --git a/telephony/api/system-removed.txt b/telephony/api/system-removed.txt
index c7fd304..ae46075 100644
--- a/telephony/api/system-removed.txt
+++ b/telephony/api/system-removed.txt
@@ -1,11 +1,6 @@
 // Signature format: 2.0
 package android.telephony {
 
-  public final class PreciseDataConnectionState implements android.os.Parcelable {
-    method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
-    method @Deprecated public int getDataConnectionNetworkType();
-  }
-
   public class TelephonyManager {
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall();
     method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall();
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index bc987a6..71a1964 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -623,6 +623,10 @@
     }
 
     private static int getCarrierPrivilegeStatus(Context context, int subId, int uid) {
+        if (uid == Process.SYSTEM_UID || uid == Process.PHONE_UID) {
+            // Skip the check if it's one of these special uids
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+        }
         final long identity = Binder.clearCallingIdentity();
         try {
             TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 157e885..b617f6a 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2549,15 +2549,15 @@
     /**
      * List of 4 customized 5G SS reference signal received quality (SSRSRQ) thresholds.
      * <p>
-     * Reference: 3GPP TS 38.215
+     * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10
      * <p>
-     * 4 threshold integers must be within the boundaries [-20 dB, -3 dB], and the levels are:
+     * 4 threshold integers must be within the boundaries [-43 dB, 20 dB], and the levels are:
      * <UL>
-     *     <LI>"NONE: [-20, threshold1]"</LI>
+     *     <LI>"NONE: [-43, threshold1]"</LI>
      *     <LI>"POOR: (threshold1, threshold2]"</LI>
      *     <LI>"MODERATE: (threshold2, threshold3]"</LI>
      *     <LI>"GOOD:  (threshold3, threshold4]"</LI>
-     *     <LI>"EXCELLENT:  (threshold4, -3]"</LI>
+     *     <LI>"EXCELLENT:  (threshold4, 20]"</LI>
      * </UL>
      * <p>
      * This key is considered invalid if the format is violated. If the key is invalid or
@@ -3216,6 +3216,17 @@
             "5g_icon_display_secondary_grace_period_string";
 
     /**
+     * Whether device reset all of NR timers when device camped on a network that haven't 5G
+     * capability and RRC currently in IDLE state.
+     *
+     * The default value is false;
+     *
+     * @hide
+     */
+    public static final String KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL =
+            "nr_timers_reset_if_non_endc_and_rrc_idle_bool";
+
+    /**
      * Controls time in milliseconds until DcTracker reevaluates 5G connection state.
      * @hide
      */
@@ -4284,12 +4295,12 @@
                     -65,  /* SIGNAL_STRENGTH_GREAT */
                 });
         sDefaults.putIntArray(KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
-                // Boundaries: [-20 dB, -3 dB]
+                // Boundaries: [-43 dB, 20 dB]
                 new int[] {
-                    -16, /* SIGNAL_STRENGTH_POOR */
-                    -12, /* SIGNAL_STRENGTH_MODERATE */
-                    -9, /* SIGNAL_STRENGTH_GOOD */
-                    -6  /* SIGNAL_STRENGTH_GREAT */
+                    -31, /* SIGNAL_STRENGTH_POOR */
+                    -19, /* SIGNAL_STRENGTH_MODERATE */
+                    -7, /* SIGNAL_STRENGTH_GOOD */
+                    6  /* SIGNAL_STRENGTH_GREAT */
                 });
         sDefaults.putIntArray(KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
                 // Boundaries: [-23 dB, 40 dB]
@@ -4326,6 +4337,7 @@
                         + "not_restricted_rrc_con:5G");
         sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, "");
         sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, "");
+        sDefaults.putBoolean(KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL, false);
         /* Default value is 1 hour. */
         sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
         sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false);
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 4e4abd0..aa12301 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -46,7 +46,14 @@
      *
      * Callers wishing to request a single location update should use
      * {@link TelephonyManager#requestCellInfoUpdate}.
+     *
+     * @deprecated this method has undesirable side-effects, and it calls into the OS without
+     * access to a {@link android.content.Context Context}, meaning that certain safety checks and
+     * attribution are error-prone. Given that this method has numerous downsides, and given that
+     * there are long-available superior alternatives, callers are strongly discouraged from using
+     * this method.
      */
+    @Deprecated
     public static void requestLocationUpdate() {
         // Since this object doesn't have a context, this is the best we can do.
         final Context appContext = ActivityThread.currentApplication();
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 95fe90a..8e50bba 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -54,12 +54,12 @@
     };
 
     // Lifted from Default carrier configs and max range of SSRSRQ
-    // Boundaries: [-20 dB, -3 dB]
+    // Boundaries: [-43 dB, 20 dB]
     private int[] mSsRsrqThresholds = new int[] {
-            -16, /* SIGNAL_STRENGTH_POOR */
-            -12, /* SIGNAL_STRENGTH_MODERATE */
-            -9, /* SIGNAL_STRENGTH_GOOD */
-            -6  /* SIGNAL_STRENGTH_GREAT */
+            -31, /* SIGNAL_STRENGTH_POOR */
+            -19, /* SIGNAL_STRENGTH_MODERATE */
+            -7, /* SIGNAL_STRENGTH_GOOD */
+            6  /* SIGNAL_STRENGTH_GREAT */
     };
 
     // Lifted from Default carrier configs and max range of SSSINR
@@ -183,8 +183,8 @@
     }
 
     /**
-     * Reference: 3GPP TS 38.215.
-     * Range: -20 dB to -3 dB.
+     * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10
+     * Range: -43 dB to 20 dB.
      * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
      * value.
      */
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 31a83c9..e0b5779 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -572,7 +572,8 @@
         return "Unknown reg state " + registrationState;
     }
 
-    private static String nrStateToString(@NRState int nrState) {
+    /** @hide */
+    public static String nrStateToString(@NRState int nrState) {
         switch (nrState) {
             case NR_STATE_RESTRICTED:
                 return "RESTRICTED";
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index b682bdd..8660e38 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -169,19 +169,6 @@
     /**
      * Returns the network type associated with this data connection.
      *
-     * @deprecated use {@link getNetworkType()}
-     * @hide
-     * @removed Removed from the R preview SDK but was never part of the stable API surface.
-     */
-    @Deprecated
-    @SystemApi
-    public @NetworkType int getDataConnectionNetworkType() {
-        return mNetworkType;
-    }
-
-    /**
-     * Returns the network type associated with this data connection.
-     *
      * Return the current/latest (radio) bearer technology that carries this data connection.
      * For a variety of reasons, the network type can change during the life of the data
      * connection, and this information is not reliable unless the physical link is currently
@@ -220,20 +207,6 @@
 
     /**
      * Get the properties of the network link {@link LinkProperties}.
-     *
-     * @deprecated use {@link #getLinkProperties()}
-     * @hide
-     * @removed Removed from the R preview SDK but was never part of the stable API surface.
-     */
-    @Deprecated
-    @SystemApi
-    @Nullable
-    public LinkProperties getDataConnectionLinkProperties() {
-        return mLinkProperties;
-    }
-
-    /**
-     * Get the properties of the network link {@link LinkProperties}.
      */
     @Nullable
     public LinkProperties getLinkProperties() {
diff --git a/telephony/java/android/telephony/SmsCbEtwsInfo.java b/telephony/java/android/telephony/SmsCbEtwsInfo.java
index 2a7f7ad..a98916d 100644
--- a/telephony/java/android/telephony/SmsCbEtwsInfo.java
+++ b/telephony/java/android/telephony/SmsCbEtwsInfo.java
@@ -27,6 +27,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.time.DateTimeException;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 import java.util.Arrays;
@@ -173,7 +174,7 @@
     /**
      * Returns the Warning-Security-Information timestamp (GSM primary notifications only).
      * As of Release 10, 3GPP TS 23.041 states that the UE shall ignore this value if received.
-     * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present
+     * @return a UTC timestamp in System.currentTimeMillis() format, or 0 if not present or invalid.
      */
     public long getPrimaryNotificationTimestamp() {
         if (mWarningSecurityInformation == null || mWarningSecurityInformation.length < 7) {
@@ -201,18 +202,23 @@
         // timezoneOffset is in quarter hours.
         int timeZoneOffsetSeconds = timezoneOffset * 15 * 60;
 
-        LocalDateTime localDateTime = LocalDateTime.of(
-                // We only need to support years above 2000.
-                year + 2000,
-                month /* 1-12 */,
-                day,
-                hour,
-                minute,
-                second);
+        try {
+            LocalDateTime localDateTime = LocalDateTime.of(
+                    // We only need to support years above 2000.
+                    year + 2000,
+                    month /* 1-12 */,
+                    day,
+                    hour,
+                    minute,
+                    second);
 
-        long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
-        // Convert to milliseconds, ignore overflow.
-        return epochSeconds * 1000;
+            long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+            // Convert to milliseconds, ignore overflow.
+            return epochSeconds * 1000;
+        } catch (DateTimeException ex) {
+            // No-op
+        }
+        return 0;
     }
 
     /**
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index b376660..183fdcc 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -670,10 +670,12 @@
         }
 
         if (priority < 0x00 || priority > 0x03) {
+            Log.e(TAG, "Invalid Priority " + priority);
             priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
         }
 
         if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            Log.e(TAG, "Invalid Validity Period " + validityPeriod);
             validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
         }
 
@@ -1231,10 +1233,12 @@
         }
 
         if (priority < 0x00 || priority > 0x03) {
+            Log.e(TAG, "Invalid Priority " + priority);
             priority = SMS_MESSAGE_PRIORITY_NOT_SPECIFIED;
         }
 
         if (validityPeriod < 0x05 || validityPeriod > 0x09b0a0) {
+            Log.e(TAG, "Invalid Validity Period " + validityPeriod);
             validityPeriod = SMS_MESSAGE_PERIOD_NOT_SPECIFIED;
         }
 
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 347dcc8..717a9b1 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -255,28 +255,6 @@
     }
 
     /**
-     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
-     * +CMT unsolicited response (PDU mode, of course)
-     *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
-     *
-     * Only public for debugging and for RIL
-     *
-     * {@hide}
-     */
-    public static SmsMessage newFromCMT(byte[] pdu) {
-        // received SMS in 3GPP format
-        SmsMessageBase wrappedMessage =
-                com.android.internal.telephony.gsm.SmsMessage.newFromCMT(pdu);
-
-        if (wrappedMessage != null) {
-            return new SmsMessage(wrappedMessage);
-        } else {
-            Rlog.e(LOG_TAG, "newFromCMT(): wrappedMessage is null");
-            return null;
-        }
-    }
-
-    /**
      * Creates an SmsMessage from an SMS EF record.
      *
      * @param index Index of SMS EF record.
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 01d468c..de0fb86 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -285,8 +285,8 @@
         public static final int CAPABILITY_TYPE_SMS = 1 << 3;
 
         /**
-        * @hide
-        */
+         * @hide
+         */
         @Override
         @SystemApi @TestApi
         public final void addCapabilities(@MmTelCapability int capabilities) {
@@ -294,8 +294,8 @@
         }
 
         /**
-        * @hide
-        */
+         * @hide
+         */
         @Override
         @SystemApi @TestApi
         public final void removeCapabilities(@MmTelCapability int capability) {
@@ -303,17 +303,18 @@
         }
 
         /**
-        * @hide
-        */
+         * @param capabilities a bitmask of one or more {@link MmTelCapability}.
+         *
+         * @return true if all queried capabilities are true, otherwise false.
+         */
         @Override
-        @SystemApi @TestApi
         public final boolean isCapable(@MmTelCapability int capabilities) {
             return super.isCapable(capabilities);
         }
 
         /**
-        * @hide
-        */
+         * @hide
+         */
         @NonNull
         @Override
         public String toString() {
diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
index 3bd8cdd..f8ab87d 100644
--- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
+++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
@@ -65,13 +65,7 @@
             return "";
         }
 
-        if (!mIs7BitTranslationTableLoaded) {
-            mTranslationTableCommon = new SparseIntArray();
-            mTranslationTableGSM = new SparseIntArray();
-            mTranslationTableCDMA = new SparseIntArray();
-            load7BitTranslationTableFromXml();
-            mIs7BitTranslationTableLoaded = true;
-        }
+        ensure7BitTranslationTableLoaded();
 
         if ((mTranslationTableCommon != null && mTranslationTableCommon.size() > 0) ||
                 (mTranslationTableGSM != null && mTranslationTableGSM.size() > 0) ||
@@ -115,6 +109,8 @@
          */
         int translation = -1;
 
+        ensure7BitTranslationTableLoaded();
+
         if (mTranslationTableCommon != null) {
             translation = mTranslationTableCommon.get(c, -1);
         }
@@ -155,6 +151,18 @@
         }
     }
 
+    private static void ensure7BitTranslationTableLoaded() {
+        synchronized (Sms7BitEncodingTranslator.class) {
+            if (!mIs7BitTranslationTableLoaded) {
+                mTranslationTableCommon = new SparseIntArray();
+                mTranslationTableGSM = new SparseIntArray();
+                mTranslationTableCDMA = new SparseIntArray();
+                load7BitTranslationTableFromXml();
+                mIs7BitTranslationTableLoaded = true;
+            }
+        }
+    }
+
     /**
      * Load the whole translation table file from the framework resource
      * encoded in XML.
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index 4fbafb7..d186fcf 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -35,6 +35,7 @@
 import com.android.telephony.Rlog;
 
 import java.io.ByteArrayOutputStream;
+import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -315,10 +316,16 @@
         }
 
         public long toMillis() {
-            LocalDateTime localDateTime =
-                    LocalDateTime.of(year, monthOrdinal, monthDay, hour, minute, second);
-            Instant instant = localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime));
-            return instant.toEpochMilli();
+            try {
+                LocalDateTime localDateTime =
+                        LocalDateTime.of(year, monthOrdinal, monthDay, hour, minute, second);
+                Instant instant =
+                        localDateTime.toInstant(mZoneId.getRules().getOffset(localDateTime));
+                return instant.toEpochMilli();
+            } catch (DateTimeException ex) {
+                Rlog.e(LOG_TAG, "Invalid timestamp", ex);
+            }
+            return 0;
         }
 
 
@@ -1093,7 +1100,7 @@
             bData.hasUserDataHeader = (inStream.read(1) == 1);
             inStream.skip(3);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "MESSAGE_IDENTIFIER decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1462,7 +1469,7 @@
             bData.reportReq      = (inStream.read(1) == 1);
             inStream.skip(4);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "REPLY_OPTION decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1481,7 +1488,7 @@
             decodeSuccess = true;
             bData.numberOfMessages = IccUtils.cdmaBcdByteToInt((byte)inStream.read(8));
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "NUMBER_OF_MESSAGES decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1500,7 +1507,7 @@
             decodeSuccess = true;
             bData.depositIndex = (inStream.read(8) << 8) | inStream.read(8);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "MESSAGE_DEPOSIT_INDEX decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1587,7 +1594,7 @@
             bData.errorClass = inStream.read(2);
             bData.messageStatus = inStream.read(6);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "MESSAGE_STATUS decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1607,7 +1614,7 @@
             decodeSuccess = true;
             bData.msgCenterTimeStamp = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "MESSAGE_CENTER_TIME_STAMP decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1626,7 +1633,7 @@
             decodeSuccess = true;
             bData.validityPeriodAbsolute = TimeStamp.fromByteArray(inStream.readByteArray(6 * 8));
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "VALIDITY_PERIOD_ABSOLUTE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1646,7 +1653,7 @@
             bData.deferredDeliveryTimeAbsolute = TimeStamp.fromByteArray(
                     inStream.readByteArray(6 * 8));
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_ABSOLUTE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1665,7 +1672,7 @@
             decodeSuccess = true;
             bData.deferredDeliveryTimeRelative = inStream.read(8);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "VALIDITY_PERIOD_RELATIVE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1685,7 +1692,7 @@
             decodeSuccess = true;
             bData.validityPeriodRelative = inStream.read(8);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "DEFERRED_DELIVERY_TIME_RELATIVE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1706,7 +1713,7 @@
             bData.privacy = inStream.read(2);
             inStream.skip(6);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "PRIVACY_INDICATOR decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1726,7 +1733,7 @@
             decodeSuccess = true;
             bData.language = inStream.read(8);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "LANGUAGE_INDICATOR decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1747,7 +1754,7 @@
             bData.displayMode = inStream.read(2);
             inStream.skip(6);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "DISPLAY_MODE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1768,7 +1775,7 @@
             bData.priority = inStream.read(2);
             inStream.skip(6);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "PRIORITY_INDICATOR decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1789,7 +1796,7 @@
             bData.alert = inStream.read(2);
             inStream.skip(6);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "ALERT_ON_MESSAGE_DELIVERY decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1809,7 +1816,7 @@
             decodeSuccess = true;
             bData.userResponseCode = inStream.read(8);
         }
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "USER_RESPONSE_CODE decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ")");
@@ -1871,7 +1878,7 @@
             decodeSuccess = true;
         }
 
-        if ((! decodeSuccess) || (paramBits > 0)) {
+        if ((!decodeSuccess) || (paramBits > 0)) {
             Rlog.d(LOG_TAG, "SERVICE_CATEGORY_PROGRAM_DATA decode " +
                       (decodeSuccess ? "succeeded" : "failed") +
                       " (extra bits = " + paramBits + ')');
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index ccb1474..7e31c46 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -43,6 +43,7 @@
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
 import java.text.ParseException;
+import java.time.DateTimeException;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
@@ -91,14 +92,15 @@
 
     private int mVoiceMailCount = 0;
 
+    /** TP-Validity-Period-Format (TP-VPF). See TS 23.040, 9.2.3.3 */
     private static final int VALIDITY_PERIOD_FORMAT_NONE = 0x00;
     private static final int VALIDITY_PERIOD_FORMAT_ENHANCED = 0x01;
     private static final int VALIDITY_PERIOD_FORMAT_RELATIVE = 0x02;
     private static final int VALIDITY_PERIOD_FORMAT_ABSOLUTE = 0x03;
 
-    //Validity Period min - 5 mins
+    // Validity Period min - 5 mins
     private static final int VALIDITY_PERIOD_MIN = 5;
-    //Validity Period max - 63 weeks
+    // Validity Period max - 63 weeks
     private static final int VALIDITY_PERIOD_MAX = 635040;
 
     private static final int INVALID_VALIDITY_PERIOD = -1;
@@ -139,38 +141,6 @@
     }
 
     /**
-     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
-     * +CMT unsolicited response (PDU mode, of course)
-     *  +CMT: [&lt;alpha>],<length><CR><LF><pdu>
-     *
-     * Only public for debugging
-     *
-     * {@hide}
-     */
-    public static SmsMessage newFromCMT(byte[] pdu) {
-        try {
-            SmsMessage msg = new SmsMessage();
-            msg.parsePdu(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Rlog.e(LOG_TAG, "SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /** @hide */
-    public static SmsMessage newFromCDS(byte[] pdu) {
-        try {
-            SmsMessage msg = new SmsMessage();
-            msg.parsePdu(pdu);
-            return msg;
-        } catch (RuntimeException ex) {
-            Rlog.e(LOG_TAG, "CDS SMS PDU parsing failed: ", ex);
-            return null;
-        }
-    }
-
-    /**
      * Creates an SmsMessage from an SMS EF record.
      *
      * @param index Index of SMS EF record.
@@ -224,20 +194,20 @@
     }
 
     /**
-     * Get Encoded Relative Validty Period Value from Validity period in mins.
+     * Gets Encoded Relative Validity Period Value from Validity period in mins.
      *
      * @param validityPeriod Validity period in mins.
      *
      * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1.
-     * ||relValidityPeriod (TP-VP)  ||                 ||  validityPeriod   ||
-     *
-     *      0 to 143                            --->       (TP-VP + 1) x 5 minutes
-     *
-     *      144 to 167                         --->        12 hours + ((TP-VP -143) x 30 minutes)
-     *
-     *      168 to 196                         --->        (TP-VP - 166) x 1 day
-     *
-     *      197 to 255                         --->        (TP-VP - 192) x 1 week
+     * ------------------------------------------------------------
+     *        TP-VP       |            Validity period
+     *  (Relative format) |                 value
+     * ------------------------------------------------------------
+     *  0 to 143          | (TP-VP + 1) x 5 minutes
+     *  144 to 167        | 12 hours + ((TP-VP -143) x 30 minutes)
+     *  168 to 196        | (TP-VP - 166) x 1 day
+     *  197 to 255        | (TP-VP - 192) x 1 week
+     * ------------------------------------------------------------
      *
      * @return relValidityPeriod Encoded Relative Validity Period Value.
      * @hide
@@ -245,19 +215,16 @@
     public static int getRelativeValidityPeriod(int validityPeriod) {
         int relValidityPeriod = INVALID_VALIDITY_PERIOD;
 
-        if (validityPeriod < VALIDITY_PERIOD_MIN  || validityPeriod > VALIDITY_PERIOD_MAX) {
-            Rlog.e(LOG_TAG,"Invalid Validity Period" + validityPeriod);
-            return relValidityPeriod;
-        }
-
-        if (validityPeriod <= 720) {
-            relValidityPeriod = (validityPeriod  / 5) - 1;
-        } else if (validityPeriod <= 1440) {
-            relValidityPeriod = ((validityPeriod - 720) / 30) + 143;
-        } else if (validityPeriod <= 43200) {
-            relValidityPeriod = (validityPeriod  / 1440) + 166;
-        } else if (validityPeriod <= 635040) {
-            relValidityPeriod = (validityPeriod  / 10080) + 192;
+        if (validityPeriod >= VALIDITY_PERIOD_MIN) {
+            if (validityPeriod <= 720) {
+                relValidityPeriod = (validityPeriod / 5) - 1;
+            } else if (validityPeriod <= 1440) {
+                relValidityPeriod = ((validityPeriod - 720) / 30) + 143;
+            } else if (validityPeriod <= 43200) {
+                relValidityPeriod = (validityPeriod / 1440) + 166;
+            } else if (validityPeriod <= VALIDITY_PERIOD_MAX) {
+                relValidityPeriod = (validityPeriod / 10080) + 192;
+            }
         }
         return relValidityPeriod;
     }
@@ -367,17 +334,19 @@
 
         SubmitPdu ret = new SubmitPdu();
 
-        int validityPeriodFormat = VALIDITY_PERIOD_FORMAT_NONE;
-        int relativeValidityPeriod = INVALID_VALIDITY_PERIOD;
+        int relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod);
 
-        // TP-Validity-Period-Format (TP-VPF) in 3GPP TS 23.040 V6.8.1 section 9.2.3.3
-        //bit 4:3 = 10 - TP-VP field present - relative format
-        if((relativeValidityPeriod = getRelativeValidityPeriod(validityPeriod)) >= 0) {
-            validityPeriodFormat = VALIDITY_PERIOD_FORMAT_RELATIVE;
+        byte mtiByte = 0x01; // SMS-SUBMIT
+
+        if (header != null) {
+            // Set TP-UDHI
+            mtiByte |= 0x40;
         }
 
-        byte mtiByte = (byte)(0x01 | (validityPeriodFormat << 0x03) |
-                (header != null ? 0x40 : 0x00));
+        if (relativeValidityPeriod != INVALID_VALIDITY_PERIOD) {
+            // Set TP-Validity-Period-Format (TP-VPF)
+            mtiByte |= VALIDITY_PERIOD_FORMAT_RELATIVE << 3;
+        }
 
         ByteArrayOutputStream bo = getSubmitPduHead(
                 scAddress, destinationAddress, mtiByte,
@@ -449,8 +418,8 @@
             bo.write(0x08);
         }
 
-        if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) {
-            // ( TP-Validity-Period - relative format)
+        // TP-Validity-Period (TP-VP)
+        if (relativeValidityPeriod != INVALID_VALIDITY_PERIOD) {
             bo.write(relativeValidityPeriod);
         }
 
@@ -887,10 +856,9 @@
         }
 
         /**
-         * Parses an SC timestamp and returns a currentTimeMillis()-style
-         * timestamp
+         * Parses an SC timestamp and returns a currentTimeMillis()-style timestamp, or 0 if
+         * invalid.
          */
-
         long getSCTimestampMillis() {
             // TP-Service-Centre-Time-Stamp
             int year = IccUtils.gsmBcdByteToInt(mPdu[mCur++]);
@@ -916,16 +884,22 @@
 
             // It's 2006.  Should I really support years < 2000?
             int fullYear = year >= 90 ? year + 1900 : year + 2000;
-            LocalDateTime localDateTime = LocalDateTime.of(
-                    fullYear,
-                    month /* 1-12 */,
-                    day,
-                    hour,
-                    minute,
-                    second);
-            long epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
-            // Convert to milliseconds.
-            return epochSeconds * 1000;
+            try {
+                LocalDateTime localDateTime = LocalDateTime.of(
+                        fullYear,
+                        month /* 1-12 */,
+                        day,
+                        hour,
+                        minute,
+                        second);
+                long epochSeconds =
+                        localDateTime.toEpochSecond(ZoneOffset.UTC) - timeZoneOffsetSeconds;
+                // Convert to milliseconds.
+                return epochSeconds * 1000;
+            } catch (DateTimeException ex) {
+                Rlog.e(LOG_TAG, "Invalid timestamp", ex);
+            }
+            return 0;
         }
 
         /**
@@ -1276,6 +1250,7 @@
         mRecipientAddress = p.getAddress();
         // TP-Service-Centre-Time-Stamp
         mScTimeMillis = p.getSCTimestampMillis();
+        // TP-Discharge-Time
         p.getSCTimestampMillis();
         // TP-Status
         mStatus = p.getByte();
@@ -1334,6 +1309,7 @@
                     + " data coding scheme: " + mDataCodingScheme);
         }
 
+        // TP-Service-Centre-Time-Stamp
         mScTimeMillis = p.getSCTimestampMillis();
 
         if (VDBG) Rlog.d(LOG_TAG, "SMS SC timestamp: " + mScTimeMillis);
@@ -1376,23 +1352,17 @@
 
         // TP-Validity-Period-Format
         int validityPeriodLength = 0;
-        int validityPeriodFormat = ((firstByte>>3) & 0x3);
-        if (0x0 == validityPeriodFormat) /* 00, TP-VP field not present*/
-        {
+        int validityPeriodFormat = ((firstByte >> 3) & 0x3);
+        if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_NONE) {
             validityPeriodLength = 0;
-        }
-        else if (0x2 == validityPeriodFormat) /* 10, TP-VP: relative format*/
-        {
+        } else if (validityPeriodFormat == VALIDITY_PERIOD_FORMAT_RELATIVE) {
             validityPeriodLength = 1;
-        }
-        else /* other case, 11 or 01, TP-VP: absolute or enhanced format*/
-        {
+        } else { // VALIDITY_PERIOD_FORMAT_ENHANCED or VALIDITY_PERIOD_FORMAT_ABSOLUTE
             validityPeriodLength = 7;
         }
 
         // TP-Validity-Period is not used on phone, so just ignore it for now.
-        while (validityPeriodLength-- > 0)
-        {
+        while (validityPeriodLength-- > 0) {
             p.getByte();
         }
 
diff --git a/tests/FlickerTests/Android.bp b/tests/FlickerTests/Android.bp
index baff952..070dacb 100644
--- a/tests/FlickerTests/Android.bp
+++ b/tests/FlickerTests/Android.bp
@@ -16,7 +16,7 @@
 
 android_test {
     name: "FlickerTests",
-    srcs: ["src/**/*.java"],
+    srcs: ["src/**/*.java", "src/**/*.kt"],
     manifest: "AndroidManifest.xml",
     test_config: "AndroidTest.xml",
     platform_apis: true,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
deleted file mode 100644
index ed6f33e..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation;
-import static com.android.server.wm.flicker.WindowUtils.getAppPosition;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition;
-import static com.android.server.wm.flicker.WindowUtils.getStatusBarPosition;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import android.graphics.Rect;
-import android.util.Log;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Cycle through supported app rotations.
- * To run this test: {@code atest FlickerTest:ChangeAppRotationTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class ChangeAppRotationTest extends FlickerTestBase {
-    private int mBeginRotation;
-    private int mEndRotation;
-
-    public ChangeAppRotationTest(String beginRotationName, String endRotationName,
-            int beginRotation, int endRotation) {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-        this.mBeginRotation = beginRotation;
-        this.mEndRotation = endRotation;
-    }
-
-    @Parameters(name = "{0}-{1}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-        for (int begin : supportedRotations) {
-            for (int end : supportedRotations) {
-                if (begin != end) {
-                    params.add(new Object[]{rotationToString(begin), rotationToString(end), begin,
-                            end});
-                }
-            }
-        }
-        return params;
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return changeAppRotation(mTestApp, mUiDevice, mBeginRotation, mEndRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkPosition_navBarLayerRotatesAndScales() {
-        Rect startingPos = getNavigationBarPosition(mBeginRotation);
-        Rect endingPos = getNavigationBarPosition(mEndRotation);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                            .inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Test
-    public void checkPosition_appLayerRotates() {
-        Rect startingPos = getAppPosition(mBeginRotation);
-        Rect endingPos = getAppPosition(mEndRotation);
-        Log.e(TAG, "startingPos=" + startingPos + " endingPos=" + endingPos);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(mTestApp.getPackage(), startingPos).inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(mTestApp.getPackage(), endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Test
-    public void checkPosition_statusBarLayerScales() {
-        Rect startingPos = getStatusBarPosition(mBeginRotation);
-        Rect endingPos = getStatusBarPosition(mEndRotation);
-        checkResults(result -> {
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
-                            .inTheBeginning();
-                    LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd();
-                }
-        );
-    }
-
-    @Ignore("Flaky. Pending debug")
-    @Test
-    public void checkVisibility_screenshotLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .replaceVisibleLayer(mTestApp.getPackage(), SCREENSHOT_LAYER)
-                .then()
-                .showsLayer(mTestApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER)
-                .then()
-                .replaceVisibleLayer(SCREENSHOT_LAYER, mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
deleted file mode 100644
index 58dcb99..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeAutoOpenWindowToAppTest extends CloseImeWindowToAppTest {
-
-    public CloseImeAutoOpenWindowToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToApp((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppLayerIsAlwaysVisible() {
-        super.checkVisibility_imeAppLayerIsAlwaysVisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppWindowIsAlwaysVisible() {
-        super.checkVisibility_imeAppWindowIsAlwaysVisible();
-    }
-
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
deleted file mode 100644
index 7f610a6..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeAutoOpenWindowToHomeTest extends CloseImeWindowToHomeTest {
-
-    public CloseImeAutoOpenWindowToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToHome((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeWindowBecomesInvisible() {
-        super.checkVisibility_imeWindowBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 141458352)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        super.checkVisibility_imeLayerBecomesInvisible();
-    }
-
-    @FlakyTest(bugId = 157449248)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_imeAppWindowBecomesInvisible() {
-        super.checkVisibility_imeAppWindowBecomesInvisible();
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
deleted file mode 100644
index 57ad7e7..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing back to app window transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeWindowToAppTest extends NonRotationTestBase {
-
-    static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public CloseImeWindowToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToApp((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Ignore("Flaky. Pending debug")
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(IME_WINDOW_TITLE)
-                .then()
-                .hidesLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
deleted file mode 100644
index 12d1179..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window closing to home transitions.
- * To run this test: {@code atest FlickerTests:CloseImeWindowToHomeTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class CloseImeWindowToHomeTest extends NonRotationTestBase {
-
-    static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public CloseImeWindowToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextLoseFocusToHome((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_imeWindowBecomesInvisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsImeWindow(IME_WINDOW_TITLE)
-                .then()
-                .hidesImeWindow(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 153739621)
-    @Ignore
-    @Test
-    public void checkVisibility_imeLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(IME_WINDOW_TITLE)
-                .then()
-                .hidesLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 153739621)
-    @Ignore
-    @Test
-    public void checkVisibility_imeAppLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .hidesLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeAppWindowBecomesInvisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .then()
-                .hidesAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
deleted file mode 100644
index b1854c3..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static android.os.SystemClock.sleep;
-import static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.clearRecents;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.expandPipWindow;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.launchSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.stopPackage;
-
-import android.app.Instrumentation;
-import android.content.Context;
-import android.content.Intent;
-import android.os.RemoteException;
-import android.platform.helpers.IAppHelper;
-import android.util.Rational;
-import android.view.Surface;
-
-import androidx.annotation.Nullable;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder;
-import com.android.server.wm.flicker.helpers.AutomationUtils;
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-/**
- * Collection of common transitions which can be used to test different apps or scenarios.
- */
-class CommonTransitions {
-
-    public static final int ITERATIONS = 1;
-    private static final String TAG = "FLICKER";
-    private static final long APP_LAUNCH_TIMEOUT = 10000;
-
-    private static void setRotation(UiDevice device, int rotation) {
-        try {
-            switch (rotation) {
-                case Surface.ROTATION_270:
-                    device.setOrientationLeft();
-                    break;
-
-                case Surface.ROTATION_90:
-                    device.setOrientationRight();
-                    break;
-
-                case Surface.ROTATION_0:
-                default:
-                    device.setOrientationNatural();
-            }
-            // Wait for animation to complete
-            sleep(1000);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Build a test tag for the test
-     * @param testName Name of the transition(s) being tested
-     * @param app App being launcher
-     * @param rotation Initial screen rotation
-     *
-     * @return test tag with pattern <NAME>__<APP>__<ROTATION>
-     */
-    private static String buildTestTag(String testName, IAppHelper app, int rotation) {
-        return buildTestTag(
-                testName, app, /* app2 */ null, rotation, rotation, /* description */ "");
-    }
-
-    /**
-     * Build a test tag for the test
-     * @param testName Name of the transition(s) being tested
-     * @param app App being launcher
-     * @param beginRotation Initial screen rotation
-     * @param endRotation End screen rotation (if any, otherwise use same as initial)
-     *
-     * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION>
-     */
-    private static String buildTestTag(String testName, IAppHelper app, int beginRotation,
-            int endRotation) {
-        return buildTestTag(
-                testName, app, /* app2 */ null, beginRotation, endRotation, /* description */ "");
-    }
-
-    /**
-     * Build a test tag for the test
-     * @param testName Name of the transition(s) being tested
-     * @param app App being launcher
-     * @param app2 Second app being launched (if any)
-     * @param beginRotation Initial screen rotation
-     * @param endRotation End screen rotation (if any, otherwise use same as initial)
-     * @param extraInfo Additional information to append to the tag
-     *
-     * @return test tag with pattern <NAME>__<APP(S)>__<ROTATION(S)>[__<EXTRA>]
-     */
-    private static String buildTestTag(String testName, IAppHelper app, @Nullable IAppHelper app2,
-            int beginRotation, int endRotation, String extraInfo) {
-        StringBuilder testTag = new StringBuilder();
-        testTag.append(testName)
-                .append("__")
-                .append(app.getLauncherName());
-
-        if (app2 != null) {
-            testTag.append("-")
-                    .append(app2.getLauncherName());
-        }
-
-        testTag.append("__")
-                .append(rotationToString(beginRotation));
-
-        if (endRotation != beginRotation) {
-            testTag.append("-")
-                    .append(rotationToString(endRotation));
-        }
-
-        if (!extraInfo.isEmpty()) {
-            testTag.append("__")
-                    .append(extraInfo);
-        }
-
-        return testTag.toString();
-    }
-
-    static TransitionBuilder openAppWarm(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("openAppWarm", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBeforeAll(testApp::open)
-                .runBefore(device::pressHome)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .run(testApp::open)
-                .runAfterAll(testApp::exit)
-                .runAfterAll(AutomationUtils::setDefaultWait)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder closeAppWithBackKey(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .run(device::pressBack)
-                .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
-                .runAfterAll(AutomationUtils::setDefaultWait)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder closeAppWithHomeKey(IAppHelper testApp, UiDevice
-            device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .run(device::pressHome)
-                .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
-                .runAfterAll(AutomationUtils::setDefaultWait)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder openAppCold(IAppHelper testApp,
-            UiDevice device, int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("openAppCold", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::exit)
-                .runBefore(device::waitForIdle)
-                .run(testApp::open)
-                .runAfterAll(testApp::exit)
-                .runAfterAll(() -> setRotation(device, Surface.ROTATION_0))
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder changeAppRotation(IAppHelper testApp, UiDevice
-            device, int beginRotation, int endRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(testApp::open)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .run(() -> setRotation(device, endRotation))
-                .runAfterAll(testApp::exit)
-                .runAfterAll(() -> setRotation(device, Surface.ROTATION_0))
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder changeAppRotation(Intent intent, String intentId, Context context,
-            UiDevice device, int beginRotation, int endRotation) {
-        final String testTag = "changeAppRotation_" + intentId + "_" +
-                rotationToString(beginRotation) + "_" + rotationToString(endRotation);
-        return TransitionRunner.newBuilder()
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> {
-                            context.startActivity(intent);
-                            device.wait(Until.hasObject(By.pkg(intent.getComponent()
-                                        .getPackageName()).depth(0)), APP_LAUNCH_TIMEOUT);
-                        }
-                )
-                .runBefore(() -> setRotation(device, beginRotation))
-                .run(() -> setRotation(device, endRotation))
-                .runAfterAll(() -> stopPackage(context, intent.getComponent().getPackageName()))
-                .runAfterAll(() -> setRotation(device, Surface.ROTATION_0))
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder appToSplitScreen(IAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> sleep(500))
-                .run(() -> launchSplitScreen(device))
-                .runAfter(() -> exitSplitScreen(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder splitScreenToLauncher(IAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> launchSplitScreen(device))
-                .run(() -> exitSplitScreen(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder editTextSetFocus(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .run(() -> testApp.openIME(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder resizeSplitScreen(Instrumentation instr, IAppHelper testAppTop,
-            ImeAppHelper testAppBottom, UiDevice device, int beginRotation, Rational startRatio,
-            Rational stopRatio) {
-        String description = startRatio.toString().replace("/", "-") + "_to_"
-                + stopRatio.toString().replace("/", "-");
-        String testTag = buildTestTag("resizeSplitScreen", testAppTop, testAppBottom,
-                beginRotation, beginRotation, description);
-        return TransitionRunner.newBuilder()
-                .withTag(testTag)
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBeforeAll(() -> setRotation(device, beginRotation))
-                .runBeforeAll(() -> clearRecents(instr))
-                .runBefore(testAppBottom::open)
-                .runBefore(device::pressHome)
-                .runBefore(testAppTop::open)
-                .runBefore(device::waitForIdle)
-                .runBefore(() -> launchSplitScreen(device))
-                .runBefore(() -> {
-                    UiObject2 snapshot = device.findObject(
-                            By.res(device.getLauncherPackageName(), "snapshot"));
-                    snapshot.click();
-                })
-                .runBefore(() -> testAppBottom.openIME(device))
-                .runBefore(device::pressBack)
-                .runBefore(() -> AutomationUtils.resizeSplitScreen(device, startRatio))
-                .run(() -> AutomationUtils.resizeSplitScreen(device, stopRatio))
-                .runAfter(() -> exitSplitScreen(device))
-                .runAfter(device::pressHome)
-                .runAfterAll(testAppTop::exit)
-                .runAfterAll(testAppBottom::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder editTextLoseFocusToHome(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(() -> testApp.openIME(device))
-                .run(device::pressHome)
-                .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder editTextLoseFocusToApp(ImeAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .runBefore(() -> testApp.openIME(device))
-                .run(device::pressBack)
-                .run(device::waitForIdle)
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("enterPipMode", testApp, beginRotation))
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .run(() -> testApp.clickEnterPipButton(device))
-                .runAfter(() -> testApp.closePipWindow(device))
-                .runAfterAll(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .runBefore(device::pressHome)
-                .runBefore(() -> setRotation(device, beginRotation))
-                .runBefore(testApp::open)
-                .run(() -> testApp.clickEnterPipButton(device))
-                .run(() -> testApp.closePipWindow(device))
-                .run(device::waitForIdle)
-                .run(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-
-    static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device,
-            int beginRotation) {
-        return TransitionRunner.newBuilder()
-                .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation))
-                .recordAllRuns()
-                .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
-                .run(device::pressHome)
-                .run(() -> setRotation(device, beginRotation))
-                .run(testApp::open)
-                .run(() -> testApp.clickEnterPipButton(device))
-                .run(() -> expandPipWindow(device))
-                .run(device::waitForIdle)
-                .run(testApp::exit)
-                .repeat(ITERATIONS);
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
new file mode 100644
index 0000000..b69e6a9
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.kt
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.app.Instrumentation
+import android.content.Context
+import android.content.Intent
+import android.os.RemoteException
+import android.os.SystemClock
+import android.platform.helpers.IAppHelper
+import android.util.Rational
+import android.view.Surface
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
+
+/**
+ * Collection of common transitions which can be used to test different apps or scenarios.
+ */
+internal object CommonTransitions {
+    private const val ITERATIONS = 1
+    private const val APP_LAUNCH_TIMEOUT: Long = 10000
+    private fun setRotation(device: UiDevice, rotation: Int) {
+        try {
+            when (rotation) {
+                Surface.ROTATION_270 -> device.setOrientationLeft()
+                Surface.ROTATION_90 -> device.setOrientationRight()
+                Surface.ROTATION_0 -> device.setOrientationNatural()
+                else -> device.setOrientationNatural()
+            }
+            // Wait for animation to complete
+            SystemClock.sleep(1000)
+        } catch (e: RemoteException) {
+            throw RuntimeException(e)
+        }
+    }
+
+    /**
+     * Build a test tag for the test
+     * @param testName Name of the transition(s) being tested
+     * @param app App being launcher
+     * @param rotation Initial screen rotation
+     *
+     * @return test tag with pattern <NAME>__<APP>__<ROTATION>
+    </ROTATION></APP></NAME> */
+    private fun buildTestTag(testName: String, app: IAppHelper, rotation: Int): String {
+        return buildTestTag(
+                testName, app, rotation, rotation, app2 = null, extraInfo = "")
+    }
+
+    /**
+     * Build a test tag for the test
+     * @param testName Name of the transition(s) being tested
+     * @param app App being launcher
+     * @param beginRotation Initial screen rotation
+     * @param endRotation End screen rotation (if any, otherwise use same as initial)
+     *
+     * @return test tag with pattern <NAME>__<APP>__<BEGIN_ROTATION>-<END_ROTATION>
+    </END_ROTATION></BEGIN_ROTATION></APP></NAME> */
+    private fun buildTestTag(
+        testName: String,
+        app: IAppHelper,
+        beginRotation: Int,
+        endRotation: Int
+    ): String {
+        return buildTestTag(
+                testName, app, beginRotation, endRotation, app2 = null, extraInfo = "")
+    }
+
+    /**
+     * Build a test tag for the test
+     * @param testName Name of the transition(s) being tested
+     * @param app App being launcher
+     * @param app2 Second app being launched (if any)
+     * @param beginRotation Initial screen rotation
+     * @param endRotation End screen rotation (if any, otherwise use same as initial)
+     * @param extraInfo Additional information to append to the tag
+     *
+     * @return test tag with pattern <NAME>__<APP></APP>(S)>__<ROTATION></ROTATION>(S)>[__<EXTRA>]
+    </EXTRA></NAME> */
+    private fun buildTestTag(
+        testName: String,
+        app: IAppHelper,
+        beginRotation: Int,
+        endRotation: Int,
+        app2: IAppHelper?,
+        extraInfo: String
+    ): String {
+        val testTag = StringBuilder()
+        testTag.append(testName)
+                .append("__")
+                .append(app.launcherName)
+        if (app2 != null) {
+            testTag.append("-")
+                    .append(app2.launcherName)
+        }
+        testTag.append("__")
+                .append(Surface.rotationToString(beginRotation))
+        if (endRotation != beginRotation) {
+            testTag.append("-")
+                    .append(Surface.rotationToString(endRotation))
+        }
+        if (extraInfo.isNotEmpty()) {
+            testTag.append("__")
+                    .append(extraInfo)
+        }
+        return testTag.toString()
+    }
+
+    fun openAppWarm(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("openAppWarm", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll { setRotation(device, beginRotation) }
+                .runBeforeAll { testApp.open() }
+                .runBefore { device.pressHome() }
+                .runBefore { device.waitForIdle() }
+                .runBefore { setRotation(device, beginRotation) }
+                .run { testApp.open() }
+                .runAfterAll { testApp.exit() }
+                .runAfterAll { AutomationUtils.setDefaultWait() }
+                .repeat(ITERATIONS)
+    }
+
+    fun closeAppWithBackKey(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("closeAppWithBackKey", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { testApp.open() }
+                .runBefore { device.waitForIdle() }
+                .run { device.pressBack() }
+                .run { device.waitForIdle() }
+                .runAfterAll { testApp.exit() }
+                .runAfterAll { AutomationUtils.setDefaultWait() }
+                .repeat(ITERATIONS)
+    }
+
+    fun closeAppWithHomeKey(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("closeAppWithHomeKey", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { testApp.open() }
+                .runBefore { device.waitForIdle() }
+                .run { device.pressHome() }
+                .run { device.waitForIdle() }
+                .runAfterAll { testApp.exit() }
+                .runAfterAll { AutomationUtils.setDefaultWait() }
+                .repeat(ITERATIONS)
+    }
+
+    fun openAppCold(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("openAppCold", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBeforeAll { setRotation(device, beginRotation) }
+                .runBefore { testApp.exit() }
+                .runBefore { device.waitForIdle() }
+                .run { testApp.open() }
+                .runAfterAll { testApp.exit() }
+                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
+                .repeat(ITERATIONS)
+    }
+
+    fun changeAppRotation(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int,
+        endRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("changeAppRotation", testApp, beginRotation, endRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll { testApp.open() }
+                .runBefore { setRotation(device, beginRotation) }
+                .run { setRotation(device, endRotation) }
+                .runAfterAll { testApp.exit() }
+                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
+                .repeat(ITERATIONS)
+    }
+
+    fun changeAppRotation(
+        intent: Intent,
+        intentId: String,
+        context: Context,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int,
+        endRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        val testTag = "changeAppRotation_" + intentId + "_" +
+                Surface.rotationToString(beginRotation) + "_" +
+                Surface.rotationToString(endRotation)
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(testTag)
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll {
+                    context.startActivity(intent)
+                    device.wait(Until.hasObject(By.pkg(intent.component?.packageName)
+                            .depth(0)), APP_LAUNCH_TIMEOUT)
+                }
+                .runBefore { setRotation(device, beginRotation) }
+                .run { setRotation(device, endRotation) }
+                .runAfterAll { AutomationUtils.stopPackage(context, intent.component?.packageName) }
+                .runAfterAll { setRotation(device, Surface.ROTATION_0) }
+                .repeat(ITERATIONS)
+    }
+
+    fun appToSplitScreen(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("appToSplitScreen", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .runBefore { device.waitForIdle() }
+                .runBefore { SystemClock.sleep(500) }
+                .run { AutomationUtils.launchSplitScreen(device) }
+                .runAfter { AutomationUtils.exitSplitScreen(device) }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun splitScreenToLauncher(
+        testApp: IAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("splitScreenToLauncher", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { testApp.open() }
+                .runBefore { device.waitForIdle() }
+                .runBefore { AutomationUtils.launchSplitScreen(device) }
+                .run { AutomationUtils.exitSplitScreen(device) }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun editTextSetFocus(
+        testApp: ImeAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("editTextSetFocus", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBefore { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .run { testApp.openIME(device) }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun resizeSplitScreen(
+        testAppTop: IAppHelper,
+        testAppBottom: ImeAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int,
+        startRatio: Rational,
+        stopRatio: Rational
+    ): TransitionRunner.TransitionBuilder {
+        val description = (startRatio.toString().replace("/", "-") + "_to_" +
+                stopRatio.toString().replace("/", "-"))
+        val testTag = buildTestTag("resizeSplitScreen", testAppTop, beginRotation,
+                beginRotation, testAppBottom, description)
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(testTag)
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBeforeAll { setRotation(device, beginRotation) }
+                .runBeforeAll { AutomationUtils.clearRecents(instrumentation) }
+                .runBefore { testAppBottom.open() }
+                .runBefore { device.pressHome() }
+                .runBefore { testAppTop.open() }
+                .runBefore { device.waitForIdle() }
+                .runBefore { AutomationUtils.launchSplitScreen(device) }
+                .runBefore {
+                    val snapshot = device.findObject(
+                            By.res(device.launcherPackageName, "snapshot"))
+                    snapshot.click()
+                }
+                .runBefore { testAppBottom.openIME(device) }
+                .runBefore { device.pressBack() }
+                .runBefore { AutomationUtils.resizeSplitScreen(device, startRatio) }
+                .run { AutomationUtils.resizeSplitScreen(device, stopRatio) }
+                .runAfter { AutomationUtils.exitSplitScreen(device) }
+                .runAfter { device.pressHome() }
+                .runAfterAll { testAppTop.exit() }
+                .runAfterAll { testAppBottom.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun editTextLoseFocusToHome(
+        testApp: ImeAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("editTextLoseFocusToHome", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBefore { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .runBefore { testApp.openIME(device) }
+                .run { device.pressHome() }
+                .run { device.waitForIdle() }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun editTextLoseFocusToApp(
+        testApp: ImeAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("editTextLoseFocusToApp", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBefore { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .runBefore { testApp.openIME(device) }
+                .run { device.pressBack() }
+                .run { device.waitForIdle() }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun enterPipMode(
+        testApp: PipAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("enterPipMode", testApp, beginRotation))
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBefore { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .run { testApp.clickEnterPipButton(device) }
+                .runAfter { testApp.closePipWindow(device) }
+                .runAfterAll { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun exitPipModeToHome(
+        testApp: PipAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("exitPipModeToHome", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .runBefore { device.pressHome() }
+                .runBefore { setRotation(device, beginRotation) }
+                .runBefore { testApp.open() }
+                .run { testApp.clickEnterPipButton(device) }
+                .run { testApp.closePipWindow(device) }
+                .run { device.waitForIdle() }
+                .run { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+
+    fun exitPipModeToApp(
+        testApp: PipAppHelper,
+        instrumentation: Instrumentation,
+        device: UiDevice,
+        beginRotation: Int
+    ): TransitionRunner.TransitionBuilder {
+        return TransitionRunner.TransitionBuilder(instrumentation)
+                .withTag(buildTestTag("exitPipModeToApp", testApp, beginRotation))
+                .recordAllRuns()
+                .runBeforeAll { AutomationUtils.wakeUpAndGoToHomeScreen() }
+                .run { device.pressHome() }
+                .run { setRotation(device, beginRotation) }
+                .run { testApp.open() }
+                .run { testApp.clickEnterPipButton(device) }
+                .run { AutomationUtils.expandPipWindow(device) }
+                .run { device.waitForIdle() }
+                .run { testApp.exit() }
+                .repeat(ITERATIONS)
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
deleted file mode 100644
index dec5680..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import android.app.Instrumentation;
-import android.platform.helpers.IAppHelper;
-import android.util.Rational;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-
-/**
- * Tests to help debug individual transitions, capture video recordings and create test cases.
- */
-@LargeTest
-@Ignore("Used for debugging transitions used in FlickerTests.")
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class DebugTest {
-    private IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-            "com.android.server.wm.flicker.testapp", "SimpleApp");
-    private UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-    /**
-     * atest FlickerTests:DebugTest#openAppCold
-     */
-    @Test
-    public void openAppCold() {
-        CommonTransitions.openAppCold(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppWarm
-     */
-    @Test
-    public void openAppWarm() {
-        CommonTransitions.openAppWarm(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
-     */
-    @Test
-    public void changeOrientationFromNaturalToLeft() {
-        CommonTransitions.changeAppRotation(testApp, uiDevice, Surface.ROTATION_0,
-                Surface.ROTATION_270).recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithBackKey
-     */
-    @Test
-    public void closeAppWithBackKey() {
-        CommonTransitions.closeAppWithBackKey(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#closeAppWithHomeKey
-     */
-    @Test
-    public void closeAppWithHomeKey() {
-        CommonTransitions.closeAppWithHomeKey(testApp, uiDevice, Surface.ROTATION_0)
-                .recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#openAppToSplitScreen
-     */
-    @Test
-    public void openAppToSplitScreen() {
-        CommonTransitions.appToSplitScreen(testApp, uiDevice,
-                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#splitScreenToLauncher
-     */
-    @Test
-    public void splitScreenToLauncher() {
-        CommonTransitions.splitScreenToLauncher(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().recordAllRuns().build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#resizeSplitScreen
-     */
-    @Test
-    public void resizeSplitScreen() {
-        Instrumentation instr = InstrumentationRegistry.getInstrumentation();
-        ImeAppHelper bottomApp = new ImeAppHelper(instr);
-        CommonTransitions.resizeSplitScreen(instr, testApp, bottomApp, uiDevice, Surface.ROTATION_0,
-                new Rational(1, 3), new Rational(2, 3))
-                .includeJankyRuns().build().run();
-    }
-
-    // IME tests
-
-    /**
-     * atest FlickerTests:DebugTest#editTextSetFocus
-     */
-    @Test
-    public void editTextSetFocus() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
-     */
-    @Test
-    public void editTextLoseFocusToHome() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
-     */
-    @Test
-    public void editTextLoseFocusToApp() {
-        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    // PIP tests
-
-    /**
-     * atest FlickerTests:DebugTest#enterPipMode
-     */
-    @Test
-    public void enterPipMode() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.enterPipMode(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToHome
-     */
-    @Test
-    public void exitPipModeToHome() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToHome(testApp, uiDevice, Surface.ROTATION_0)
-                .includeJankyRuns()
-                .build().run();
-    }
-
-    /**
-     * atest FlickerTests:DebugTest#exitPipModeToApp
-     */
-    @Test
-    public void exitPipModeToApp() {
-        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-        CommonTransitions.exitPipModeToApp(testApp, uiDevice, Surface.ROTATION_0).includeJankyRuns()
-                .build().run();
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
new file mode 100644
index 0000000..f871ea5
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.kt
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.platform.helpers.IAppHelper
+import android.util.Rational
+import android.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import androidx.test.runner.AndroidJUnit4
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+/**
+ * Tests to help debug individual transitions, capture video recordings and create test cases.
+ */
+@LargeTest
+@Ignore("Used for debugging transitions used in FlickerTests.")
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class DebugTest {
+    private val instrumentation = InstrumentationRegistry.getInstrumentation()
+    private val testApp: IAppHelper = StandardAppHelper(instrumentation,
+            "com.android.server.wm.flicker.testapp", "SimpleApp")
+    private val uiDevice = UiDevice.getInstance(instrumentation)
+
+    /**
+     * atest FlickerTests:DebugTest#openAppCold
+     */
+    @Test
+    fun openAppCold() {
+        CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#openAppWarm
+     */
+    @Test
+    fun openAppWarm() {
+        CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
+     */
+    @Test
+    fun changeOrientationFromNaturalToLeft() {
+        CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice, Surface.ROTATION_0,
+                Surface.ROTATION_270).recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#closeAppWithBackKey
+     */
+    @Test
+    fun closeAppWithBackKey() {
+        CommonTransitions.closeAppWithBackKey(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#closeAppWithHomeKey
+     */
+    @Test
+    fun closeAppWithHomeKey() {
+        CommonTransitions.closeAppWithHomeKey(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#openAppToSplitScreen
+     */
+    @Test
+    fun openAppToSplitScreen() {
+        CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().recordAllRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#splitScreenToLauncher
+     */
+    @Test
+    fun splitScreenToLauncher() {
+        CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().recordAllRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#resizeSplitScreen
+     */
+    @Test
+    fun resizeSplitScreen() {
+        val bottomApp = ImeAppHelper(instrumentation)
+        CommonTransitions.resizeSplitScreen(
+                testApp,
+                bottomApp,
+                instrumentation,
+                uiDevice,
+                Surface.ROTATION_0,
+                Rational(1, 3), Rational(2, 3)
+        ).includeJankyRuns().build().run()
+    }
+    // IME tests
+    /**
+     * atest FlickerTests:DebugTest#editTextSetFocus
+     */
+    @Test
+    fun editTextSetFocus() {
+        val testApp = ImeAppHelper(instrumentation)
+        CommonTransitions.editTextSetFocus(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
+     */
+    @Test
+    fun editTextLoseFocusToHome() {
+        val testApp = ImeAppHelper(instrumentation)
+        CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
+     */
+    @Test
+    fun editTextLoseFocusToApp() {
+        val testApp = ImeAppHelper(instrumentation)
+        CommonTransitions.editTextLoseFocusToHome(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().build().run()
+    }
+    // PIP tests
+    /**
+     * atest FlickerTests:DebugTest#enterPipMode
+     */
+    @Test
+    fun enterPipMode() {
+        val testApp = PipAppHelper(instrumentation)
+        CommonTransitions.enterPipMode(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#exitPipModeToHome
+     */
+    @Test
+    fun exitPipModeToHome() {
+        val testApp = PipAppHelper(instrumentation)
+        CommonTransitions.exitPipModeToHome(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns()
+                .build().run()
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#exitPipModeToApp
+     */
+    @Test
+    fun exitPipModeToApp() {
+        val testApp = PipAppHelper(instrumentation)
+        CommonTransitions.exitPipModeToApp(testApp, instrumentation, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().build().run()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
deleted file mode 100644
index 6bbf684..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.setDefaultWait;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.platform.helpers.IAppHelper;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
-
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.function.Consumer;
-
-/**
- * Base class of all Flicker test that performs common functions for all flicker tests:
- * <p>
- * - Caches transitions so that a transition is run once and the transition results are used by
- * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
- * multiple times.
- * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
- * - Fails tests if results are not available for any test due to jank.
- */
-public abstract class FlickerTestBase {
-    public static final String TAG = "FLICKER";
-    static final String SCREENSHOT_LAYER = "RotationLayer";
-    static final String NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar";
-    static final String STATUS_BAR_WINDOW_TITLE = "StatusBar";
-    static final String DOCKED_STACK_DIVIDER = "DockedStackDivider";
-    private static HashMap<String, List<TransitionResult>> transitionResults =
-            new HashMap<>();
-    IAppHelper mTestApp;
-    UiDevice mUiDevice;
-    private List<TransitionResult> mResults;
-    private TransitionResult mLastResult = null;
-
-    @Before
-    public void setUp() {
-        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-    }
-
-    /**
-     * Teardown any system settings and clean up test artifacts from the file system.
-     *
-     * Note: test artifacts for failed tests will remain on the device.
-     */
-    @AfterClass
-    public static void teardown() {
-        setDefaultWait();
-        transitionResults.values().stream()
-                .flatMap(List::stream)
-                .forEach(result -> {
-                    if (result.canDelete()) {
-                        result.delete();
-                    } else {
-                        if (result.layersTraceExists()) {
-                            Log.e(TAG, "Layers trace saved to " + result.getLayersTracePath());
-                        }
-                        if (result.windowManagerTraceExists()) {
-                            Log.e(TAG, "WindowManager trace saved to " + result
-                                    .getWindowManagerTracePath
-                                            ());
-                        }
-                        if (result.screenCaptureVideoExists()) {
-                            Log.e(TAG, "Screen capture video saved to " + result
-                                    .screenCaptureVideoPath().toString());
-                        }
-                    }
-                });
-    }
-
-    /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    void run(TransitionRunner transition) {
-        if (transitionResults.containsKey(transition.getTestTag())) {
-            mResults = transitionResults.get(transition.getTestTag());
-            return;
-        }
-        mResults = transition.run().getResults();
-        /* Fail if we don't have any results due to jank */
-        assertWithMessage("No results to test because all transition runs were invalid because "
-                + "of Jank").that(mResults).isNotEmpty();
-        transitionResults.put(transition.getTestTag(), mResults);
-    }
-
-    /**
-     * Runs a transition, returns a cached result if the transition has run before.
-     */
-    @Before
-    public void runTransition() {
-        run(getTransitionToRun());
-    }
-
-    /**
-     * Gets the transition that will be executed
-     */
-    abstract TransitionRunner getTransitionToRun();
-
-    /**
-     * Goes through a list of transition results and checks assertions on each result.
-     */
-    void checkResults(Consumer<TransitionResult> assertion) {
-
-        for (TransitionResult result : mResults) {
-            mLastResult = result;
-            assertion.accept(result);
-        }
-        mLastResult = null;
-    }
-
-    /**
-     * Kludge to mark a file for saving. If {@code checkResults} fails, the last result is not
-     * cleared. This indicates the assertion failed for the result, so mark it for saving.
-     */
-    @After
-    public void markArtifactsForSaving() {
-        if (mLastResult != null) {
-            mLastResult.flagForSaving();
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
new file mode 100644
index 0000000..d7586d0
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.platform.helpers.IAppHelper
+import android.util.Log
+import androidx.test.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.google.common.truth.Truth
+import org.junit.After
+import org.junit.AfterClass
+import org.junit.Before
+
+/**
+ * Base class of all Flicker test that performs common functions for all flicker tests:
+ *
+ *
+ * - Caches transitions so that a transition is run once and the transition results are used by
+ * tests multiple times. This is needed for parameterized tests which call the BeforeClass methods
+ * multiple times.
+ * - Keeps track of all test artifacts and deletes ones which do not need to be reviewed.
+ * - Fails tests if results are not available for any test due to jank.
+ */
+abstract class FlickerTestBase {
+    lateinit var testApp: IAppHelper
+    open val instrumentation by lazy {
+        InstrumentationRegistry.getInstrumentation()
+    }
+    val uiDevice by lazy {
+        UiDevice.getInstance(instrumentation)
+    }
+    lateinit var tesults: List<TransitionResult>
+    private var lastResult: TransitionResult? = null
+
+    /**
+     * Runs a transition, returns a cached result if the transition has run before.
+     */
+    fun run(transition: TransitionRunner) {
+        if (transitionResults.containsKey(transition.testTag)) {
+            tesults = transitionResults[transition.testTag]
+                    ?: throw IllegalStateException("Results do not contain test tag " +
+                            transition.testTag)
+            return
+        }
+        tesults = transition.run().results
+        /* Fail if we don't have any results due to jank */
+        Truth.assertWithMessage("No results to test because all transition runs were invalid " +
+                "because of Jank").that(tesults).isNotEmpty()
+        transitionResults[transition.testTag] = tesults
+    }
+
+    /**
+     * Runs a transition, returns a cached result if the transition has run before.
+     */
+    @Before
+    fun runTransition() {
+        run(transitionToRun)
+    }
+
+    /**
+     * Gets the transition that will be executed
+     */
+    abstract val transitionToRun: TransitionRunner
+
+    /**
+     * Goes through a list of transition results and checks assertions on each result.
+     */
+    fun checkResults(assertion: (TransitionResult) -> Unit) {
+        for (result in tesults) {
+            lastResult = result
+            assertion(result)
+        }
+        lastResult = null
+    }
+
+    /**
+     * Kludge to mark a file for saving. If `checkResults` fails, the last result is not
+     * cleared. This indicates the assertion failed for the result, so mark it for saving.
+     */
+    @After
+    fun markArtifactsForSaving() {
+        lastResult?.flagForSaving()
+    }
+
+    companion object {
+        const val TAG = "FLICKER"
+        const val NAVIGATION_BAR_WINDOW_TITLE = "NavigationBar"
+        const val STATUS_BAR_WINDOW_TITLE = "StatusBar"
+        const val DOCKED_STACK_DIVIDER = "DockedStackDivider"
+        private val transitionResults = mutableMapOf<String, List<TransitionResult>>()
+
+        /**
+         * Teardown any system settings and clean up test artifacts from the file system.
+         *
+         * Note: test artifacts for failed tests will remain on the device.
+         */
+        @AfterClass
+        @JvmStatic
+        fun teardown() {
+            AutomationUtils.setDefaultWait()
+            transitionResults.values
+                .flatten()
+                .forEach {
+                    if (it.canDelete()) {
+                        it.delete()
+                    } else {
+                        if (it.layersTraceExists()) {
+                            Log.e(TAG, "Layers trace saved to ${it.layersTracePath}")
+                        }
+                        if (it.windowManagerTraceExists()) {
+                            Log.e(TAG,
+                                    "WindowManager trace saved to ${it.windowManagerTracePath}")
+                        }
+                        if (it.screenCaptureVideoExists()) {
+                            Log.e(TAG,
+                                    "Screen capture video saved to ${it.screenCaptureVideoPath()}")
+                        }
+                    }
+                }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
deleted file mode 100644
index 54941dc..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-
-import android.graphics.Rect;
-import android.view.Surface;
-
-import androidx.test.filters.FlakyTest;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-public abstract class NonRotationTestBase extends FlickerTestBase {
-
-    int mBeginRotation;
-
-    public NonRotationTestBase(String beginRotationName, int beginRotation) {
-        this.mBeginRotation = beginRotation;
-    }
-
-    @Parameters(name = "{0}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-
-        for (int begin : supportedRotations) {
-            params.add(new Object[]{rotationToString(begin), begin});
-        }
-
-        return params;
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        Rect displayBounds = getDisplayBounds(mBeginRotation);
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                displayBounds).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @FlakyTest(bugId = 141361128)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
new file mode 100644
index 0000000..653fecd
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runners.Parameterized
+
+abstract class NonRotationTestBase(
+    beginRotationName: String,
+    protected val beginRotation: Int
+) : FlickerTestBase() {
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkCoveredRegion_noUncoveredRegions() {
+        val displayBounds = WindowUtils.getDisplayBounds(beginRotation)
+        checkResults {
+            LayersTraceSubject.assertThat(it).coversRegion(
+                    displayBounds).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_statusBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    companion object {
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+            val params: MutableCollection<Array<Any>> = ArrayList()
+            for (begin in supportedRotations) {
+                params.add(arrayOf(Surface.rotationToString(begin), begin))
+            }
+            return params
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
deleted file mode 100644
index c150e09..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.openAppCold;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test cold launch app from launcher.
- * To run this test: {@code atest FlickerTests:OpenAppColdTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppColdTest extends NonRotationTestBase {
-
-    public OpenAppColdTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return openAppCold(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_wallpaperWindowBecomesInvisible() {
-        checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .hidesBelowAppWindow("Wallpaper")
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults(result -> assertThat(result)
-                .showsAppWindowOnTop(
-                        "com.android.launcher3/.Launcher")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
deleted file mode 100644
index 00da62f..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.appToSplitScreen;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test open app to split screen.
- * To run this test: {@code atest FlickerTests:OpenAppToSplitScreenTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppToSplitScreenTest extends NonRotationTestBase {
-
-    public OpenAppToSplitScreenTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return appToSplitScreen(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns()
-                .build();
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .hidesLayer(DOCKED_STACK_DIVIDER)
-                .then()
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
deleted file mode 100644
index 62ae254..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.openAppWarm;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test warm launch app.
- * To run this test: {@code atest FlickerTests:OpenAppWarmTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenAppWarmTest extends NonRotationTestBase {
-
-    public OpenAppWarmTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return openAppWarm(mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_wallpaperBecomesInvisible() {
-        checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .hidesBelowAppWindow("Wallpaper")
-                .forAllEntries());
-    }
-
-    @FlakyTest(bugId = 140855415)
-    @Ignore("Waiting bug feedback")
-    @Test
-    public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
-        checkResults(result -> assertThat(result)
-                .showsAppWindowOnTop(
-                        "com.android.launcher3/.Launcher")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_wallpaperLayerBecomesInvisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("Wallpaper")
-                .then()
-                .replaceVisibleLayer("Wallpaper", mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
deleted file mode 100644
index fcb022c..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.editTextSetFocus;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test IME window opening transitions.
- * To run this test: {@code atest FlickerTests:OpenImeWindowTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class OpenImeWindowTest extends NonRotationTestBase {
-
-    private static final String IME_WINDOW_TITLE = "InputMethod";
-
-    public OpenImeWindowTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return editTextSetFocus((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_imeWindowBecomesVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .hidesImeWindow(IME_WINDOW_TITLE)
-                .then()
-                .showsImeWindow(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_imeLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .hidesLayer(IME_WINDOW_TITLE)
-                .then()
-                .showsLayer(IME_WINDOW_TITLE)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java
deleted file mode 100644
index cf51d78..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipTestBase.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.closePipWindow;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.AfterClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public abstract class PipTestBase extends NonRotationTestBase {
-    static final String sPipWindowTitle = "PipMenuActivity";
-
-    public PipTestBase(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-
-        this.mTestApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (hasPipWindow(device)) {
-            closePipWindow(device);
-        }
-    }
-
-    @Test
-    public void checkVisibility_pipWindowBecomesVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .hidesAppWindow(sPipWindowTitle)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_pipLayerBecomesVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsLayer(sPipWindowTitle)
-                .then()
-                .hidesLayer(sPipWindowTitle)
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
deleted file mode 100644
index 5e67ada..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToAppTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToApp;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test Pip launch.
- * To run this test: {@code atest FlickerTests:PipToAppTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 152738416)
-@Ignore("Waiting bug feedback")
-public class PipToAppTest extends PipTestBase {
-    public PipToAppTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return exitPipModeToApp((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .skipUntilFirstAssertion()
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .showsAppWindowOnTop(mTestApp.getPackage())
-                .then()
-                .hidesAppWindowOnTop(mTestApp.getPackage())
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
deleted file mode 100644
index af713c7..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/PipToHomeTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.exitPipModeToHome;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import com.android.server.wm.flicker.helpers.PipAppHelper;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-
-/**
- * Test Pip launch.
- * To run this test: {@code atest FlickerTests:PipToHomeTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 152738416)
-@Ignore("Waiting bug feedback")
-public class PipToHomeTest extends PipTestBase {
-    public PipToHomeTest(String beginRotationName, int beginRotation) {
-        super(beginRotationName, beginRotation);
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return exitPipModeToHome((PipAppHelper) mTestApp, mUiDevice, mBeginRotation)
-                .includeJankyRuns().build();
-    }
-
-    @Ignore
-    @Test
-    public void checkVisibility_backgroundWindowVisibleBehindPipLayer() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(sPipWindowTitle)
-                .then()
-                .showsBelowAppWindow("Wallpaper")
-                .then()
-                .showsAppWindowOnTop("Wallpaper")
-                .forAllEntries());
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
deleted file mode 100644
index 9516af6..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.resizeSplitScreen;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.WindowUtils.getDockedStackDividerInset;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarHeight;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.Instrumentation;
-import android.graphics.Rect;
-import android.util.Rational;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.UiDevice;
-
-import com.android.server.wm.flicker.helpers.ImeAppHelper;
-
-import org.junit.AfterClass;
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-
-/**
- * Test split screen resizing window transitions.
- * To run this test: {@code atest FlickerTests:ResizeSplitScreenTest}
- *
- * Currently it runs only in 0 degrees because of b/156100803
- */
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 159096424)
-@Ignore("Waiting bug feedback")
-public class ResizeSplitScreenTest extends FlickerTestBase {
-
-    private static String sSimpleActivity = "SimpleActivity";
-    private static String sImeActivity = "ImeActivity";
-
-    public ResizeSplitScreenTest() {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        Instrumentation instr = InstrumentationRegistry.getInstrumentation();
-        ImeAppHelper bottomApp = new ImeAppHelper(instr);
-        return resizeSplitScreen(instr, mTestApp, bottomApp, mUiDevice, Surface.ROTATION_0,
-                new Rational(1, 3), new Rational(2, 3))
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkVisibility_topAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(sSimpleActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_bottomAppLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(sImeActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-
-    @Test
-    @Ignore("Waiting feedback")
-    public void checkPosition_appsStartingBounds() {
-        Rect displayBounds = getDisplayBounds();
-        checkResults(result -> {
-            LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath(), result.getLayersTraceChecksum());
-
-            assertThat(entries.getEntries()).isNotEmpty();
-            Rect startingDividerBounds = entries.getEntries().get(0).getVisibleBounds
-                    (DOCKED_STACK_DIVIDER);
-
-            Rect startingTopAppBounds = new Rect(0, 0, startingDividerBounds.right,
-                    startingDividerBounds.top + getDockedStackDividerInset());
-
-            Rect startingBottomAppBounds = new Rect(0,
-                    startingDividerBounds.bottom - getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - getNavigationBarHeight());
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
-                    .inTheBeginning();
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
-                    .inTheBeginning();
-        });
-    }
-
-    @Test
-    @Ignore("Waiting feedback")
-    public void checkPosition_appsEndingBounds() {
-        Rect displayBounds = getDisplayBounds();
-        checkResults(result -> {
-            LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                    result.getLayersTracePath(), result.getLayersTraceChecksum());
-
-            assertThat(entries.getEntries()).isNotEmpty();
-            Rect endingDividerBounds = entries.getEntries().get(
-                    entries.getEntries().size() - 1).getVisibleBounds(
-                    DOCKED_STACK_DIVIDER);
-
-            Rect startingTopAppBounds = new Rect(0, 0, endingDividerBounds.right,
-                    endingDividerBounds.top + getDockedStackDividerInset());
-
-            Rect startingBottomAppBounds = new Rect(0,
-                    endingDividerBounds.bottom - getDockedStackDividerInset(),
-                    displayBounds.right,
-                    displayBounds.bottom - getNavigationBarHeight());
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
-                    .atTheEnd();
-
-            LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
-                    .atTheEnd();
-        });
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    @FlakyTest(bugId = 156223549)
-    @Ignore("Waiting bug feedback")
-    public void checkVisibility_topAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow(sSimpleActivity)
-                .forAllEntries());
-    }
-
-    @Test
-    @FlakyTest(bugId = 156223549)
-    @Ignore("Waiting bug feedback")
-    public void checkVisibility_bottomAppWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow(sImeActivity)
-                .forAllEntries());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (isInSplitScreen(device)) {
-            exitSplitScreen(device);
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
new file mode 100644
index 0000000..873d607
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/RotationTestBase.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker
+
+import android.view.Surface
+import androidx.test.filters.FlakyTest
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runners.Parameterized
+
+abstract class RotationTestBase(
+    beginRotationName: String,
+    endRotationName: String,
+    protected val beginRotation: Int,
+    protected val endRotation: Int
+) : FlickerTestBase() {
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkPosition_navBarLayerRotatesAndScales() {
+        val startingPos = WindowUtils.getNavigationBarPosition(beginRotation)
+        val endingPos = WindowUtils.getNavigationBarPosition(endRotation)
+        if (startingPos == endingPos) {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+                        .forAllEntries()
+            }
+        } else {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
+                        .inTheBeginning()
+            }
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
+                        .atTheEnd()
+            }
+        }
+    }
+
+    @Test
+    fun checkPosition_statusBarLayerRotatesScales() {
+        val startingPos = WindowUtils.getStatusBarPosition(beginRotation)
+        val endingPos = WindowUtils.getStatusBarPosition(endRotation)
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
+                    .inTheBeginning()
+            LayersTraceSubject.assertThat(it)
+                    .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, endingPos).atTheEnd()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_navBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkVisibility_statusBarLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    companion object {
+        const val SCREENSHOT_LAYER = "RotationLayer"
+
+        @Parameterized.Parameters(name = "{0}-{1}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+            val params: MutableCollection<Array<Any>> = mutableListOf()
+            for (begin in supportedRotations) {
+                for (end in supportedRotations) {
+                    if (begin != end) {
+                        params.add(arrayOf(
+                                Surface.rotationToString(begin),
+                                Surface.rotationToString(end),
+                                begin,
+                                end
+                        ))
+                    }
+                }
+            }
+            return params
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
deleted file mode 100644
index 3cff868..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static android.view.Surface.rotationToString;
-
-import static com.android.server.wm.flicker.CommonTransitions.changeAppRotation;
-import static com.android.server.wm.flicker.WindowUtils.getAppPosition;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.WindowUtils.getNavigationBarPosition;
-import static com.android.server.wm.flicker.testapp.ActivityOptions.EXTRA_STARVE_UI_THREAD;
-import static com.android.server.wm.flicker.testapp.ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME;
-
-import android.content.Intent;
-import android.graphics.Rect;
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.LargeTest;
-
-import org.junit.FixMethodOrder;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Cycle through supported app rotations using seamless rotations.
- * To run this test: {@code atest FlickerTests:SeamlessAppRotationTest}
- */
-@LargeTest
-@RunWith(Parameterized.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@FlakyTest(bugId = 147659548)
-@Ignore("Waiting bug feedback")
-public class SeamlessAppRotationTest extends FlickerTestBase {
-    private int mBeginRotation;
-    private int mEndRotation;
-    private Intent mIntent;
-
-    public SeamlessAppRotationTest(String testId, Intent intent, int beginRotation,
-            int endRotation) {
-        this.mIntent = intent;
-        this.mBeginRotation = beginRotation;
-        this.mEndRotation = endRotation;
-    }
-
-    @Parameters(name = "{0}")
-    public static Collection<Object[]> getParams() {
-        int[] supportedRotations =
-                {Surface.ROTATION_0, Surface.ROTATION_90};
-        Collection<Object[]> params = new ArrayList<>();
-
-        ArrayList<Intent> testIntents = new ArrayList<>();
-
-        // launch test activity that supports seamless rotation
-        Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setComponent(SEAMLESS_ACTIVITY_COMPONENT_NAME);
-        testIntents.add(intent);
-
-        // launch test activity that supports seamless rotation with a busy UI thread to miss frames
-        // when the app is asked to redraw
-        intent = new Intent(intent);
-        intent.putExtra(EXTRA_STARVE_UI_THREAD, true);
-        testIntents.add(intent);
-
-        for (Intent testIntent : testIntents) {
-            for (int begin : supportedRotations) {
-                for (int end : supportedRotations) {
-                    if (begin != end) {
-                        String testId = rotationToString(begin) + "_" + rotationToString(end);
-                        if (testIntent.getExtras() != null &&
-                                testIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) {
-                            testId += "_" + "BUSY_UI_THREAD";
-                        }
-                        params.add(new Object[]{testId, testIntent, begin, end});
-                    }
-                }
-            }
-        }
-        return params;
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        String intentId = "";
-        if (mIntent.getExtras() != null &&
-                mIntent.getExtras().getBoolean(EXTRA_STARVE_UI_THREAD)) {
-            intentId = "BUSY_UI_THREAD";
-        }
-
-        return changeAppRotation(mIntent, intentId, InstrumentationRegistry.getContext(),
-                mUiDevice, mBeginRotation, mEndRotation).build();
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkPosition_navBarLayerRotatesAndScales() {
-        Rect startingPos = getNavigationBarPosition(mBeginRotation);
-        Rect endingPos = getNavigationBarPosition(mEndRotation);
-        if (startingPos.equals(endingPos)) {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                    .forAllEntries());
-        } else {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
-                    .inTheBeginning());
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, endingPos)
-                    .atTheEnd());
-        }
-    }
-
-    @Test
-    public void checkPosition_appLayerRotates() {
-        Rect startingPos = getAppPosition(mBeginRotation);
-        Rect endingPos = getAppPosition(mEndRotation);
-        if (startingPos.equals(endingPos)) {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos)
-                    .forAllEntries());
-        } else {
-            checkResults(result -> LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), startingPos)
-                    .then()
-                    .hasVisibleRegion(mIntent.getComponent().getPackageName(), endingPos)
-                    .forAllEntries());
-        }
-    }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        Rect startingBounds = getDisplayBounds(mBeginRotation);
-        Rect endingBounds = getDisplayBounds(mEndRotation);
-        if (startingBounds.equals(endingBounds)) {
-            checkResults(result ->
-                    LayersTraceSubject.assertThat(result)
-                            .coversRegion(startingBounds)
-                            .forAllEntries());
-        } else {
-            checkResults(result ->
-                    LayersTraceSubject.assertThat(result)
-                            .coversRegion(startingBounds)
-                            .then()
-                            .coversRegion(endingBounds)
-                            .forAllEntries());
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
deleted file mode 100644
index 9e9c829..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker;
-
-import static com.android.server.wm.flicker.CommonTransitions.splitScreenToLauncher;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.exitSplitScreen;
-import static com.android.server.wm.flicker.helpers.AutomationUtils.isInSplitScreen;
-
-import android.view.Surface;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-import androidx.test.uiautomator.UiDevice;
-
-import org.junit.AfterClass;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-
-/**
- * Test open app to split screen.
- * To run this test: {@code atest FlickerTests:SplitScreenToLauncherTest}
- */
-@LargeTest
-@RunWith(AndroidJUnit4.class)
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class SplitScreenToLauncherTest extends FlickerTestBase {
-
-    public SplitScreenToLauncherTest() {
-        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "SimpleApp");
-    }
-
-    @Override
-    TransitionRunner getTransitionToRun() {
-        return splitScreenToLauncher(mTestApp, mUiDevice, Surface.ROTATION_0)
-                .includeJankyRuns().build();
-    }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result ->
-                LayersTraceSubject.assertThat(result)
-                        .coversRegion(getDisplayBounds()).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_dividerLayerBecomesInVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(DOCKED_STACK_DIVIDER)
-                .then()
-                .hidesLayer(DOCKED_STACK_DIVIDER)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_appLayerBecomesInVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mTestApp.getPackage())
-                .then()
-                .hidesLayer(mTestApp.getPackage())
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @AfterClass
-    public static void teardown() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-
-        if (isInSplitScreen(device)) {
-            exitSplitScreen(device);
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
deleted file mode 100644
index 42977f5..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.helpers;
-
-import android.app.Instrumentation;
-
-import com.android.server.wm.flicker.StandardAppHelper;
-
-public abstract class FlickerAppHelper extends StandardAppHelper {
-
-    static int sFindTimeout = 10000;
-    static String sFlickerPackage = "com.android.server.wm.flicker.testapp";
-
-    public FlickerAppHelper(Instrumentation instr, String launcherName) {
-        super(instr, sFlickerPackage, launcherName);
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
new file mode 100644
index 0000000..e579533
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import com.android.server.wm.flicker.StandardAppHelper
+
+abstract class FlickerAppHelper(
+    instr: Instrumentation,
+    launcherName: String
+) : StandardAppHelper(instr, sFlickerPackage, launcherName) {
+    companion object {
+        var sFindTimeout = 10000
+        var sFlickerPackage = "com.android.server.wm.flicker.testapp"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
deleted file mode 100644
index 1b2c484..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.helpers;
-
-import android.app.Instrumentation;
-
-import androidx.test.uiautomator.UiDevice;
-
-public class ImeAppAutoFocusHelper extends ImeAppHelper {
-
-    public ImeAppAutoFocusHelper(Instrumentation instr) {
-        super(instr, "ImeAppAutoFocus");
-    }
-
-    public void openIME(UiDevice device) {
-        // do nothing (the app is focused automatically)
-    }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/Cancellable.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
similarity index 64%
rename from services/core/java/com/android/server/biometrics/sensors/Cancellable.java
rename to tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
index 68a3bc6..d587f1e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/Cancellable.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.kt
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.server.biometrics.sensors;
+package com.android.server.wm.flicker.helpers
 
-/**
- * Interface that cancellable {@link ClientMonitor} subclasses should implement.
- */
-public interface Cancellable {
-    /**
-     * Requests to end the ClientMonitor's lifecycle.
-     */
-    void cancel();
+import android.app.Instrumentation
+import androidx.test.uiautomator.UiDevice
+
+class ImeAppAutoFocusHelper(instr: Instrumentation) : ImeAppHelper(instr, "ImeAppAutoFocus") {
+    override fun openIME(device: UiDevice) {
+        // do nothing (the app is focused automatically)
+    }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
deleted file mode 100644
index 095722d..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.helpers;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.app.Instrumentation;
-
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-import androidx.test.uiautomator.Until;
-
-public class ImeAppHelper extends FlickerAppHelper {
-
-    ImeAppHelper(Instrumentation instr, String launcherName) {
-        super(instr, launcherName);
-    }
-
-    public ImeAppHelper(Instrumentation instr) {
-        this(instr, "ImeApp");
-    }
-
-    public void openIME(UiDevice device) {
-        UiObject2 editText = device.wait(
-                Until.findObject(By.res(getPackage(), "plain_text_input")),
-                AutomationUtils.FIND_TIMEOUT);
-        assertNotNull("Text field not found, this usually happens when the device was left "
-                + "in an unknown state (e.g. in split screen)", editText);
-        editText.click();
-
-        if (!AutomationUtils.waitForIME(device)) {
-            fail("IME did not appear");
-        }
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
new file mode 100644
index 0000000..979cbea
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import androidx.test.uiautomator.Until
+import org.junit.Assert
+
+open class ImeAppHelper(
+    instr: Instrumentation,
+    launcherName: String = "ImeApp"
+) : FlickerAppHelper(instr, launcherName) {
+    open fun openIME(device: UiDevice) {
+        val editText = device.wait(
+                Until.findObject(By.res(getPackage(), "plain_text_input")),
+                AutomationUtils.FIND_TIMEOUT)
+        Assert.assertNotNull("Text field not found, this usually happens when the device " +
+                "was left in an unknown state (e.g. in split screen)", editText)
+        editText.click()
+        if (!AutomationUtils.waitForIME(device)) {
+            Assert.fail("IME did not appear")
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
deleted file mode 100644
index f2b7a7e3..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm.flicker.helpers;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.hasPipWindow;
-
-import static org.junit.Assert.assertNotNull;
-
-import android.app.Instrumentation;
-
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.UiObject2;
-
-public class PipAppHelper extends FlickerAppHelper {
-
-    public PipAppHelper(Instrumentation instr) {
-        super(instr, "PipApp");
-    }
-
-    public void clickEnterPipButton(UiDevice device) {
-        UiObject2 enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"));
-        assertNotNull("Pip button not found, this usually happens when the device was left "
-                + "in an unknown state (e.g. in split screen)", enterPipButton);
-        enterPipButton.click();
-        hasPipWindow(device);
-    }
-
-    public void closePipWindow(UiDevice device) {
-        AutomationUtils.closePipWindow(device);
-    }
-
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
new file mode 100644
index 0000000..daee810
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.helpers
+
+import android.app.Instrumentation
+import androidx.test.uiautomator.By
+import androidx.test.uiautomator.UiDevice
+import org.junit.Assert
+
+class PipAppHelper(instr: Instrumentation) : FlickerAppHelper(instr, "PipApp") {
+    fun clickEnterPipButton(device: UiDevice) {
+        val enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"))
+        Assert.assertNotNull("Pip button not found, this usually happens when the device " +
+                "was left in an unknown state (e.g. in split screen)", enterPipButton)
+        enterPipButton.click()
+        AutomationUtils.hasPipWindow(device)
+    }
+
+    fun closePipWindow(device: UiDevice) {
+        AutomationUtils.closePipWindow(device)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
new file mode 100644
index 0000000..6946618
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class CloseImeAutoOpenWindowToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : CloseImeWindowToAppTest(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppAutoFocusHelper(instrumentation)
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppAutoFocusHelper,
+                instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppLayerIsAlwaysVisible() {
+        super.checkVisibility_imeAppLayerIsAlwaysVisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppWindowIsAlwaysVisible() {
+        super.checkVisibility_imeAppWindowIsAlwaysVisible()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
new file mode 100644
index 0000000..a1030d8
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class CloseImeAutoOpenWindowToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : CloseImeWindowToHomeTest(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppAutoFocusHelper(instrumentation)
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppAutoFocusHelper,
+                instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeWindowBecomesInvisible() {
+        super.checkVisibility_imeWindowBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible()
+    }
+
+    @FlakyTest(bugId = 157449248)
+    @Ignore("Waiting bug feedback")
+    @Test
+    override fun checkVisibility_imeAppWindowBecomesInvisible() {
+        super.checkVisibility_imeAppWindowBecomesInvisible()
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
new file mode 100644
index 0000000..6e7c92b
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class CloseImeWindowToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(instrumentation)
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToApp(testApp as ImeAppHelper,
+                instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Ignore("Flaky. Pending debug")
+    @Test
+    open fun checkVisibility_imeLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    open fun checkVisibility_imeAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    open fun checkVisibility_imeAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        const val IME_WINDOW_TITLE = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
new file mode 100644
index 0000000..7b155eb
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window closing to home transitions.
+ * To run this test: `atest FlickerTests:CloseImeWindowToHomeTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+open class CloseImeWindowToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(instrumentation)
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextLoseFocusToHome(testApp as ImeAppHelper,
+                instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    open fun checkVisibility_imeWindowBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsImeWindow(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesImeWindow(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 153739621)
+    @Ignore
+    @Test
+    open fun checkVisibility_imeLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 153739621)
+    @Ignore
+    @Test
+    fun checkVisibility_imeAppLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsLayer(testApp.getPackage())
+                    .then()
+                    .hidesLayer(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    open fun checkVisibility_imeAppWindowBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .then()
+                    .hidesAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        const val IME_WINDOW_TITLE: String = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
new file mode 100644
index 0000000..9885359
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.ime
+
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test IME window opening transitions.
+ * To run this test: `atest FlickerTests:OpenImeWindowTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenImeWindowTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = ImeAppHelper(instrumentation)
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.editTextSetFocus(testApp as ImeAppHelper,
+                instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_imeWindowBecomesVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .hidesImeWindow(IME_WINDOW_TITLE)
+                    .then()
+                    .showsImeWindow(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_imeLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hidesLayer(IME_WINDOW_TITLE)
+                    .then()
+                    .showsLayer(IME_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        private const val IME_WINDOW_TITLE = "InputMethod"
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
new file mode 100644
index 0000000..943a525
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test cold launch app from launcher.
+ * To run this test: `atest FlickerTests:OpenAppColdTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppColdTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(instrumentation,
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.openAppCold(testApp, instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_wallpaperWindowBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .hidesBelowAppWindow("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(
+                            "com.android.launcher3/.Launcher")
+                    .then()
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_wallpaperLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
new file mode 100644
index 0000000..7964d94
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test warm launch app.
+ * To run this test: `atest FlickerTests:OpenAppWarmTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppWarmTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(instrumentation,
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.openAppWarm(testApp, instrumentation, uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_wallpaperBecomesInvisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .hidesBelowAppWindow("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
+    @Test
+    fun checkZOrder_appWindowReplacesLauncherAsTopWindow() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(
+                            "com.android.launcher3/.Launcher")
+                    .then()
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_wallpaperLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer("Wallpaper")
+                    .then()
+                    .replaceVisibleLayer("Wallpaper", testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
new file mode 100644
index 0000000..79321f9
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipTestBase.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.pip
+
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.AfterClass
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+abstract class PipTestBase(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = PipAppHelper(instrumentation)
+    }
+
+    @Test
+    fun checkVisibility_pipWindowBecomesVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .hidesAppWindow(sPipWindowTitle)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_pipLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsLayer(sPipWindowTitle)
+                    .then()
+                    .hidesLayer(sPipWindowTitle)
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        const val sPipWindowTitle = "PipMenuActivity"
+
+        @AfterClass
+        @JvmStatic
+        fun teardown() {
+            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+            if (AutomationUtils.hasPipWindow(device)) {
+                AutomationUtils.closePipWindow(device)
+            }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
new file mode 100644
index 0000000..bfececa
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToAppTest.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.pip
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToAppTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+@Ignore("Waiting bug feedback")
+class PipToAppTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : PipTestBase(beginRotationName, beginRotation) {
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.exitPipModeToApp(testApp as PipAppHelper, instrumentation,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .skipUntilFirstAssertion()
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .showsAppWindowOnTop(testApp.getPackage())
+                    .then()
+                    .hidesAppWindowOnTop(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
new file mode 100644
index 0000000..ecfcd82
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/pip/PipToHomeTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.pip
+
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.PipAppHelper
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test Pip launch.
+ * To run this test: `atest FlickerTests:PipToHomeTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 152738416)
+@Ignore("Waiting bug feedback")
+class PipToHomeTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : PipTestBase(beginRotationName, beginRotation) {
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.exitPipModeToHome(testApp as PipAppHelper, instrumentation,
+                uiDevice, beginRotation)
+                .includeJankyRuns().build()
+
+    @Ignore
+    @Test
+    fun checkVisibility_backgroundWindowVisibleBehindPipLayer() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindowOnTop(sPipWindowTitle)
+                    .then()
+                    .showsBelowAppWindow("Wallpaper")
+                    .then()
+                    .showsAppWindowOnTop("Wallpaper")
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
new file mode 100644
index 0000000..7a581d0
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.rotation
+
+import android.util.Log
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.RotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WindowUtils
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Cycle through supported app rotations.
+ * To run this test: `atest FlickerTest:ChangeAppRotationTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class ChangeAppRotationTest(
+    beginRotationName: String,
+    endRotationName: String,
+    beginRotation: Int,
+    endRotation: Int
+) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
+    init {
+        testApp = StandardAppHelper(instrumentation,
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.changeAppRotation(testApp, instrumentation, uiDevice,
+                beginRotation, endRotation)
+                .includeJankyRuns().build()
+
+    @Test
+    fun checkPosition_appLayerRotates() {
+        val startingPos = WindowUtils.getAppPosition(beginRotation)
+        val endingPos = WindowUtils.getAppPosition(endRotation)
+        Log.e(TAG, "startingPos=$startingPos endingPos=$endingPos")
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hasVisibleRegion(testApp.getPackage(), startingPos).inTheBeginning()
+            LayersTraceSubject.assertThat(it)
+                    .hasVisibleRegion(testApp.getPackage(), endingPos).atTheEnd()
+        }
+    }
+
+    @Ignore("Flaky. Pending debug")
+    @Test
+    fun checkVisibility_screenshotLayerBecomesInvisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(testApp.getPackage())
+                    .then()
+                    .replaceVisibleLayer(testApp.getPackage(), SCREENSHOT_LAYER)
+                    .then()
+                    .showsLayer(testApp.getPackage()).and().showsLayer(SCREENSHOT_LAYER)
+                    .then()
+                    .replaceVisibleLayer(SCREENSHOT_LAYER, testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
new file mode 100644
index 0000000..d53af6f
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.rotation
+
+import android.content.Intent
+import android.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.RotationTestBase
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.testapp.ActivityOptions
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Cycle through supported app rotations using seamless rotations.
+ * To run this test: `atest FlickerTests:SeamlessAppRotationTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 147659548)
+@Ignore("Waiting bug feedback")
+class SeamlessAppRotationTest(
+    private val intent: Intent,
+    beginRotationName: String,
+    endRotationName: String,
+    beginRotation: Int,
+    endRotation: Int
+) : RotationTestBase(beginRotationName, endRotationName, beginRotation, endRotation) {
+    override val transitionToRun: TransitionRunner
+        get() {
+            var intentId = ""
+            if (intent.extras?.getBoolean(ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
+                intentId = "BUSY_UI_THREAD"
+            }
+            return CommonTransitions.changeAppRotation(intent, intentId,
+                    InstrumentationRegistry.getContext(), instrumentation, uiDevice,
+                    beginRotation, endRotation).build()
+        }
+
+    @Test
+    fun checkPosition_appLayerRotates() {
+        val startingPos = WindowUtils.getAppPosition(beginRotation)
+        val endingPos = WindowUtils.getAppPosition(endRotation)
+        if (startingPos == endingPos) {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
+                        .forAllEntries()
+            }
+        } else {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .hasVisibleRegion(intent.component?.packageName ?: "", startingPos)
+                        .then()
+                        .hasVisibleRegion(intent.component?.packageName ?: "", endingPos)
+                        .forAllEntries()
+            }
+        }
+    }
+
+    @Test
+    fun checkCoveredRegion_noUncoveredRegions() {
+        val startingBounds = WindowUtils.getDisplayBounds(beginRotation)
+        val endingBounds = WindowUtils.getDisplayBounds(endRotation)
+        if (startingBounds == endingBounds) {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .coversRegion(startingBounds)
+                        .forAllEntries()
+            }
+        } else {
+            checkResults {
+                LayersTraceSubject.assertThat(it)
+                        .coversRegion(startingBounds)
+                        .then()
+                        .coversRegion(endingBounds)
+                        .forAllEntries()
+            }
+        }
+    }
+
+    companion object {
+        // launch test activity that supports seamless rotation
+
+        // launch test activity that supports seamless rotation with a busy UI thread to miss frames
+        // when the app is asked to redraw
+        @Parameterized.Parameters(name = "{0}")
+        @JvmStatic
+        fun getParams(): Collection<Array<Any>> {
+            val supportedRotations = intArrayOf(Surface.ROTATION_0, Surface.ROTATION_90)
+            val params: MutableCollection<Array<Any>> = ArrayList()
+            val testIntents = ArrayList<Intent>()
+
+            // launch test activity that supports seamless rotation
+            var intent = Intent(Intent.ACTION_MAIN)
+            intent.component = ActivityOptions.SEAMLESS_ACTIVITY_COMPONENT_NAME
+            testIntents.add(intent)
+
+            // launch test activity that supports seamless rotation with a busy UI thread to miss frames
+            // when the app is asked to redraw
+            intent = Intent(intent)
+            intent.putExtra(ActivityOptions.EXTRA_STARVE_UI_THREAD, true)
+            testIntents.add(intent)
+            for (testIntent in testIntents) {
+                for (begin in supportedRotations) {
+                    for (end in supportedRotations) {
+                        if (begin != end) {
+                            var testId: String = Surface.rotationToString(begin) +
+                                    "_" + Surface.rotationToString(end)
+                            if (testIntent.extras?.getBoolean(
+                                            ActivityOptions.EXTRA_STARVE_UI_THREAD) == true) {
+                                testId += "_" + "BUSY_UI_THREAD"
+                            }
+                            params.add(arrayOf(testId, testIntent, begin, end))
+                        }
+                    }
+                }
+            }
+            return params
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
new file mode 100644
index 0000000..b5611a4
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/OpenAppToSplitScreenTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.splitscreen
+
+import androidx.test.filters.LargeTest
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.NonRotationTestBase
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WmTraceSubject
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest FlickerTests:OpenAppToSplitScreenTest`
+ */
+@LargeTest
+@RunWith(Parameterized::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppToSplitScreenTest(
+    beginRotationName: String,
+    beginRotation: Int
+) : NonRotationTestBase(beginRotationName, beginRotation) {
+    init {
+        testApp = StandardAppHelper(instrumentation,
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.appToSplitScreen(testApp, instrumentation, uiDevice,
+                beginRotation).includeJankyRuns().build()
+
+    @Test
+    fun checkVisibility_navBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerBecomesVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .hidesLayer(DOCKED_STACK_DIVIDER)
+                    .then()
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
new file mode 100644
index 0000000..b6cce26
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/ResizeSplitScreenTest.kt
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.splitscreen
+
+import android.graphics.Region
+import android.util.Rational
+import android.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.FlakyTest
+import androidx.test.filters.LargeTest
+import androidx.test.runner.AndroidJUnit4
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.FlickerTestBase
+import com.android.server.wm.flicker.LayersTrace
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.TransitionResult
+import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import com.android.server.wm.flicker.helpers.ImeAppHelper
+import com.google.common.truth.Truth
+import org.junit.AfterClass
+import org.junit.FixMethodOrder
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+/**
+ * Test split screen resizing window transitions.
+ * To run this test: `atest FlickerTests:ResizeSplitScreenTest`
+ *
+ * Currently it runs only in 0 degrees because of b/156100803
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 159096424)
+@Ignore("Waiting bug feedback")
+class ResizeSplitScreenTest : FlickerTestBase() {
+    init {
+        testApp = StandardAppHelper(instrumentation,
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() {
+            val bottomApp = ImeAppHelper(instrumentation)
+            return CommonTransitions.resizeSplitScreen(testApp, bottomApp, instrumentation,
+                    uiDevice, Surface.ROTATION_0,
+                    Rational(1, 3), Rational(2, 3))
+                    .includeJankyRuns().build()
+        }
+
+    @Test
+    fun checkVisibility_topAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(sSimpleActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_bottomAppLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(sImeActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerIsAlwaysVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    @Ignore("Waiting feedback")
+    fun checkPosition_appsStartingBounds() {
+        val displayBounds = WindowUtils.getDisplayBounds()
+        checkResults { result: TransitionResult ->
+            val entries = LayersTrace.parseFrom(result.layersTrace,
+                    result.layersTracePath, result.layersTraceChecksum)
+            Truth.assertThat(entries.entries).isNotEmpty()
+            val startingDividerBounds = entries.entries[0].getVisibleBounds(
+                    DOCKED_STACK_DIVIDER).bounds
+            val startingTopAppBounds = Region(0, 0, startingDividerBounds.right,
+                    startingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
+            val startingBottomAppBounds = Region(0,
+                    startingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
+                    displayBounds.right,
+                    displayBounds.bottom - WindowUtils.getNavigationBarHeight())
+            LayersTraceSubject.assertThat(result)
+                    .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
+                    .inTheBeginning()
+            LayersTraceSubject.assertThat(result)
+                    .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
+                    .inTheBeginning()
+        }
+    }
+
+    @Test
+    @Ignore("Waiting feedback")
+    fun checkPosition_appsEndingBounds() {
+        val displayBounds = WindowUtils.getDisplayBounds()
+        checkResults { result: TransitionResult ->
+            val entries = LayersTrace.parseFrom(result.layersTrace,
+                    result.layersTracePath, result.layersTraceChecksum)
+            Truth.assertThat(entries.entries).isNotEmpty()
+            val endingDividerBounds = entries.entries[entries.entries.size - 1].getVisibleBounds(
+                    DOCKED_STACK_DIVIDER).bounds
+            val startingTopAppBounds = Region(0, 0, endingDividerBounds.right,
+                    endingDividerBounds.top + WindowUtils.getDockedStackDividerInset())
+            val startingBottomAppBounds = Region(0,
+                    endingDividerBounds.bottom - WindowUtils.getDockedStackDividerInset(),
+                    displayBounds.right,
+                    displayBounds.bottom - WindowUtils.getNavigationBarHeight())
+            LayersTraceSubject.assertThat(result)
+                    .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
+                    .atTheEnd()
+            LayersTraceSubject.assertThat(result)
+                    .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
+                    .atTheEnd()
+        }
+    }
+
+    @Test
+    fun checkVisibility_navBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    @FlakyTest(bugId = 156223549)
+    @Ignore("Waiting bug feedback")
+    fun checkVisibility_topAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindow(sSimpleActivity)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    @FlakyTest(bugId = 156223549)
+    @Ignore("Waiting bug feedback")
+    fun checkVisibility_bottomAppWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAppWindow(sImeActivity)
+                    .forAllEntries()
+        }
+    }
+
+    companion object {
+        private const val sSimpleActivity = "SimpleActivity"
+        private const val sImeActivity = "ImeActivity"
+
+        @AfterClass
+        @JvmStatic
+        fun teardown() {
+            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+            if (AutomationUtils.isInSplitScreen(device)) {
+                AutomationUtils.exitSplitScreen(device)
+            }
+        }
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
new file mode 100644
index 0000000..fdcafdb
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/splitscreen/SplitScreenToLauncherTest.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.splitscreen
+
+import android.view.Surface
+import androidx.test.InstrumentationRegistry
+import androidx.test.filters.LargeTest
+import androidx.test.runner.AndroidJUnit4
+import androidx.test.uiautomator.UiDevice
+import com.android.server.wm.flicker.CommonTransitions
+import com.android.server.wm.flicker.FlickerTestBase
+import com.android.server.wm.flicker.LayersTraceSubject
+import com.android.server.wm.flicker.StandardAppHelper
+import com.android.server.wm.flicker.TransitionRunner
+import com.android.server.wm.flicker.WindowUtils
+import com.android.server.wm.flicker.WmTraceSubject
+import com.android.server.wm.flicker.helpers.AutomationUtils
+import org.junit.AfterClass
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+
+/**
+ * Test open app to split screen.
+ * To run this test: `atest FlickerTests:SplitScreenToLauncherTest`
+ */
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class SplitScreenToLauncherTest : FlickerTestBase() {
+    init {
+        testApp = StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+                "com.android.server.wm.flicker.testapp", "SimpleApp")
+    }
+
+    override val transitionToRun: TransitionRunner
+        get() = CommonTransitions.splitScreenToLauncher(testApp, instrumentation, uiDevice,
+                Surface.ROTATION_0).includeJankyRuns().build()
+
+    @Test
+    fun checkCoveredRegion_noUncoveredRegions() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .coversRegion(WindowUtils.getDisplayBounds()).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_dividerLayerBecomesInVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(DOCKED_STACK_DIVIDER)
+                    .then()
+                    .hidesLayer(DOCKED_STACK_DIVIDER)
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_appLayerBecomesInVisible() {
+        checkResults {
+            LayersTraceSubject.assertThat(it)
+                    .showsLayer(testApp.getPackage())
+                    .then()
+                    .hidesLayer(testApp.getPackage())
+                    .forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_navBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    @Test
+    fun checkVisibility_statusBarWindowIsAlwaysVisible() {
+        checkResults {
+            WmTraceSubject.assertThat(it)
+                    .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries()
+        }
+    }
+
+    companion object {
+        @AfterClass
+        @JvmStatic
+        fun teardown() {
+            val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
+            if (AutomationUtils.isInSplitScreen(device)) {
+                AutomationUtils.exitSplitScreen(device)
+            }
+        }
+    }
+}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 65d15a7..da6018e 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -24,7 +24,16 @@
     name: "StagedInstallInternalTest",
     srcs: ["src/**/*.java"],
     libs: ["tradefed"],
-    static_libs: ["testng", "compatibility-tradefed", "frameworks-base-hostutils"],
+    static_libs: [
+        "testng",
+        "compatibility-tradefed",
+        "frameworks-base-hostutils",
+        "module_test_util",
+    ],
+    data: [
+        ":com.android.apex.cts.shim.v2_prebuilt",
+        ":TestAppAv1",
+    ],
     test_suites: ["general-tests"],
     test_config: "StagedInstallInternalTest.xml",
 }
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index e6ba801..7cfbdc2 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -20,9 +20,11 @@
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
 
 import com.android.ddmlib.Log;
 import com.android.tests.rollback.host.AbandonSessionsRule;
+import com.android.tests.util.ModuleTestUtils;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.util.ProcessInfo;
@@ -33,6 +35,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.io.File;
+
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class StagedInstallInternalTest extends BaseHostJUnit4Test {
 
@@ -41,6 +45,10 @@
 
     @Rule
     public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this);
+    private static final String SHIM_V2 = "com.android.apex.cts.shim.v2.apex";
+    private static final String APK_A = "TestAppAv1.apk";
+
+    private final ModuleTestUtils mTestUtils = new ModuleTestUtils(this);
 
     /**
      * Runs the given phase of a test by calling into the device.
@@ -82,6 +90,58 @@
         runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
     }
 
+    @Test
+    public void testAdbStagedInstallWaitForReadyFlagWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        String output = getDevice().executeAdbCommand("install", "--staged",
+                "--wait-for-staged-ready", "60000", apexFile.getAbsolutePath());
+        assertThat(output).contains("Reboot device to apply staged session");
+        String sessionId = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+        assertThat(sessionId).isNotEmpty();
+    }
+
+    @Test
+    public void testAdbStagedInstallNoWaitFlagWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        String output = getDevice().executeAdbCommand("install", "--staged",
+                "--no-wait", apexFile.getAbsolutePath());
+        assertThat(output).doesNotContain("Reboot device to apply staged session");
+        assertThat(output).contains("Success");
+        String sessionId = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").trim();
+        assertThat(sessionId).isEmpty();
+    }
+
+    @Test
+    public void testAdbInstallMultiPackageCommandWorks() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mTestUtils.isApexUpdateSupported());
+
+        File apexFile = mTestUtils.getTestFile(SHIM_V2);
+        File apkFile = mTestUtils.getTestFile(APK_A);
+        String output = getDevice().executeAdbCommand("install-multi-package",
+                apexFile.getAbsolutePath(), apkFile.getAbsolutePath());
+        assertThat(output).contains("Created parent session");
+        assertThat(output).contains("Created child session");
+        assertThat(output).contains("Success. Reboot device to apply staged session");
+
+        // Ensure there is only one parent session
+        String[] sessionIds = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-parent --only-sessionid").split("\n");
+        assertThat(sessionIds.length).isEqualTo(1);
+        // Ensure there are two children session
+        sessionIds = getDevice().executeShellCommand(
+                "pm get-stagedsessions --only-ready --only-sessionid").split("\n");
+        assertThat(sessionIds.length).isEqualTo(3);
+    }
+
     private void restartSystemServer() throws Exception {
         // Restart the system server
         ProcessInfo oldPs = getDevice().getProcessByName("system_server");
diff --git a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
index 9adbf21..16fed39 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsSubscriptionsMonitorTest.java
@@ -17,7 +17,6 @@
 package com.android.server.net;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyInt;
@@ -32,7 +31,6 @@
 import android.annotation.NonNull;
 import android.content.Context;
 import android.os.test.TestLooper;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
@@ -63,6 +61,7 @@
     private static final String TEST_IMSI3 = "466929999999999";
 
     @Mock private Context mContext;
+    @Mock private PhoneStateListener mPhoneStateListener;
     @Mock private SubscriptionManager mSubscriptionManager;
     @Mock private TelephonyManager mTelephonyManager;
     @Mock private NetworkStatsSubscriptionsMonitor.Delegate mDelegate;
@@ -216,53 +215,4 @@
         verify(mTelephonyManager, times(2)).listen(any(), eq(PhoneStateListener.LISTEN_NONE));
         assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
     }
-
-    @Test
-    public void test5g() {
-        mMonitor.start();
-        // Insert sim1, verify RAT type is NETWORK_TYPE_UNKNOWN, and never get any callback
-        // before changing RAT type. Also capture listener for later use.
-        addTestSub(TEST_SUBID1, TEST_IMSI1);
-        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        final ArgumentCaptor<RatTypeListener> ratTypeListenerCaptor =
-                ArgumentCaptor.forClass(RatTypeListener.class);
-        verify(mTelephonyManager, times(1)).listen(ratTypeListenerCaptor.capture(),
-                eq(PhoneStateListener.LISTEN_SERVICE_STATE));
-        final RatTypeListener listener = CollectionUtils
-                .find(ratTypeListenerCaptor.getAllValues(), it -> it.getSubId() == TEST_SUBID1);
-        assertNotNull(listener);
-
-        // Set RAT type to 5G NSA (non-standalone) mode, verify the monitor outputs NETWORK_TYPE_NR.
-        final ServiceState serviceState = mock(ServiceState.class);
-        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE);
-        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
-        listener.onServiceStateChanged(serviceState);
-        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
-        reset(mDelegate);
-
-        // Set RAT type to LTE without NR connected, the RAT type should be downgraded to LTE.
-        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE);
-        listener.onServiceStateChanged(serviceState);
-        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_LTE);
-        reset(mDelegate);
-
-        // Verify NR connected with other RAT type does not take effect.
-        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_UMTS);
-        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
-        listener.onServiceStateChanged(serviceState);
-        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_UMTS);
-        reset(mDelegate);
-
-        // Set RAT type to 5G standalone mode, the RAT type should be NR.
-        setRatTypeForSub(ratTypeListenerCaptor.getAllValues(), TEST_SUBID1,
-                TelephonyManager.NETWORK_TYPE_NR);
-        assertRatTypeChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
-        reset(mDelegate);
-
-        // Set NR state to none in standalone mode does not change anything.
-        when(serviceState.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_NR);
-        when(serviceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_NONE);
-        listener.onServiceStateChanged(serviceState);
-        assertRatTypeNotChangedForSub(TEST_IMSI1, TelephonyManager.NETWORK_TYPE_NR);
-    }
 }
diff --git a/tools/validatekeymaps/Android.bp b/tools/validatekeymaps/Android.bp
index 819e75b..61ce44c 100644
--- a/tools/validatekeymaps/Android.bp
+++ b/tools/validatekeymaps/Android.bp
@@ -20,6 +20,7 @@
         "libutils",
         "libcutils",
         "liblog",
+        "libui-types",
     ],
 
     // This tool is prebuilt if we're doing an app-only build.
