Merge "Add DeviceConfig flag to be able to change sampling ratio of AttributedAppOps atom after R release." into rvc-dev
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 8ab9524..bfc1367 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -97,9 +97,6 @@
 droidstubs {
     name: "api-stubs-docs",
     defaults: ["metalava-full-api-stubs-default"],
-    api_filename: "public_api.txt",
-    private_api_filename: "private.txt",
-    removed_api_filename: "removed.txt",
     removed_dex_api_filename: "removed-dex.txt",
     arg_files: [
         "core/res/AndroidManifest.xml",
@@ -142,10 +139,6 @@
 droidstubs {
     name: "system-api-stubs-docs",
     defaults: ["metalava-full-api-stubs-default"],
-    api_tag_name: "SYSTEM",
-    api_filename: "system-api.txt",
-    private_api_filename: "system-private.txt",
-    removed_api_filename: "system-removed.txt",
     removed_dex_api_filename: "system-removed-dex.txt",
     arg_files: [
         "core/res/AndroidManifest.xml",
@@ -178,9 +171,6 @@
 droidstubs {
     name: "test-api-stubs-docs",
     defaults: ["metalava-full-api-stubs-default"],
-    api_tag_name: "TEST",
-    api_filename: "test-api.txt",
-    removed_api_filename: "test-removed.txt",
     arg_files: [
         "core/res/AndroidManifest.xml",
     ],
@@ -216,7 +206,6 @@
 droidstubs {
     name: "module-lib-api",
     defaults: ["metalava-full-api-stubs-default"],
-    api_tag_name: "MODULE_LIB",
     arg_files: ["core/res/AndroidManifest.xml"],
     args: metalava_framework_docs_args + module_libs,
     check_api: {
diff --git a/api/test-current.txt b/api/test-current.txt
index abfd12b..d8db1b9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5260,10 +5260,20 @@
 
 package android.window {
 
+  public final class DisplayAreaInfo implements android.os.Parcelable {
+    ctor public DisplayAreaInfo(@NonNull android.window.WindowContainerToken, int);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.window.DisplayAreaInfo> CREATOR;
+    field @NonNull public final android.content.res.Configuration configuration;
+    field public final int displayId;
+    field @NonNull public final android.window.WindowContainerToken token;
+  }
+
   public class DisplayAreaOrganizer extends android.window.WindowOrganizer {
     ctor public DisplayAreaOrganizer();
-    method public void onDisplayAreaAppeared(@NonNull android.window.WindowContainerToken);
-    method public void onDisplayAreaVanished(@NonNull android.window.WindowContainerToken);
+    method public void onDisplayAreaAppeared(@NonNull android.window.DisplayAreaInfo);
+    method public void onDisplayAreaVanished(@NonNull android.window.DisplayAreaInfo);
     method @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) public void registerOrganizer(int);
     field public static final int FEATURE_DEFAULT_TASK_CONTAINER = 1; // 0x1
     field public static final int FEATURE_ROOT = 0; // 0x0
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index cfc1de4..c9ccfb9 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -18,7 +18,6 @@
 #include "Log.h"
 #include "FieldValue.h"
 #include "HashableDimensionKey.h"
-#include "atoms_info.h"
 #include "math.h"
 
 namespace android {
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index cc48d50..062fcf9 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -25,7 +25,6 @@
 #include <frameworks/base/cmds/statsd/src/experiment_ids.pb.h>
 
 #include "android-base/stringprintf.h"
-#include "atoms_info.h"
 #include "external/StatsPullerManager.h"
 #include "guardrail/StatsdStats.h"
 #include "logd/LogEvent.h"
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 88824f0..b3da32fc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -9000,7 +9000,7 @@
  * Each pull creates multiple atoms, one for each call. The sequence is randomized when pulled.
  *
  * Pulled from:
- *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
  */
 message VoiceCallSession {
     // Bearer (IMS or CS) when the call started.
@@ -9064,9 +9064,7 @@
     // See https://source.android.com/devices/tech/config/carrierid.
     optional int32 carrier_id = 18;
 
-    // Whether an SRVCC has been completed successfully.
-    // SRVCC (CS fallback) should be recorded in the IMS call since there will be no more SRVCC
-    // events once the call is switched to CS.
+    // Whether an SRVCC has been completed successfully for this call.
     optional bool srvcc_completed = 19;
 
     // Number of SRVCC failures.
@@ -9075,7 +9073,8 @@
     // Number of SRVCC cancellations.
     optional int64 srvcc_cancellation_count = 21;
 
-    // Whether the Real-Time Text (RTT) was ever used in the call.
+    // Whether the Real-Time Text (RTT) was ever used in the call (rather than whether RTT was
+    // enabled in the dialer's settings).
     optional bool rtt_enabled = 22;
 
     // Whether this was an emergency call.
@@ -9092,7 +9091,7 @@
  * time. The atom will be skipped if not enough data is available.
  *
  * Pulled from:
- *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/PersistPullers.java
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
  */
 message VoiceCallRatUsage {
     // Carrier ID (https://source.android.com/devices/tech/config/carrierid).
@@ -9113,7 +9112,7 @@
  * Pulls the number of active SIM slots and SIMs/eSIM profiles.
  *
  * Pulled from:
- *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
  */
 message SimSlotState {
     // Number of active SIM slots (both physical and eSIM profiles) in the device.
@@ -9134,7 +9133,7 @@
  * This atom reports the capabilities of the device, rather than the network it has access to.
  *
  * Pulled from:
- *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/NonPersistPullers.java
+ *   frameworks/opt/telephony/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
  */
 message SupportedRadioAccessFamily {
     // A bitmask of supported radio technologies.
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
index 9e72a23..84bc684 100644
--- a/cmds/statsd/src/external/puller_util.cpp
+++ b/cmds/statsd/src/external/puller_util.cpp
@@ -17,7 +17,6 @@
 #define DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
-#include "atoms_info.h"
 #include "puller_util.h"
 
 namespace android {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 21e524a..805281c 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -16,7 +16,6 @@
 #pragma once
 
 #include "config/ConfigKey.h"
-#include "atoms_info.h"
 
 #include <gtest/gtest_prod.h>
 #include <log/log_time.h>
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index e03de0b..d7ad27b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -387,11 +387,14 @@
         // Uid is 3rd from last field and must match the caller's uid,
         // unless that caller is statsd itself (statsd is allowed to spoof uids).
         long appHookUid = event.GetLong(event.size()-2, &err);
-        if (err != NO_ERROR ) {
+        if (err != NO_ERROR) {
             VLOG("APP_BREADCRUMB_REPORTED had error when parsing the uid");
             return false;
         }
-        int32_t loggerUid = event.GetUid();
+
+        // Because the uid within the LogEvent may have been mapped from
+        // isolated to host, map the loggerUid similarly before comparing.
+        int32_t loggerUid = mUidMap->getHostUidOrSelf(event.GetUid());
         if (loggerUid != appHookUid && loggerUid != AID_STATSD) {
             VLOG("APP_BREADCRUMB_REPORTED has invalid uid: claimed %ld but caller is %d",
                  appHookUid, loggerUid);
@@ -400,7 +403,7 @@
 
         // The state must be from 0,3. This part of code must be manually updated.
         long appHookState = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR ) {
+        if (err != NO_ERROR) {
             VLOG("APP_BREADCRUMB_REPORTED had error when parsing the state field");
             return false;
         } else if (appHookState < 0 || appHookState > 3) {
@@ -414,7 +417,7 @@
 
         // Uid is the first field provided.
         long jankUid = event.GetLong(1, &err);
-        if (err != NO_ERROR ) {
+        if (err != NO_ERROR) {
             VLOG("Davey occurred had error when parsing the uid");
             return false;
         }
@@ -426,7 +429,7 @@
         }
 
         long duration = event.GetLong(event.size(), &err);
-        if (err != NO_ERROR ) {
+        if (err != NO_ERROR) {
             VLOG("Davey occurred had error when parsing the duration");
             return false;
         } else if (duration > 100000) {
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 88616dd..3ab44f4 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -21,7 +21,6 @@
 
 #include <inttypes.h>
 
-#include "atoms_info.h"
 #include "FieldValue.h"
 #include "MetricProducer.h"
 #include "condition/CombinationConditionTracker.h"
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index f9fddc8..2acffee 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -24,7 +24,6 @@
 
 #include "statscompanion_util.h"
 
-using android::util::AtomsInfo;
 using android::util::FIELD_COUNT_REPEATED;
 using android::util::FIELD_TYPE_BOOL;
 using android::util::FIELD_TYPE_FIXED64;
diff --git a/cmds/uiautomator/library/Android.bp b/cmds/uiautomator/library/Android.bp
index 3a26063..c33d31f 100644
--- a/cmds/uiautomator/library/Android.bp
+++ b/cmds/uiautomator/library/Android.bp
@@ -28,9 +28,6 @@
     installable: false,
     args: "-stubpackages com.android.uiautomator.core:" +
           "com.android.uiautomator.testrunner",
-    api_tag_name: "UIAUTOMATOR",
-    api_filename: "uiautomator_api.txt",
-    removed_api_filename: "uiautomator_removed_api.txt",
 
     check_api: {
         current: {
diff --git a/core/java/android/content/pm/CrossProfileApps.java b/core/java/android/content/pm/CrossProfileApps.java
index 144a07e..99e6d91 100644
--- a/core/java/android/content/pm/CrossProfileApps.java
+++ b/core/java/android/content/pm/CrossProfileApps.java
@@ -279,12 +279,8 @@
      * <ul>
      * <li>{@code UserManager#getEnabledProfileIds(int)} ()} returns at least one other profile for
      * the calling user.</li>
-     * <li>The calling app has requested</li>
-     * {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} in its manifest.
-     * <li>The calling package has either been whitelisted by default by the OEM or has been
-     * explicitly whitelisted by the admin via
-     * {@link android.app.admin.DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)}.
-     * </li>
+     * <li>The calling app has requested
+     * {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} in its manifest.</li>
      * </ul>
      *
      * <p>Note that in order for the user to be able to grant the consent, the requesting package
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index eb6901f6..2012039 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -488,11 +488,7 @@
      * The respective value of such request key can be obtained by calling
      * {@link CaptureRequest.Builder#getPhysicalCameraKey }. Capture requests that contain
      * individual physical device requests must be built via
-     * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}.
-     * Such extended capture requests can be passed only to
-     * {@link CameraCaptureSession#capture } or {@link CameraCaptureSession#captureBurst } and
-     * not to {@link CameraCaptureSession#setRepeatingRequest } or
-     * {@link CameraCaptureSession#setRepeatingBurst }.</p>
+     * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}.</p>
      *
      * <p>The list returned is not modifiable, so any attempts to modify it will throw
      * a {@code UnsupportedOperationException}.</p>
diff --git a/core/java/android/window/DisplayAreaInfo.aidl b/core/java/android/window/DisplayAreaInfo.aidl
new file mode 100644
index 0000000..b745017
--- /dev/null
+++ b/core/java/android/window/DisplayAreaInfo.aidl
@@ -0,0 +1,18 @@
+/**
+ * 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 android.window;
+
+parcelable DisplayAreaInfo;
diff --git a/core/java/android/window/DisplayAreaInfo.java b/core/java/android/window/DisplayAreaInfo.java
new file mode 100644
index 0000000..0d35bca
--- /dev/null
+++ b/core/java/android/window/DisplayAreaInfo.java
@@ -0,0 +1,87 @@
+/*
+ * 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 android.window;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.content.res.Configuration;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Stores information about a particular {@link com.android.server.wm.DisplayArea}. This object will
+ * be sent to registered {@link DisplayAreaOrganizer} to provide information when the DisplayArea
+ * is added, removed, or changed.
+ *
+ * @hide
+ */
+@TestApi
+public final class DisplayAreaInfo implements Parcelable {
+
+    @NonNull
+    public final WindowContainerToken token;
+
+    @NonNull
+    public final Configuration configuration = new Configuration();
+
+    /**
+     * The id of the display this display area is associated with.
+     */
+    public final int displayId;
+
+    public DisplayAreaInfo(@NonNull WindowContainerToken token, int displayId) {
+        this.token = token;
+        this.displayId = displayId;
+    }
+
+    private DisplayAreaInfo(Parcel in) {
+        token = WindowContainerToken.CREATOR.createFromParcel(in);
+        configuration.readFromParcel(in);
+        displayId = in.readInt();
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        token.writeToParcel(dest, flags);
+        configuration.writeToParcel(dest, flags);
+        dest.writeInt(displayId);
+    }
+
+    @NonNull
+    public static final Creator<DisplayAreaInfo> CREATOR = new Creator<DisplayAreaInfo>() {
+        @Override
+        public DisplayAreaInfo createFromParcel(Parcel in) {
+            return new DisplayAreaInfo(in);
+        }
+
+        @Override
+        public DisplayAreaInfo[] newArray(int size) {
+            return new DisplayAreaInfo[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "DisplayAreaInfo{token=" + token
+                + " config=" + configuration + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/window/DisplayAreaOrganizer.java b/core/java/android/window/DisplayAreaOrganizer.java
index 6ae70b7..f3ef5a0 100644
--- a/core/java/android/window/DisplayAreaOrganizer.java
+++ b/core/java/android/window/DisplayAreaOrganizer.java
@@ -52,21 +52,42 @@
         }
     }
 
-    public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {}
+    /**
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+    public void unregisterOrganizer() {
+        try {
+            getController().unregisterOrganizer(mInterface);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 
-    public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {}
+    public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) {}
 
+    public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {}
+
+    /**
+     * @hide
+     */
+    public void onDisplayAreaInfoChanged(@NonNull DisplayAreaInfo displayAreaInfo) {}
 
     private final IDisplayAreaOrganizer mInterface = new IDisplayAreaOrganizer.Stub() {
 
         @Override
-        public void onDisplayAreaAppeared(@NonNull WindowContainerToken displayArea) {
-            DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayArea);
+        public void onDisplayAreaAppeared(@NonNull DisplayAreaInfo displayAreaInfo) {
+            DisplayAreaOrganizer.this.onDisplayAreaAppeared(displayAreaInfo);
         }
 
         @Override
-        public void onDisplayAreaVanished(@NonNull WindowContainerToken displayArea) {
-            DisplayAreaOrganizer.this.onDisplayAreaVanished(displayArea);
+        public void onDisplayAreaVanished(@NonNull DisplayAreaInfo displayAreaInfo) {
+            DisplayAreaOrganizer.this.onDisplayAreaVanished(displayAreaInfo);
+        }
+
+        @Override
+        public void onDisplayAreaInfoChanged(@NonNull DisplayAreaInfo displayAreaInfo) {
+            DisplayAreaOrganizer.this.onDisplayAreaInfoChanged(displayAreaInfo);
         }
     };
 
diff --git a/core/java/android/window/IDisplayAreaOrganizer.aidl b/core/java/android/window/IDisplayAreaOrganizer.aidl
index 9c72e60..39a9235 100644
--- a/core/java/android/window/IDisplayAreaOrganizer.aidl
+++ b/core/java/android/window/IDisplayAreaOrganizer.aidl
@@ -16,13 +16,14 @@
 
 package android.window;
 
-import android.window.WindowContainerToken;
+import android.window.DisplayAreaInfo;
 
 /**
  * Interface for WindowManager to delegate control of display areas.
  * {@hide}
  */
 oneway interface IDisplayAreaOrganizer {
-    void onDisplayAreaAppeared(in WindowContainerToken displayArea);
-    void onDisplayAreaVanished(in WindowContainerToken displayArea);
+    void onDisplayAreaAppeared(in DisplayAreaInfo displayAreaInfo);
+    void onDisplayAreaVanished(in DisplayAreaInfo displayAreaInfo);
+    void onDisplayAreaInfoChanged(in DisplayAreaInfo displayAreaInfo);
 }
diff --git a/core/java/android/window/IDisplayAreaOrganizerController.aidl b/core/java/android/window/IDisplayAreaOrganizerController.aidl
index fc6fbef..41b9d02 100644
--- a/core/java/android/window/IDisplayAreaOrganizerController.aidl
+++ b/core/java/android/window/IDisplayAreaOrganizerController.aidl
@@ -23,4 +23,9 @@
 
     /** Register a DisplayAreaOrganizer to manage display areas for a given feature. */
     void registerOrganizer(in IDisplayAreaOrganizer organizer, int displayAreaFeature);
+
+    /**
+     * Unregisters a previously registered display area organizer.
+     */
+    void unregisterOrganizer(in IDisplayAreaOrganizer organizer);
 }
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 21985f0b..3a5720fd 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1555,22 +1555,15 @@
 static void BindMountStorageToLowerFs(const userid_t user_id, const char* dir_name,
     const char* package, fail_fn_t fail_fn) {
 
-  bool hasPackage = (package != nullptr);
   bool hasSdcardFs = IsFilesystemSupported("sdcardfs");
   std::string source;
   if (hasSdcardFs) {
-    source = hasPackage ?
-        StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package) :
-        StringPrintf("/mnt/runtime/default/emulated/%d/%s", user_id, dir_name);
+    source = StringPrintf("/mnt/runtime/default/emulated/%d/%s/%s", user_id, dir_name, package);
   } else {
-    source = hasPackage ?
-        StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s",
-            user_id, user_id, dir_name, package) :
-        StringPrintf("/mnt/pass_through/%d/emulated/%d/%s", user_id, user_id, dir_name);
+    source = StringPrintf("/mnt/pass_through/%d/emulated/%d/%s/%s",
+        user_id, user_id, dir_name, package);
   }
-  std::string target = hasPackage ?
-      StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package) :
-      StringPrintf("/storage/emulated/%d/%s", user_id, dir_name);
+  std::string target = StringPrintf("/storage/emulated/%d/%s/%s", user_id, dir_name, package);
 
   if (access(source.c_str(), F_OK) != 0) {
     fail_fn(CREATE_ERROR("Error accessing %s: %s", source.c_str(), strerror(errno)));
@@ -1594,10 +1587,7 @@
   int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0;
 
   if (size == 0) {
-    // App data isolation is not enabled for this process, so we bind mount to whole obb/ dir.
-    BindMountStorageToLowerFs(user_id, "Android/obb", /* package */ nullptr, fail_fn);
-    BindMountStorageToLowerFs(user_id, "Android/data", /* package */ nullptr, fail_fn);
-    return;
+    fail_fn(CREATE_ERROR("Data package list cannot be empty"));
   }
 
   // Bind mount each package obb directory
diff --git a/core/proto/android/app/tvsettings_enums.proto b/core/proto/android/app/tvsettings_enums.proto
index 6804d3f..30d365c 100644
--- a/core/proto/android/app/tvsettings_enums.proto
+++ b/core/proto/android/app/tvsettings_enums.proto
@@ -298,6 +298,12 @@
     // TvSettings > Apps > See all apps > [An app entry] > Permissions
     APPS_ALL_APPS_APP_ENTRY_PERMISSIONS = 0x1611A000;
 
+    // TvSettings > Apps > See all apps > [An app entry] > Enable
+    APPS_ALL_APPS_APP_ENTRY_ENABLE = 0x1611B000;
+
+    // TvSettings > Apps > See all apps > [An app entry] > Open source licenses
+    APPS_ALL_APPS_APP_ENTRY_LICENSES = 0x1611C000;
+
     // TvSettings > Apps > See all apps > Show system apps
     APPS_ALL_APPS_SHOW_SYSTEM_APPS = 0x16120000;
 
diff --git a/core/proto/android/stats/dnsresolver/dns_resolver.proto b/core/proto/android/stats/dnsresolver/dns_resolver.proto
index 61b9b25..b17d12c 100644
--- a/core/proto/android/stats/dnsresolver/dns_resolver.proto
+++ b/core/proto/android/stats/dnsresolver/dns_resolver.proto
@@ -211,7 +211,7 @@
 // 1. bionic/libc/kernel/uapi/asm-generic/errno-base.h
 // 2. bionic/libc/kernel/uapi/asm-generic/errno.h
 enum LinuxErrno {
-    SYS_UNKNOWN = 0;
+    SYS_NO_ERROR = 0;
     SYS_EPERM = 1;              // Not super-user
     SYS_ENOENT = 2;             // No such file or directory
     SYS_ESRCH = 3;              // No such process
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 0ea9624..2c65cc4 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -35,7 +35,6 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -379,11 +378,7 @@
      */
     public void transferTo(@NonNull MediaRoute2Info route) {
         Objects.requireNonNull(route, "route must not be null");
-
-        List<RoutingController> controllers = getControllers();
-        RoutingController controller = controllers.get(controllers.size() - 1);
-
-        transfer(controller, route);
+        transfer(getCurrentController(), route);
     }
 
     /**
@@ -391,10 +386,7 @@
      * controls the media routing, this method is a no-op.
      */
     public void stop() {
-        List<RoutingController> controllers = getControllers();
-        RoutingController controller = controllers.get(controllers.size() - 1);
-
-        controller.release();
+        getCurrentController().release();
     }
 
     /**
@@ -417,12 +409,9 @@
             return;
         }
 
-        controller.release();
-
         final int requestId = mControllerCreationRequestCnt.getAndIncrement();
 
-        ControllerCreationRequest request =
-                new ControllerCreationRequest(requestId, controller, route);
+        ControllerCreationRequest request = new ControllerCreationRequest(requestId, route);
         mControllerCreationRequests.add(request);
 
         OnGetControllerHintsListener listener = mOnGetControllerHintsListener;
@@ -450,6 +439,12 @@
         }
     }
 
+    @NonNull
+    private RoutingController getCurrentController() {
+        List<RoutingController> controllers = getControllers();
+        return controllers.get(controllers.size() - 1);
+    }
+
     /**
      * Gets a {@link RoutingController} which can control the routes provided by system.
      * e.g. Phone speaker, wired headset, Bluetooth, etc.
@@ -474,13 +469,8 @@
     public List<RoutingController> getControllers() {
         List<RoutingController> result = new ArrayList<>();
         result.add(0, mSystemController);
-
-        Collection<RoutingController> controllers;
         synchronized (sRouterLock) {
-            controllers = mRoutingControllers.values();
-            if (controllers != null) {
-                result.addAll(controllers);
-            }
+            result.addAll(mRoutingControllers.values());
         }
         return result;
     }
@@ -608,19 +598,33 @@
             }
         }
 
-        if (sessionInfo != null) {
-            RoutingController newController;
-            if (sessionInfo.isSystemSession()) {
-                newController = getSystemController();
-            } else {
-                newController = new RoutingController(sessionInfo);
-                synchronized (sRouterLock) {
-                    mRoutingControllers.put(newController.getId(), newController);
-                }
+        if (sessionInfo == null) {
+            return;
+        }
+
+        RoutingController oldController = getCurrentController();
+        if (!oldController.releaseInternal(
+                /* shouldReleaseSession= */ true, /* shouldNotifyStop= */ false)) {
+            // Could not release the controller since it was just released by other thread.
+            oldController = getSystemController();
+        }
+
+        RoutingController newController;
+        if (sessionInfo.isSystemSession()) {
+            newController = getSystemController();
+            newController.setRoutingSessionInfo(sessionInfo);
+        } else {
+            newController = new RoutingController(sessionInfo);
+            synchronized (sRouterLock) {
+                mRoutingControllers.put(newController.getId(), newController);
             }
-            //TODO: Determine oldController properly when transfer is launched by Output Switcher.
-            notifyTransfer(matchingRequest != null ? matchingRequest.mController :
-                    getSystemController(), newController);
+        }
+
+        // Two controller can be same if stop() is called before the result of Cast -> Phone comes.
+        if (oldController != newController) {
+            notifyTransfer(oldController, newController);
+        } else if (matchingRequest != null) {
+            notifyTransferFailure(matchingRequest.mRoute);
         }
     }
 
@@ -687,7 +691,8 @@
             return;
         }
 
-        matchingController.releaseInternal(/* shouldReleaseSession= */ false);
+        matchingController.releaseInternal(
+                /* shouldReleaseSession= */ false, /* shouldNotifyStop= */ true);
     }
 
     void onGetControllerHintsForCreatingSessionOnHandler(long uniqueRequestId,
@@ -814,8 +819,9 @@
     public abstract static class TransferCallback {
         /**
          * Called when a media is transferred between two different routing controllers.
-         * This can happen by calling {@link #transferTo(MediaRoute2Info)} or
-         * {@link RoutingController#release()}.
+         * This can happen by calling {@link #transferTo(MediaRoute2Info)}.
+         * The {@code oldController} is released before this method is called, except for the
+         * {@link #getSystemController() system controller}.
          *
          * @param oldController the previous controller that controlled routing
          * @param newController the new controller to control routing
@@ -833,6 +839,9 @@
 
         /**
          * Called when a media routing stops. It can be stopped by a user or a provider.
+         * App should not continue playing media locally when this method is called.
+         * The {@code oldController} is released before this method is called, except for the
+         * {@link #getSystemController() system controller}.
          *
          * @param controller the controller that controlled the stopped media routing.
          */
@@ -1206,14 +1215,18 @@
          */
         // TODO: Add tests using {@link MediaRouter2Manager#getActiveSessions()}.
         public void release() {
-            releaseInternal(/* shouldReleaseSession= */ true);
+            releaseInternal(/* shouldReleaseSession= */ true, /* shouldNotifyStop= */ true);
         }
 
-        void releaseInternal(boolean shouldReleaseSession) {
+        /**
+         * Returns {@code true} when succeeded to release, {@code false} if the controller is
+         * already released.
+         */
+        boolean releaseInternal(boolean shouldReleaseSession, boolean shouldNotifyStop) {
             synchronized (mControllerLock) {
                 if (mIsReleased) {
                     Log.w(TAG, "releaseInternal() called on released controller. Ignoring.");
-                    return;
+                    return false;
                 }
                 mIsReleased = true;
             }
@@ -1232,12 +1245,11 @@
                 }
             }
 
-            if (Thread.currentThread() == mHandler.getLooper().getThread()) {
-                notifyStop(this);
-            } else {
+            if (shouldNotifyStop) {
                 mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
                         RoutingController.this));
             }
+            return true;
         }
 
         @Override
@@ -1294,13 +1306,14 @@
         }
 
         @Override
-        public void release() {
-            // Do nothing. SystemRoutingController will never be released
+        public boolean isReleased() {
+            // SystemRoutingController will never be released
+            return false;
         }
 
         @Override
-        public boolean isReleased() {
-            // SystemRoutingController will never be released
+        boolean releaseInternal(boolean shouldReleaseSession, boolean shouldNotifyStop) {
+            // Do nothing. SystemRoutingController will never be released
             return false;
         }
     }
@@ -1391,13 +1404,10 @@
 
     static final class ControllerCreationRequest {
         public final int mRequestId;
-        public final RoutingController mController;
         public final MediaRoute2Info mRoute;
 
-        ControllerCreationRequest(int requestId, @NonNull RoutingController controller,
-                @NonNull MediaRoute2Info route) {
+        ControllerCreationRequest(int requestId, @NonNull MediaRoute2Info route) {
             mRequestId = requestId;
-            mController = controller;
             mRoute = route;
         }
     }
diff --git a/media/java/android/media/RoutingSessionInfo.java b/media/java/android/media/RoutingSessionInfo.java
index 629cf154..608e29a 100644
--- a/media/java/android/media/RoutingSessionInfo.java
+++ b/media/java/android/media/RoutingSessionInfo.java
@@ -310,19 +310,19 @@
     public String toString() {
         StringBuilder result = new StringBuilder()
                 .append("RoutingSessionInfo{ ")
-                .append("sessionId=").append(mId)
-                .append(", name=").append(mName)
+                .append("sessionId=").append(getId())
+                .append(", name=").append(getName())
                 .append(", selectedRoutes={")
-                .append(String.join(",", mSelectedRoutes))
+                .append(String.join(",", getSelectedRoutes()))
                 .append("}")
                 .append(", selectableRoutes={")
-                .append(String.join(",", mSelectableRoutes))
+                .append(String.join(",", getSelectableRoutes()))
                 .append("}")
                 .append(", deselectableRoutes={")
-                .append(String.join(",", mDeselectableRoutes))
+                .append(String.join(",", getDeselectableRoutes()))
                 .append("}")
                 .append(", transferableRoutes={")
-                .append(String.join(",", mTransferableRoutes))
+                .append(String.join(",", getTransferableRoutes()))
                 .append("}")
                 .append(", volumeHandling=").append(getVolumeHandling())
                 .append(", volumeMax=").append(getVolumeMax())
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
index 71e74cf..d0916b5 100644
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
@@ -36,7 +36,7 @@
         android:background="@drawable/system_bar_background"
         android:animateLayoutChanges="true">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -47,7 +47,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/grid"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -59,7 +59,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -110,4 +110,4 @@
 
     </LinearLayout>
 
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
index f016dbf..de5a150 100644
--- a/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
@@ -36,7 +36,7 @@
         android:background="@drawable/system_bar_background"
         android:animateLayoutChanges="true">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -47,7 +47,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -59,4 +59,4 @@
             android:paddingBottom="30dp"
         />
     </LinearLayout>
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_navigation_bar.xml
index e2e9a33..1418bf8 100644
--- a/packages/CarSystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_bar.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
@@ -33,7 +33,7 @@
         android:paddingEnd="20dp"
         android:gravity="center">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             style="@style/NavigationBarButton"
             systemui:componentNames="com.android.car.carlauncher/.CarLauncher"
@@ -48,7 +48,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/maps_nav"
             style="@style/NavigationBarButton"
             systemui:categories="android.intent.category.APP_MAPS"
@@ -63,7 +63,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/music_nav"
             style="@style/NavigationBarButton"
             systemui:categories="android.intent.category.APP_MUSIC"
@@ -79,7 +79,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/phone_nav"
             style="@style/NavigationBarButton"
             systemui:icon="@drawable/car_ic_phone"
@@ -94,7 +94,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/grid_nav"
             style="@style/NavigationBarButton"
             systemui:componentNames="com.android.car.carlauncher/.AppGridActivity"
@@ -109,7 +109,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/notifications"
             style="@style/NavigationBarButton"
             systemui:icon="@drawable/car_ic_notification"
@@ -121,7 +121,7 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
-        <com.android.systemui.navigationbar.car.AssitantButton
+        <com.android.systemui.car.navigationbar.AssitantButton
             android:id="@+id/assist"
             style="@style/NavigationBarButton"
             systemui:icon="@drawable/ic_mic_white"
@@ -140,4 +140,4 @@
         android:visibility="gone"
     />
 
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
\ No newline at end of file
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
\ No newline at end of file
diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
index 1c5d37f..a040e80 100644
--- a/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_navigation_bar_unprovisioned.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
@@ -31,7 +31,7 @@
         android:paddingStart="@*android:dimen/car_padding_5"
         android:paddingEnd="@*android:dimen/car_padding_5">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             android:layout_width="@*android:dimen/car_touch_target_size"
             android:layout_height="match_parent"
@@ -42,5 +42,5 @@
             systemui:highlightWhenSelected="true"
         />
     </LinearLayout>
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
 
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
index 327610a..d386ce3 100644
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
@@ -39,7 +39,7 @@
         android:background="@drawable/system_bar_background"
         android:animateLayoutChanges="true">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -50,7 +50,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/grid"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -62,7 +62,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -113,4 +113,4 @@
 
     </LinearLayout>
 
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
index f016dbf..de5a150 100644
--- a/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
@@ -17,7 +17,7 @@
 */
 -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_height="match_parent"
@@ -36,7 +36,7 @@
         android:background="@drawable/system_bar_background"
         android:animateLayoutChanges="true">
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -47,7 +47,7 @@
             android:paddingBottom="30dp"
         />
 
-        <com.android.systemui.navigationbar.car.CarNavigationButton
+        <com.android.systemui.car.navigationbar.CarNavigationButton
             android:id="@+id/hvac"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
@@ -59,4 +59,4 @@
             android:paddingBottom="30dp"
         />
     </LinearLayout>
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
index a7347f2..3389a7a 100644
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
+++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/car_top_bar"
@@ -36,7 +36,7 @@
             android:layout_alignParentStart="true"
         >
 
-            <com.android.systemui.navigationbar.car.CarNavigationButton
+            <com.android.systemui.car.navigationbar.CarNavigationButton
                 android:id="@+id/hvacleft"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -71,7 +71,7 @@
             android:layout_height="match_parent"
             android:layout_centerInParent="true"
         >
-            <com.android.systemui.navigationbar.car.CarNavigationButton
+            <com.android.systemui.car.navigationbar.CarNavigationButton
                 android:id="@+id/qs"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -118,7 +118,7 @@
             android:layout_alignParentEnd="true"
         >
 
-            <com.android.systemui.navigationbar.car.CarNavigationButton
+            <com.android.systemui.car.navigationbar.CarNavigationButton
                 android:id="@+id/hvacright"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -148,4 +148,4 @@
         </FrameLayout>
     </RelativeLayout>
 
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
index aa0a8c5..9634950 100644
--- a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
+++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml
@@ -15,7 +15,7 @@
   ~ limitations under the License
   -->
 
-<com.android.systemui.navigationbar.car.CarNavigationBarView
+<com.android.systemui.car.navigationbar.CarNavigationBarView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/car_top_bar"
@@ -36,7 +36,7 @@
         android:layout_alignParentStart="true"
         >
 
-      <com.android.systemui.navigationbar.car.CarNavigationButton
+      <com.android.systemui.car.navigationbar.CarNavigationButton
           android:id="@+id/hvacleft"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
@@ -70,7 +70,7 @@
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_centerInParent="true">
-      <com.android.systemui.navigationbar.car.CarNavigationButton
+      <com.android.systemui.car.navigationbar.CarNavigationButton
           android:id="@+id/qs"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
@@ -114,7 +114,7 @@
         android:layout_alignParentEnd="true"
         >
 
-      <com.android.systemui.navigationbar.car.CarNavigationButton
+      <com.android.systemui.car.navigationbar.CarNavigationButton
           android:id="@+id/hvacright"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
@@ -144,4 +144,4 @@
     </FrameLayout>
   </RelativeLayout>
 
-</com.android.systemui.navigationbar.car.CarNavigationBarView>
+</com.android.systemui.car.navigationbar.CarNavigationBarView>
diff --git a/packages/CarSystemUI/res/values/config.xml b/packages/CarSystemUI/res/values/config.xml
index 52d13c3..eb1d9d0 100644
--- a/packages/CarSystemUI/res/values/config.xml
+++ b/packages/CarSystemUI/res/values/config.xml
@@ -106,10 +106,10 @@
         <item>com.android.systemui.SizeCompatModeActivityController</item>
 <!--        <item>com.android.systemui.statusbar.notification.InstantAppNotifier</item>-->
         <item>com.android.systemui.theme.ThemeOverlayController</item>
-        <item>com.android.systemui.navigationbar.car.CarNavigationBar</item>
         <item>com.android.systemui.toast.ToastUI</item>
+        <item>com.android.systemui.car.navigationbar.CarNavigationBar</item>
         <item>com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier</item>
-        <item>com.android.systemui.window.SystemUIOverlayWindowManager</item>
+        <item>com.android.systemui.car.window.SystemUIOverlayWindowManager</item>
         <item>com.android.systemui.car.volume.VolumeUI</item>
     </string-array>
 </resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 91e222c..58e4b9a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -18,21 +18,23 @@
 
 import com.android.systemui.biometrics.AuthController;
 import com.android.systemui.bubbles.dagger.BubbleModule;
+import com.android.systemui.car.navigationbar.CarNavigationBar;
 import com.android.systemui.car.notification.CarNotificationModule;
+import com.android.systemui.car.statusbar.CarStatusBar;
+import com.android.systemui.car.statusbar.CarStatusBarModule;
 import com.android.systemui.car.voicerecognition.ConnectedDeviceVoiceRecognitionNotifier;
 import com.android.systemui.car.volume.VolumeUI;
+import com.android.systemui.car.window.OverlayWindowModule;
+import com.android.systemui.car.window.SystemUIOverlayWindowManager;
 import com.android.systemui.globalactions.GlobalActionsComponent;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.dagger.KeyguardModule;
-import com.android.systemui.navigationbar.car.CarNavigationBar;
 import com.android.systemui.pip.PipUI;
 import com.android.systemui.power.PowerUI;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsModule;
 import com.android.systemui.shortcut.ShortcutKeyDispatcher;
 import com.android.systemui.stackdivider.Divider;
-import com.android.systemui.statusbar.car.CarStatusBar;
-import com.android.systemui.statusbar.car.CarStatusBarModule;
 import com.android.systemui.statusbar.notification.InstantAppNotifier;
 import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
 import com.android.systemui.statusbar.phone.StatusBar;
@@ -40,8 +42,6 @@
 import com.android.systemui.theme.ThemeOverlayController;
 import com.android.systemui.toast.ToastUI;
 import com.android.systemui.util.leak.GarbageMonitor;
-import com.android.systemui.window.OverlayWindowModule;
-import com.android.systemui.window.SystemUIOverlayWindowManager;
 
 import dagger.Binds;
 import dagger.Module;
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 13a5556..f066bf5 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -25,6 +25,8 @@
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
 import com.android.systemui.car.keyguard.CarKeyguardViewController;
+import com.android.systemui.car.statusbar.CarStatusBar;
+import com.android.systemui.car.statusbar.CarStatusBarKeyguardViewManager;
 import com.android.systemui.car.volume.CarVolumeDialogComponent;
 import com.android.systemui.dagger.SystemUIRootComponent;
 import com.android.systemui.dock.DockManager;
@@ -40,8 +42,6 @@
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
-import com.android.systemui.statusbar.car.CarStatusBar;
-import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -87,9 +87,6 @@
                 groupManager, configurationController);
     }
 
-    @Binds
-    abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
-
     @Singleton
     @Provides
     @Named(LEAK_REPORT_EMAIL_NAME)
@@ -97,6 +94,16 @@
         return "buganizer-system+181579@google.com";
     }
 
+    @Provides
+    @Singleton
+    static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
+            CommandQueue commandQueue) {
+        return new Recents(context, recentsImplementation, commandQueue);
+    }
+
+    @Binds
+    abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
+
     @Binds
     abstract EnhancedEstimates bindEnhancedEstimates(EnhancedEstimatesImpl enhancedEstimates);
 
@@ -123,13 +130,6 @@
     @Binds
     abstract ShadeController provideShadeController(ShadeControllerImpl shadeController);
 
-    @Provides
-    @Singleton
-    static Recents provideRecents(Context context, RecentsImplementation recentsImplementation,
-            CommandQueue commandQueue) {
-        return new Recents(context, recentsImplementation, commandQueue);
-    }
-
     @Binds
     abstract SystemUIRootComponent bindSystemUIRootComponent(
             CarSystemUIRootComponent systemUIRootComponent);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.java
index 4e0fd4a..9b5e2712 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/CarBatteryController.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.systemui.statusbar.car;
+package com.android.systemui.car.bluetooth;
 
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
@@ -116,10 +116,12 @@
         mChangeCallbacks.remove(cb);
     }
 
+    /** Sets {@link BatteryViewHandler}. */
     public void addBatteryViewHandler(BatteryViewHandler batteryViewHandler) {
         mBatteryViewHandler = batteryViewHandler;
     }
 
+    /** Starts listening for bluetooth broadcast messages. */
     public void startListening() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
@@ -127,6 +129,7 @@
         mContext.registerReceiver(this, filter);
     }
 
+    /** Stops listening for bluetooth broadcast messages. */
     public void stopListening() {
         mContext.unregisterReceiver(this);
     }
@@ -279,8 +282,10 @@
      * in the {@link CarBatteryController}.
      */
     public interface BatteryViewHandler {
+        /** Hides the battery view. */
         void hideBatteryView();
 
+        /** Shows the battery view. */
         void showBatteryView();
     }
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
index 3288927..4642868 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/bluetooth/ConnectedDeviceSignalController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 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.systemui.statusbar.car;
+package com.android.systemui.car.bluetooth;
 
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
 
@@ -125,6 +125,7 @@
                 BluetoothProfile.HEADSET_CLIENT);
     }
 
+    /** Starts listening for bluetooth broadcast messages. */
     public void startListening() {
         IntentFilter filter = new IntentFilter();
         filter.addAction(BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
@@ -134,6 +135,7 @@
         mController.addCallback(this);
     }
 
+    /** Stops listening for bluetooth broadcast messages. */
     public void stopListening() {
         mContext.unregisterReceiver(this);
         mController.removeCallback(this);
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
index 4fde309..b5f648b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
@@ -35,9 +35,11 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
+import com.android.systemui.car.window.OverlayViewController;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
@@ -45,8 +47,6 @@
 import com.android.systemui.statusbar.phone.NotificationPanelViewController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.window.OverlayViewController;
-import com.android.systemui.window.OverlayViewGlobalStateController;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java
index db0f5d8..5a35c48 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/keyguard/CarKeyguardViewMediator.java
@@ -17,7 +17,7 @@
 package com.android.systemui.car.keyguard;
 
 import com.android.systemui.car.userswitcher.FullScreenUserSwitcherViewController;
-import com.android.systemui.window.OverlayViewMediator;
+import com.android.systemui.car.window.OverlayViewMediator;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
index 98cc00e..69ec78e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/AssitantButton.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE;
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
index c36aaa0..eedcfa5 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.app.ActivityManager;
 import android.content.ComponentName;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
similarity index 94%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
index 9da4121..1361798 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/ButtonSelectionStateListener.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/ButtonSelectionStateListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.app.ActivityTaskManager;
 import android.util.Log;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
similarity index 99%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
index 4e315c6..2b5cab7 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
index 8f3ae1a..55c1153 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarController.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.content.Context;
 import android.view.View;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
index 5b99f53..46a720b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationBarView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.content.Context;
 import android.util.AttributeSet;
@@ -24,7 +24,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.navigationbar.car.CarNavigationBarController.NotificationsShadeController;
+import com.android.systemui.car.navigationbar.CarNavigationBarController.NotificationsShadeController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
index b4d4785..5f4ac2d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/CarNavigationButton.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.app.ActivityOptions;
 import android.content.Context;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
rename to packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
index e47c5d1..3b7b48a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/navigationbar/NavigationBarViewFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import android.content.Context;
 import android.util.ArrayMap;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
index d8a894c..a17a0e9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewController.java
@@ -45,13 +45,13 @@
 import com.android.systemui.R;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.car.window.OverlayPanelViewController;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
 import com.android.systemui.dagger.qualifiers.Main;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.window.OverlayPanelViewController;
-import com.android.systemui.window.OverlayViewGlobalStateController;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java
index 9d71797..24a84d9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/NotificationPanelViewMediator.java
@@ -20,10 +20,9 @@
 import android.content.res.Configuration;
 
 import com.android.systemui.car.CarDeviceProvisionedController;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
-import com.android.systemui.statusbar.car.PowerManagerHelper;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
+import com.android.systemui.car.window.OverlayViewMediator;
 import com.android.systemui.statusbar.policy.ConfigurationController;
-import com.android.systemui.window.OverlayViewMediator;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java b/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
similarity index 95%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java
rename to packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
index 615a7bae..92a11d8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/notification/PowerManagerHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.statusbar.car;
+package com.android.systemui.car.notification;
 
 import android.annotation.NonNull;
 import android.car.Car;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
index ec1dabc..b6eb015 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 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.systemui.statusbar.car;
+package com.android.systemui.car.statusbar;
 
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 
@@ -41,6 +41,8 @@
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.car.CarDeviceProvisionedController;
 import com.android.systemui.car.CarDeviceProvisionedListener;
+import com.android.systemui.car.bluetooth.CarBatteryController;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
 import com.android.systemui.classifier.FalsingLog;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -49,7 +51,6 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java
index e1c051f..96a998a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarKeyguardViewManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarKeyguardViewManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 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.systemui.statusbar.car;
+package com.android.systemui.car.statusbar;
 
 import android.content.Context;
 import android.view.View;
@@ -23,8 +23,8 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.R;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
 import com.android.systemui.dock.DockManager;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.SysuiStatusBarStateController;
 import com.android.systemui.statusbar.phone.NavigationModeController;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
rename to packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java
index f72ab25..dc2eb04 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBarModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/statusbar/CarStatusBarModule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.statusbar.car;
+package com.android.systemui.car.statusbar;
 
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 
@@ -31,13 +31,13 @@
 import com.android.systemui.broadcast.BroadcastDispatcher;
 import com.android.systemui.bubbles.BubbleController;
 import com.android.systemui.car.CarDeviceProvisionedController;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dagger.qualifiers.UiBackground;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.plugins.DarkIconDispatcher;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginDependencyProvider;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java
index 45ceb6d..10b2b97 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullScreenUserSwitcherViewController.java
@@ -25,9 +25,9 @@
 import androidx.recyclerview.widget.GridLayoutManager;
 
 import com.android.systemui.R;
+import com.android.systemui.car.window.OverlayViewController;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
 import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.window.OverlayViewController;
-import com.android.systemui.window.OverlayViewGlobalStateController;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
index 149531f..346c38c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/userswitcher/FullscreenUserSwitcherViewMediator.java
@@ -17,9 +17,9 @@
 package com.android.systemui.car.userswitcher;
 
 import com.android.systemui.car.keyguard.CarKeyguardViewController;
+import com.android.systemui.car.window.OverlayViewMediator;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.window.OverlayViewMediator;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
index a22d1ab..98d24b1 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/volume/CarVolumeDialogComponent.java
@@ -21,7 +21,6 @@
 import com.android.systemui.car.CarServiceProvider;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.VolumeDialog;
-import com.android.systemui.volume.Events;
 import com.android.systemui.volume.VolumeDialogComponent;
 import com.android.systemui.volume.VolumeDialogControllerImpl;
 
@@ -48,7 +47,6 @@
     @Override
     protected VolumeDialog createDefault() {
         mCarVolumeDialog = new CarVolumeDialogImpl(mContext);
-        mCarVolumeDialog.show(Events.SHOW_REASON_VOLUME_CHANGED);
         return mCarVolumeDialog;
     }
 }
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
similarity index 99%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
index 58022f1..90892d5 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayPanelViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayPanelViewController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
index 15ef0be..87f2020 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import android.view.View;
 import android.view.ViewGroup;
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
index 5fe03f1..290505f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewGlobalStateController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewGlobalStateController.java
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import android.util.Log;
 
 import androidx.annotation.VisibleForTesting;
 
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
 
 import java.util.HashSet;
 import java.util.Set;
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
similarity index 96%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
index 7c34fb4..ac574ed 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayViewMediator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayViewMediator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 /**
  * Controls when to show and hide {@link OverlayViewController}(s).
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
similarity index 97%
rename from packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
index 6b4f3e3..c46b287 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/OverlayWindowModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/OverlayWindowModule.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import com.android.systemui.car.keyguard.CarKeyguardViewMediator;
 import com.android.systemui.car.notification.NotificationPanelViewMediator;
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
similarity index 99%
rename from packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
index 5df5d6e..bcd96f6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowController.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 
diff --git a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
similarity index 98%
rename from packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java
rename to packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
index af0f17d..3f88422 100644
--- a/packages/CarSystemUI/src/com/android/systemui/window/SystemUIOverlayWindowManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/window/SystemUIOverlayWindowManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import android.content.Context;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
index d4cf6cc..d40b1af 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
@@ -38,15 +38,15 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.car.CarServiceProvider;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
+import com.android.systemui.car.window.OverlayViewGlobalStateController;
+import com.android.systemui.car.window.SystemUIOverlayWindowController;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.statusbar.phone.BiometricUnlockController;
 import com.android.systemui.statusbar.phone.KeyguardBouncer;
 import com.android.systemui.statusbar.phone.KeyguardBypassController;
 import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.window.OverlayViewGlobalStateController;
-import com.android.systemui.window.SystemUIOverlayWindowController;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
similarity index 97%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
index f94dd82..893057e 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/ButtonSelectionStateControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/ButtonSelectionStateControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
similarity index 99%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
index 28c69c7..911f624 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarControllerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
similarity index 99%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
index f789d38..6620e9d 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.ITYPE_STATUS_BAR;
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
index 9e2131c..19e394f 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationBarViewTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationBarViewTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
index 96d567d..11f2fa4 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/navigationbar/car/CarNavigationButtonTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/navigationbar/CarNavigationButtonTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 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.systemui.navigationbar.car;
+package com.android.systemui.car.navigationbar;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
similarity index 99%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
index 04f2d06..70f1d25 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayPanelViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayPanelViewControllerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
index 3313261..c24a3b5 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewControllerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import static com.google.common.truth.Truth.assertThat;
 
diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
similarity index 98%
rename from packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java
rename to packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
index a96b906..25dd4f5 100644
--- a/packages/CarSystemUI/tests/src/com/android/systemui/window/OverlayViewGlobalStateControllerTest.java
+++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/window/OverlayViewGlobalStateControllerTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.window;
+package com.android.systemui.car.window;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -30,7 +30,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.SysuiTestCase;
-import com.android.systemui.navigationbar.car.CarNavigationBarController;
+import com.android.systemui.car.navigationbar.CarNavigationBarController;
 
 import org.junit.Before;
 import org.junit.Test;
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index 7d9f8e3..7bdb2a8 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index dcccada..8efd3b2 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index 7d9f8e3..7bdb2a8 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 3501fa4..eed29d1 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 8b6b5f6..2e217a5 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -250,4 +250,7 @@
     <color name="control_enabled_thermo_heat_background">@color/GM2_red_200</color>
     <color name="control_enabled_thermo_cool_background">@color/GM2_blue_200</color>
     <color name="control_enabled_default_background">@color/GM2_blue_200</color>
+
+    <!-- Docked misalignment message -->
+    <color name="misalignment_text_color">#F28B82</color>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 11b54ad..43b4723 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -311,7 +311,7 @@
                     mTextView.switchIndication(mTransientIndication);
                 } else if (!TextUtils.isEmpty(mAlignmentIndication)) {
                     mTextView.switchIndication(mAlignmentIndication);
-                    mTextView.setTextColor(Utils.getColorError(mContext));
+                    mTextView.setTextColor(mContext.getColor(R.color.misalignment_text_color));
                 } else if (mPowerPluggedIn) {
                     String indication = computePowerIndication();
                     if (animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index b9dd974..92b597b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -331,19 +331,6 @@
                 .setDuration(ACTIVATE_ANIMATION_LENGTH);
     }
 
-    @Override
-    public boolean performClick() {
-        if (!mNeedsDimming || (mAccessibilityManager != null
-                && mAccessibilityManager.isTouchExplorationEnabled())) {
-            return super.performClick();
-        }
-        return false;
-    }
-
-    boolean superPerformClick() {
-        return super.performClick();
-    }
-
     /**
      * Cancels the hotspot and makes the notification inactive.
      */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
index 2f0e433..dd30c89 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewController.java
@@ -72,7 +72,7 @@
             } else {
                 mView.makeInactive(true /* animate */);
             }
-        }, mView::superPerformClick, mView::handleSlideBack,
+        }, mView::performClick, mView::handleSlideBack,
                 mFalsingManager::onNotificationDoubleTap);
         mView.setOnTouchListener(mTouchHandler);
         mView.setTouchHandler(mTouchHandler);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index fb40177..23099d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -193,7 +193,7 @@
         assertThat(mTextView.getText()).isEqualTo(
                 mContext.getResources().getString(R.string.dock_alignment_slow_charging));
         assertThat(mTextView.getCurrentTextColor()).isEqualTo(
-                Utils.getColorError(mContext).getDefaultColor());
+                mContext.getColor(R.color.misalignment_text_color));
     }
 
     @Test
@@ -211,7 +211,7 @@
         assertThat(mTextView.getText()).isEqualTo(
                 mContext.getResources().getString(R.string.dock_alignment_not_charging));
         assertThat(mTextView.getCurrentTextColor()).isEqualTo(
-                Utils.getColorError(mContext).getDefaultColor());
+                mContext.getColor(R.color.misalignment_text_color));
     }
 
     @Test
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 05cf68e..4e16c49 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1007,6 +1007,11 @@
     }
 
     @VisibleForTesting
+    boolean isTetheringActive() {
+        return mActiveTetheringRequests.size() > 0;
+    }
+
+    @VisibleForTesting
     protected static class UserRestrictionActionListener {
         private final UserManager mUserManager;
         private final Tethering mWrapper;
@@ -1043,13 +1048,14 @@
                 return;
             }
 
-            // Restricted notification is shown when tethering function is disallowed on
-            // user's device.
-            mNotificationUpdater.notifyTetheringDisabledByRestriction();
+            if (mWrapper.isTetheringActive()) {
+                // Restricted notification is shown when tethering function is disallowed on
+                // user's device.
+                mNotificationUpdater.notifyTetheringDisabledByRestriction();
 
-            // Untether from all downstreams since tethering is disallowed.
-            mWrapper.untetherAll();
-
+                // Untether from all downstreams since tethering is disallowed.
+                mWrapper.untetherAll();
+            }
             // TODO(b/148139325): send tetheringSupported on restriction change
         }
     }
diff --git a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
index 7fd6b61..d03deda 100644
--- a/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
+++ b/packages/Tethering/src/com/android/networkstack/tethering/TetheringNotificationUpdater.java
@@ -267,7 +267,7 @@
                 null /* options */);
 
         showNotification(R.drawable.stat_sys_tether_general, title, message,
-                RESTRICTED_NOTIFICATION_ID, pi, new Action[0]);
+                RESTRICTED_NOTIFICATION_ID, false /* ongoing */, pi, new Action[0]);
     }
 
     private void notifyTetheringNoUpstream() {
@@ -288,7 +288,7 @@
         final Action action = new Action.Builder(NO_ICON_ID, disableButton, pi).build();
 
         showNotification(R.drawable.stat_sys_tether_general, title, message,
-                NO_UPSTREAM_NOTIFICATION_ID, null /* pendingIntent */, action);
+                NO_UPSTREAM_NOTIFICATION_ID, true /* ongoing */, null /* pendingIntent */, action);
     }
 
     private boolean setupRoamingNotification() {
@@ -310,7 +310,7 @@
                 null /* options */);
 
         showNotification(R.drawable.stat_sys_tether_general, title, message,
-                ROAMING_NOTIFICATION_ID, pi, new Action[0]);
+                ROAMING_NOTIFICATION_ID, true /* ongoing */, pi, new Action[0]);
         return NOTIFY_DONE;
     }
 
@@ -327,14 +327,14 @@
     }
 
     private void showNotification(@DrawableRes final int iconId, @NonNull final String title,
-            @NonNull final String message, @NotificationId final int id, @Nullable PendingIntent pi,
-            @NonNull final Action... actions) {
+            @NonNull final String message, @NotificationId final int id, final boolean ongoing,
+            @Nullable PendingIntent pi, @NonNull final Action... actions) {
         final Notification notification =
                 new Notification.Builder(mContext, mChannel.getId())
                         .setSmallIcon(iconId)
                         .setContentTitle(title)
                         .setContentText(message)
-                        .setOngoing(true)
+                        .setOngoing(ongoing)
                         .setColor(mContext.getColor(
                                 android.R.color.system_notification_accent_color))
                         .setVisibility(Notification.VISIBILITY_PUBLIC)
diff --git a/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt b/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
index a20a0df..55c59dd 100644
--- a/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
+++ b/packages/Tethering/tests/unit/common/android/net/TetheredClientTest.kt
@@ -33,7 +33,9 @@
 private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78))
 private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L)
 private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L)
-private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, "test_hostname")
+private val TEST_HOSTNAME = "test_hostname"
+private val TEST_OTHER_HOSTNAME = "test_other_hostname"
+private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, TEST_HOSTNAME)
 private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null)
 
 private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress(
@@ -49,6 +51,7 @@
 class TetheredClientTest {
     @Test
     fun testParceling() {
+        assertParcelSane(TEST_ADDRINFO1, fieldCount = 2)
         assertParcelSane(makeTestClient(), fieldCount = 3)
     }
 
@@ -65,7 +68,7 @@
         // Different hostname
         assertNotEquals(makeTestClient(), TetheredClient(
                 TEST_MACADDR,
-                listOf(AddressInfo(TEST_ADDR1, "test_other_hostname"), TEST_ADDRINFO2),
+                listOf(AddressInfo(TEST_ADDR1, TEST_OTHER_HOSTNAME), TEST_ADDRINFO2),
                 TETHERING_BLUETOOTH))
 
         // Null hostname
@@ -97,6 +100,21 @@
                 TETHERING_USB), client1.addAddresses(client2))
     }
 
+    @Test
+    fun testGetters() {
+        assertEquals(TEST_MACADDR, makeTestClient().macAddress)
+        assertEquals(listOf(TEST_ADDRINFO1, TEST_ADDRINFO2), makeTestClient().addresses)
+        assertEquals(TETHERING_BLUETOOTH, makeTestClient().tetheringType)
+    }
+
+    @Test
+    fun testAddressInfo_Getters() {
+        assertEquals(TEST_ADDR1, TEST_ADDRINFO1.address)
+        assertEquals(TEST_ADDR2, TEST_ADDRINFO2.address)
+        assertEquals(TEST_HOSTNAME, TEST_ADDRINFO1.hostname)
+        assertEquals(null, TEST_ADDRINFO2.hostname)
+    }
+
     private fun makeTestClient() = TetheredClient(
             TEST_MACADDR,
             listOf(TEST_ADDRINFO1, TEST_ADDRINFO2),
diff --git a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index cf05483..0c86eeb 100644
--- a/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -1079,12 +1079,12 @@
     }
 
     private void runUserRestrictionsChange(
-            boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList,
+            boolean currentDisallow, boolean nextDisallow, boolean isTetheringActive,
             int expectedInteractionsWithShowNotification) throws  Exception {
         final Bundle newRestrictions = new Bundle();
         newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow);
         final Tethering mockTethering = mock(Tethering.class);
-        when(mockTethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList);
+        when(mockTethering.isTetheringActive()).thenReturn(isTetheringActive);
         when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions);
 
         final Tethering.UserRestrictionActionListener ural =
@@ -1100,63 +1100,63 @@
     }
 
     @Test
-    public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] emptyActiveIfacesList = new String[]{};
+    public void testDisallowTetheringWhenTetheringIsNotActive() throws Exception {
+        final boolean isTetheringActive = false;
+        final boolean currDisallow = false;
+        final boolean nextDisallow = true;
+        final int expectedInteractionsWithShowNotification = 0;
+
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
+                expectedInteractionsWithShowNotification);
+    }
+
+    @Test
+    public void testDisallowTetheringWhenTetheringIsActive() throws Exception {
+        final boolean isTetheringActive = true;
         final boolean currDisallow = false;
         final boolean nextDisallow = true;
         final int expectedInteractionsWithShowNotification = 1;
 
-        runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList,
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
                 expectedInteractionsWithShowNotification);
     }
 
     @Test
-    public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
-        final boolean currDisallow = false;
-        final boolean nextDisallow = true;
-        final int expectedInteractionsWithShowNotification = 1;
-
-        runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
-                expectedInteractionsWithShowNotification);
-    }
-
-    @Test
-    public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{};
+    public void testAllowTetheringWhenTetheringIsNotActive() throws Exception {
+        final boolean isTetheringActive = false;
         final boolean currDisallow = true;
         final boolean nextDisallow = false;
         final int expectedInteractionsWithShowNotification = 0;
 
-        runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
                 expectedInteractionsWithShowNotification);
     }
 
     @Test
-    public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
+    public void testAllowTetheringWhenTetheringIsActive() throws Exception {
+        final boolean isTetheringActive = true;
         final boolean currDisallow = true;
         final boolean nextDisallow = false;
         final int expectedInteractionsWithShowNotification = 0;
 
-        runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
                 expectedInteractionsWithShowNotification);
     }
 
     @Test
     public void testDisallowTetheringUnchanged() throws Exception {
-        final String[] nonEmptyActiveIfacesList = new String[]{TEST_WLAN_IFNAME};
+        final boolean isTetheringActive = true;
         final int expectedInteractionsWithShowNotification = 0;
         boolean currDisallow = true;
         boolean nextDisallow = true;
 
-        runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
                 expectedInteractionsWithShowNotification);
 
         currDisallow = false;
         nextDisallow = false;
 
-        runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
+        runUserRestrictionsChange(currDisallow, nextDisallow, isTetheringActive,
                 expectedInteractionsWithShowNotification);
     }
 
diff --git a/services/Android.bp b/services/Android.bp
index 730b9a5..6d637be 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -112,7 +112,6 @@
     name: "services-stubs.sources",
     srcs: [":services-all-sources"],
     installable: false,
-    api_tag_name: "SYSTEM_SERVER",
     args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" +
         " --hide-annotation android.annotation.Hide" +
         " --hide InternalClasses" + // com.android.* classes are okay in this interface
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index e28464a..c9ee472 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2181,6 +2181,17 @@
         return result;
     }
 
+    private boolean needsStorageDataIsolation(StorageManagerInternal storageManagerInternal,
+            ProcessRecord app) {
+        return mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
+                && !storageManagerInternal.isExternalStorageService(app.uid)
+                // Special mounting mode doesn't need to have data isolation as they won't
+                // access /mnt/user anyway.
+                && app.mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
+                && app.mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH
+                && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER;
+    }
+
     private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
             ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
             int mountExternal, String seInfo, String requiredAbi, String instructionSet,
@@ -2237,8 +2248,7 @@
             int userId = UserHandle.getUserId(uid);
             StorageManagerInternal storageManagerInternal = LocalServices.getService(
                     StorageManagerInternal.class);
-            if (mVoldAppDataIsolationEnabled && UserHandle.isApp(app.uid)
-                    && !storageManagerInternal.isExternalStorageService(uid)) {
+            if (needsStorageDataIsolation(storageManagerInternal, app)) {
                 bindMountAppStorageDirs = true;
                 if (pkgDataInfoMap == null ||
                         !storageManagerInternal.prepareStorageDirs(userId, pkgDataInfoMap.keySet(),
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 546025a..85c4190 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1877,8 +1877,10 @@
                     builder.append("; this requires ");
                     builder.append(INTERACT_ACROSS_USERS_FULL);
                     if (allowMode != ALLOW_FULL_ONLY) {
-                        builder.append(" or ");
-                        builder.append(INTERACT_ACROSS_USERS);
+                        if (allowMode == ALLOW_NON_FULL || isSameProfileGroup) {
+                            builder.append(" or ");
+                            builder.append(INTERACT_ACROSS_USERS);
+                        }
                         if (isSameProfileGroup
                                 && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) {
                             builder.append(" or ");
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 44e973e..393e8db 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -117,6 +117,8 @@
     private static final String ALLOWED_INSTALLER_DELIMITER = ",";
     private static final String INSTALLER_PACKAGE_CERT_DELIMITER = "\\|";
 
+    public static final boolean DEBUG_INTEGRITY_COMPONENT = false;
+
     private static final Set<String> PACKAGE_INSTALLER =
             new HashSet<>(
                     Arrays.asList(
@@ -262,14 +264,18 @@
         int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1);
 
         try {
-            Slog.i(TAG, "Received integrity verification intent " + intent.toString());
-            Slog.i(TAG, "Extras " + intent.getExtras());
+            if (DEBUG_INTEGRITY_COMPONENT) {
+                Slog.d(TAG, "Received integrity verification intent " + intent.toString());
+                Slog.d(TAG, "Extras " + intent.getExtras());
+            }
 
             String installerPackageName = getInstallerPackageName(intent);
 
             // Skip integrity verification if the verifier is doing the install.
             if (!integrityCheckIncludesRuleProvider() && isRuleProvider(installerPackageName)) {
-                Slog.i(TAG, "Verifier doing the install. Skipping integrity check.");
+                if (DEBUG_INTEGRITY_COMPONENT) {
+                    Slog.i(TAG, "Verifier doing the install. Skipping integrity check.");
+                }
                 mPackageManagerInternal.setIntegrityVerificationResult(
                         verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
                 return;
@@ -303,19 +309,23 @@
 
             AppInstallMetadata appInstallMetadata = builder.build();
 
-            Slog.i(
-                    TAG,
-                    "To be verified: "
-                            + appInstallMetadata
-                            + " installers "
-                            + getAllowedInstallers(packageInfo));
+            if (DEBUG_INTEGRITY_COMPONENT) {
+                Slog.i(
+                        TAG,
+                        "To be verified: "
+                                + appInstallMetadata
+                                + " installers "
+                                + getAllowedInstallers(packageInfo));
+            }
             IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata);
-            Slog.i(
-                    TAG,
-                    "Integrity check result: "
-                            + result.getEffect()
-                            + " due to "
-                            + result.getMatchedRules());
+            if (DEBUG_INTEGRITY_COMPONENT) {
+                Slog.i(
+                        TAG,
+                        "Integrity check result: "
+                                + result.getEffect()
+                                + " due to "
+                                + result.getMatchedRules());
+            }
 
             FrameworkStatsLog.write(
                     FrameworkStatsLog.INTEGRITY_CHECK_RESULT_REPORTED,
@@ -424,7 +434,7 @@
                             .getPackageInfo(installer, PackageManager.GET_SIGNING_CERTIFICATES);
             return getCertificateFingerprint(installerInfo);
         } catch (PackageManager.NameNotFoundException e) {
-            Slog.i(TAG, "Installer package " + installer + " not found.");
+            Slog.w(TAG, "Installer package " + installer + " not found.");
             return Collections.emptyList();
         }
     }
@@ -653,28 +663,39 @@
     private String getCallingRulePusherPackageName(int callingUid) {
         // Obtain the system apps that are whitelisted in config_integrityRuleProviderPackages.
         List<String> allowedRuleProviders = getAllowedRuleProviderSystemApps();
-        Slog.i(TAG, String.format(
-                "Rule provider system app list contains: %s", allowedRuleProviders));
+        if (DEBUG_INTEGRITY_COMPONENT) {
+            Slog.i(TAG, String.format(
+                    "Rule provider system app list contains: %s", allowedRuleProviders));
+        }
 
         // Identify the package names in the caller list.
         List<String> callingPackageNames = getPackageListForUid(callingUid);
-        Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames));
+        if (DEBUG_INTEGRITY_COMPONENT) {
+            Slog.i(TAG, String.format("Calling packages are: ", callingPackageNames));
+        }
 
         // Find the intersection between the allowed and calling packages. Ideally, we will have
         // at most one package name here. But if we have more, it is fine.
-        List<String> allowedCallingPackages =
-                callingPackageNames
-                        .stream()
-                        .filter(packageName -> allowedRuleProviders.contains(packageName))
-                        .collect(Collectors.toList());
-        Slog.i(TAG, String.format("Calling rule pusher packages are: ", allowedCallingPackages));
-
+        List<String> allowedCallingPackages = new ArrayList<>();
+        for (String packageName : callingPackageNames) {
+            if (allowedRuleProviders.contains(packageName)) {
+                allowedCallingPackages.add(packageName);
+            }
+        }
+        if (DEBUG_INTEGRITY_COMPONENT) {
+            Slog.i(TAG,
+                    String.format("Calling rule pusher packages are: ", allowedCallingPackages));
+        }
         return allowedCallingPackages.isEmpty() ? null : allowedCallingPackages.get(0);
     }
 
     private boolean isRuleProvider(String installerPackageName) {
-        return getAllowedRuleProviderSystemApps().stream()
-                .anyMatch(ruleProvider -> ruleProvider.equals(installerPackageName));
+        for (String ruleProvider : getAllowedRuleProviderSystemApps()) {
+            if (ruleProvider.matches(installerPackageName)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     private List<String> getAllowedRuleProviderSystemApps() {
@@ -682,13 +703,18 @@
                 Arrays.asList(
                         mContext.getResources()
                                 .getStringArray(R.array.config_integrityRuleProviderPackages));
-
-        Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders));
+        if (DEBUG_INTEGRITY_COMPONENT) {
+            Slog.i(TAG, String.format("Rule provider list contains: %s", integrityRuleProviders));
+        }
 
         // Filter out the rule provider packages that are not system apps.
-        return integrityRuleProviders.stream()
-                .filter(this::isSystemApp)
-                .collect(Collectors.toList());
+        List<String> systemAppRuleProviders = new ArrayList<>();
+        for (String ruleProvider: integrityRuleProviders) {
+            if (isSystemApp(ruleProvider)) {
+                systemAppRuleProviders.add(ruleProvider);
+            }
+        }
+        return systemAppRuleProviders;
     }
 
     private boolean isSystemApp(String packageName) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 3e6d6f5..f4f0e78 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -1255,6 +1255,7 @@
                 for (int i = 0; i < N; i++) {
                     final NotificationChannel nc = p.channels.valueAt(i);
                     if (!TextUtils.isEmpty(nc.getConversationId()) && !nc.isDeleted()
+                            && !nc.isDemoted()
                             && (nc.isImportantConversation() || !onlyImportant)) {
                         ConversationChannelWrapper conversation = new ConversationChannelWrapper();
                         conversation.setPkg(p.pkg);
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index d89605a..da07223 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -395,14 +395,6 @@
             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/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index c058317..130da2d 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1419,11 +1419,10 @@
     }
 
     /**
-     * @return {@code true} if there is a letterbox and any part of that letterbox overlaps with
-     * the given {@code rect}.
+     * @see Letterbox#notIntersectsOrFullyContains(Rect)
      */
-    boolean isLetterboxOverlappingWith(Rect rect) {
-        return mLetterbox != null && mLetterbox.isOverlappingWith(rect);
+    boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+        return mLetterbox == null || mLetterbox.notIntersectsOrFullyContains(rect);
     }
 
     static class Token extends IApplicationToken.Stub {
@@ -2677,7 +2676,7 @@
         if (isState(PAUSED)
                 && mStackSupervisor.getKeyguardController().isKeyguardLocked()
                 && getStack().topActivityOccludesKeyguard()) {
-            getStack().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
+            getDisplay().ensureActivitiesVisible(null /* starting */, 0 /* configChanges */,
                     false /* preserveWindows */, false /* notifyClients */);
         }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index ff43e77..2ab03ce 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -3264,7 +3264,15 @@
     }
 
     boolean shouldIgnoreInput() {
-        return inSplitScreenPrimaryWindowingMode() && !isFocusable();
+        if (inSplitScreenPrimaryWindowingMode() && !isFocusable()) {
+            return true;
+        }
+        if (mAtmService.mHasLeanbackFeature && inPinnedWindowingMode()
+                && !isFocusedStackOnDisplay()) {
+            // Preventing Picture-in-Picture stack from receiving input on TVs.
+            return true;
+        }
+        return false;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 02f6a69..5220fb2 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -42,7 +42,9 @@
 import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
 import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
+import static android.content.pm.PackageManager.FEATURE_CANT_SAVE_STATE;
 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
@@ -393,6 +395,7 @@
     /** The currently running heavy-weight process, if any. */
     WindowProcessController mHeavyWeightProcess = null;
     boolean mHasHeavyWeightFeature;
+    boolean mHasLeanbackFeature;
     /**
      * This is the process holding the activity the user last visited that is in a different process
      * from the one they are currently in.
@@ -734,8 +737,9 @@
 
     public void onSystemReady() {
         synchronized (mGlobalLock) {
-            mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_CANT_SAVE_STATE);
+            final PackageManager pm = mContext.getPackageManager();
+            mHasHeavyWeightFeature = pm.hasSystemFeature(FEATURE_CANT_SAVE_STATE);
+            mHasLeanbackFeature = pm.hasSystemFeature(FEATURE_LEANBACK);
             mAssistUtils = new AssistUtils(mContext);
             mVrController.onSystemReady();
             mRecentTasks.onSystemReadyLocked();
diff --git a/services/core/java/com/android/server/wm/BarController.java b/services/core/java/com/android/server/wm/BarController.java
index 57cdb0b..8b14095 100644
--- a/services/core/java/com/android/server/wm/BarController.java
+++ b/services/core/java/com/android/server/wm/BarController.java
@@ -168,7 +168,7 @@
     }
 
     boolean isTransparentAllowed(WindowState win) {
-        return win == null || !win.isLetterboxedOverlappingWith(mContentFrame);
+        return win == null || win.letterboxNotIntersectsOrFullyContains(mContentFrame);
     }
 
     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 a512337..9b34bd1 100644
--- a/services/core/java/com/android/server/wm/DisplayArea.java
+++ b/services/core/java/com/android/server/wm/DisplayArea.java
@@ -31,8 +31,10 @@
 import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
 import static com.android.server.wm.WindowContainerChildProto.DISPLAY_AREA;
 
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.util.proto.ProtoOutputStream;
+import android.window.DisplayAreaInfo;
 import android.window.IDisplayAreaOrganizer;
 
 import com.android.server.policy.WindowManagerPolicy;
@@ -154,10 +156,26 @@
     }
 
     @Override
+    public void onConfigurationChanged(Configuration newParentConfig) {
+        super.onConfigurationChanged(newParentConfig);
+        if (mOrganizer != null) {
+            mOrganizerController.onDisplayAreaInfoChanged(mOrganizer, this);
+        }
+    }
+
+    @Override
     boolean isOrganized() {
         return mOrganizer != null;
     }
 
+
+    DisplayAreaInfo getDisplayAreaInfo() {
+        DisplayAreaInfo info = new DisplayAreaInfo(mRemoteToken.toWindowContainerToken(),
+                getDisplayContent().getDisplayId());
+        info.configuration.setTo(getConfiguration());
+        return info;
+    }
+
     /**
      * DisplayArea that contains WindowTokens, and orders them according to their type.
      */
diff --git a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
index f05783b..2c8c820 100644
--- a/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
+++ b/services/core/java/com/android/server/wm/DisplayAreaOrganizerController.java
@@ -92,9 +92,28 @@
         }
     }
 
+    @Override
+    public void unregisterOrganizer(IDisplayAreaOrganizer organizer) {
+        enforceStackPermission("unregisterTaskOrganizer()");
+        final long origId = Binder.clearCallingIdentity();
+        try {
+            synchronized (mGlobalLock) {
+                mOrganizersByFeatureIds.entrySet().removeIf(
+                        entry -> entry.getValue().asBinder() == organizer.asBinder());
+
+                mService.mRootWindowContainer.forAllDisplayAreas((da) -> {
+                    if (da.mOrganizer != organizer) return;
+                    da.setOrganizer(null);
+                });
+            }
+        } finally {
+            Binder.restoreCallingIdentity(origId);
+        }
+    }
+
     void onDisplayAreaAppeared(IDisplayAreaOrganizer organizer, DisplayArea da) {
         try {
-            organizer.onDisplayAreaAppeared(da.mRemoteToken.toWindowContainerToken());
+            organizer.onDisplayAreaAppeared(da.getDisplayAreaInfo());
         } catch (RemoteException e) {
             // Oh well...
         }
@@ -102,7 +121,15 @@
 
     void onDisplayAreaVanished(IDisplayAreaOrganizer organizer, DisplayArea da) {
         try {
-            organizer.onDisplayAreaVanished(da.mRemoteToken.toWindowContainerToken());
+            organizer.onDisplayAreaVanished(da.getDisplayAreaInfo());
+        } catch (RemoteException e) {
+            // Oh well...
+        }
+    }
+
+    void onDisplayAreaInfoChanged(IDisplayAreaOrganizer organizer, DisplayArea da) {
+        try {
+            organizer.onDisplayAreaInfoChanged(da.getDisplayAreaInfo());
         } catch (RemoteException e) {
             // Oh well...
         }
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index 6721ef8..00a4be3 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, 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);
+        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);
     }
 
 
@@ -101,17 +101,29 @@
     }
 
     /**
-     * Returns true if any part of the letterbox overlaps with the given {@code rect}.
+     * 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.
      */
-    public boolean isOverlappingWith(Rect rect) {
+    boolean notIntersectsOrFullyContains(Rect rect) {
+        int emptyCount = 0;
+        int noOverlappingCount = 0;
         for (LetterboxSurface surface : mSurfaces) {
-            if (surface.isOverlappingWith(rect)) {
+            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
                 return true;
             }
         }
-        return false;
+        return (emptyCount + noOverlappingCount) == mSurfaces.length;
     }
-
     /**
      * Hides the letterbox.
      *
@@ -282,17 +294,6 @@
             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/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5bf49a6..93c6b6e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2285,16 +2285,18 @@
         }
         density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
 
-        // If bounds have been overridden at this level, restrict config resources to these bounds
-        // rather than the parent because the overridden bounds can be larger than the parent.
-        boolean hasOverrideBounds = false;
+        // The bounds may have been overridden at this level. If the parent cannot cover these
+        // bounds, the configuration is still computed according to the override bounds.
+        final boolean insideParentBounds;
 
+        final Rect parentBounds = parentConfig.windowConfiguration.getBounds();
         final Rect resolvedBounds = inOutConfig.windowConfiguration.getBounds();
         if (resolvedBounds == null || resolvedBounds.isEmpty()) {
-            mTmpFullBounds.set(parentConfig.windowConfiguration.getBounds());
+            mTmpFullBounds.set(parentBounds);
+            insideParentBounds = true;
         } else {
             mTmpFullBounds.set(resolvedBounds);
-            hasOverrideBounds = true;
+            insideParentBounds = parentBounds.contains(resolvedBounds);
         }
 
         Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
@@ -2303,30 +2305,30 @@
             outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
         }
         // Non-null compatibility insets means the activity prefers to keep its original size, so
-        // the out bounds doesn't need to be restricted by the parent.
-        final boolean insideParentBounds = compatInsets == null;
-        if (insideParentBounds && windowingMode != WINDOWING_MODE_FREEFORM) {
-            Rect parentAppBounds;
-            if (hasOverrideBounds) {
-                // Since we overrode the bounds, restrict appBounds to display non-decor rather
-                // than parent. Otherwise, it won't match the overridden bounds.
-                final TaskDisplayArea displayArea = getDisplayArea();
-                parentAppBounds = displayArea != null
-                        ? displayArea.getConfiguration().windowConfiguration.getAppBounds() : null;
+        // the out bounds doesn't need to be restricted by the parent or current display.
+        final boolean customContainerPolicy = compatInsets != null;
+        if (!customContainerPolicy && windowingMode != WINDOWING_MODE_FREEFORM) {
+            final Rect containingAppBounds;
+            if (insideParentBounds) {
+                containingAppBounds = parentConfig.windowConfiguration.getAppBounds();
             } else {
-                parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
+                // Restrict appBounds to display non-decor rather than parent because the override
+                // bounds are beyond the parent. Otherwise, it won't match the overridden bounds.
+                final TaskDisplayArea displayArea = getDisplayArea();
+                containingAppBounds = displayArea != null
+                        ? displayArea.getWindowConfiguration().getAppBounds() : null;
             }
-            if (parentAppBounds != null && !parentAppBounds.isEmpty()) {
-                outAppBounds.intersect(parentAppBounds);
+            if (containingAppBounds != null && !containingAppBounds.isEmpty()) {
+                outAppBounds.intersect(containingAppBounds);
             }
         }
 
         if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
                 || inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
-            if (insideParentBounds && WindowConfiguration.isFloating(windowingMode)) {
+            if (!customContainerPolicy && WindowConfiguration.isFloating(windowingMode)) {
                 mTmpNonDecorBounds.set(mTmpFullBounds);
                 mTmpStableBounds.set(mTmpFullBounds);
-            } else if (insideParentBounds
+            } else if (!customContainerPolicy
                     && (overrideDisplayInfo != null || getDisplayContent() != null)) {
                 final DisplayInfo di = overrideDisplayInfo != null
                         ? overrideDisplayInfo
@@ -2344,7 +2346,7 @@
                 if (rotation == ROTATION_UNDEFINED) {
                     rotation = parentConfig.windowConfiguration.getRotation();
                 }
-                if (rotation != ROTATION_UNDEFINED && compatInsets != null) {
+                if (rotation != ROTATION_UNDEFINED && customContainerPolicy) {
                     mTmpNonDecorBounds.set(mTmpFullBounds);
                     mTmpStableBounds.set(mTmpFullBounds);
                     compatInsets.getBoundsByRotation(mTmpBounds, rotation);
@@ -2362,13 +2364,13 @@
 
             if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
                 final int overrideScreenWidthDp = (int) (mTmpStableBounds.width() / density);
-                inOutConfig.screenWidthDp = (insideParentBounds && !hasOverrideBounds)
+                inOutConfig.screenWidthDp = (insideParentBounds && !customContainerPolicy)
                         ? Math.min(overrideScreenWidthDp, parentConfig.screenWidthDp)
                         : overrideScreenWidthDp;
             }
             if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
                 final int overrideScreenHeightDp = (int) (mTmpStableBounds.height() / density);
-                inOutConfig.screenHeightDp = (insideParentBounds && !hasOverrideBounds)
+                inOutConfig.screenHeightDp = (insideParentBounds && !customContainerPolicy)
                         ? Math.min(overrideScreenHeightDp, parentConfig.screenHeightDp)
                         : overrideScreenHeightDp;
             }
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index 25791c7..3dc6723 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -123,6 +123,10 @@
     private final RootWindowContainer.FindTaskResult
             mTmpFindTaskResult = new RootWindowContainer.FindTaskResult();
 
+    // Indicates whether the Assistant should show on top of the Dream (respectively, above
+    // everything else on screen). Otherwise, it will be put under always-on-top stacks.
+    private final boolean mAssistantOnTopOfDream;
+
     /**
      * If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
      * stack has been resumed. If stacks are changing position this will hold the old stack until
@@ -148,6 +152,9 @@
         mDisplayContent = displayContent;
         mRootWindowContainer = service.mRoot;
         mAtmService = service.mAtmService;
+
+        mAssistantOnTopOfDream = mWmService.mContext.getResources().getBoolean(
+                    com.android.internal.R.bool.config_assistantOnTopOfDream);
     }
 
     /**
@@ -327,55 +334,80 @@
     }
 
     /**
+     * Assigns a priority number to stack types. This priority defines an order between the types
+     * of stacks that are added to the task display area.
+     *
+     * Higher priority number indicates that the stack should have a higher z-order.
+     *
+     * @return the priority of the stack
+     */
+    private int getPriority(ActivityStack stack) {
+        if (mAssistantOnTopOfDream && stack.isActivityTypeAssistant()) return 4;
+        if (stack.isActivityTypeDream()) return 3;
+        if (stack.inPinnedWindowingMode()) return 2;
+        if (stack.isAlwaysOnTop()) return 1;
+        return 0;
+    }
+
+    private int findMinPositionForStack(ActivityStack stack) {
+        int minPosition = POSITION_BOTTOM;
+        for (int i = 0; i < mChildren.size(); ++i) {
+            if (getPriority(getStackAt(i)) < getPriority(stack)) {
+                minPosition = i;
+            } else {
+                break;
+            }
+        }
+
+        if (stack.isAlwaysOnTop()) {
+            // Since a stack could be repositioned while still being one of the children, we check
+            // if this always-on-top stack already exists and if so, set the minPosition to its
+            // previous position.
+            final int currentIndex = getIndexOf(stack);
+            if (currentIndex > minPosition) {
+                minPosition = currentIndex;
+            }
+        }
+        return minPosition;
+    }
+
+    private int findMaxPositionForStack(ActivityStack stack) {
+        for (int i = mChildren.size() - 1; i >= 0; --i) {
+            final ActivityStack curr = getStackAt(i);
+            // Since a stack could be repositioned while still being one of the children, we check
+            // if 'curr' is the same stack and skip it if so
+            final boolean sameStack = curr == stack;
+            if (getPriority(curr) <= getPriority(stack) && !sameStack) {
+                return i;
+            }
+        }
+        return 0;
+    }
+
+    /**
      * When stack is added or repositioned, find a proper position for it.
-     * This will make sure that pinned stack always stays on top.
+     *
+     * The order is defined as:
+     *  - Dream is on top of everything
+     *  - PiP is directly below the Dream
+     *  - always-on-top stacks are directly below PiP; new always-on-top stacks are added above
+     *    existing ones
+     *  - other non-always-on-top stacks come directly below always-on-top stacks; new
+     *    non-always-on-top stacks are added directly below always-on-top stacks and above existing
+     *    non-always-on-top stacks
+     *  - if {@link #mAssistantOnTopOfDream} is enabled, then Assistant is on top of everything
+     *    (including the Dream); otherwise, it is a normal non-always-on-top stack
+     *
      * @param requestedPosition Position requested by caller.
      * @param stack Stack to be added or positioned.
      * @param adding Flag indicates whether we're adding a new stack or positioning an existing.
      * @return The proper position for the stack.
      */
-    private int findPositionForStack(int requestedPosition, ActivityStack stack,
-            boolean adding) {
-        if (stack.isActivityTypeDream()) {
-            return POSITION_TOP;
-        }
-
-        if (stack.inPinnedWindowingMode()) {
-            return POSITION_TOP;
-        }
-
-        final int topChildPosition = mChildren.size() - 1;
-        int belowAlwaysOnTopPosition = POSITION_BOTTOM;
-        for (int i = topChildPosition; i >= 0; --i) {
-            // Since a stack could be repositioned while being one of the child, return
-            // current index if that's the same stack we are positioning and it is always on
-            // top.
-            final boolean sameStack = mChildren.get(i) == stack;
-            if ((sameStack && stack.isAlwaysOnTop())
-                    || (!sameStack && !mChildren.get(i).isAlwaysOnTop())) {
-                belowAlwaysOnTopPosition = i;
-                break;
-            }
-        }
-
+    private int findPositionForStack(int requestedPosition, ActivityStack stack, boolean adding) {
         // The max possible position we can insert the stack at.
-        int maxPosition = POSITION_TOP;
+        int maxPosition = findMaxPositionForStack(stack);
         // The min possible position we can insert the stack at.
-        int minPosition = POSITION_BOTTOM;
-
-        if (stack.isAlwaysOnTop()) {
-            if (hasPinnedTask()) {
-                // Always-on-top stacks go below the pinned stack.
-                maxPosition = mChildren.indexOf(mRootPinnedTask) - 1;
-            }
-            // Always-on-top stacks need to be above all other stacks.
-            minPosition = belowAlwaysOnTopPosition
-                    != POSITION_BOTTOM ? belowAlwaysOnTopPosition : topChildPosition;
-        } else {
-            // Other stacks need to be below the always-on-top stacks.
-            maxPosition = belowAlwaysOnTopPosition
-                    != POSITION_BOTTOM ? belowAlwaysOnTopPosition : 0;
-        }
+        int minPosition = findMinPositionForStack(stack);
 
         // Cap the requested position to something reasonable for the previous position check
         // below.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ef690e1..bbe5d94 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3660,9 +3660,12 @@
         return mActivityRecord.getBounds().equals(mTmpRect);
     }
 
-    @Override
-    public boolean isLetterboxedOverlappingWith(Rect rect) {
-        return mActivityRecord != null && mActivityRecord.isLetterboxOverlappingWith(rect);
+    /**
+     * @see Letterbox#notIntersectsOrFullyContains(Rect)
+     */
+    boolean letterboxNotIntersectsOrFullyContains(Rect rect) {
+        return mActivityRecord == null
+                || mActivityRecord.letterboxNotIntersectsOrFullyContains(rect);
     }
 
     boolean isDragResizeChanged() {
diff --git a/services/incremental/Android.bp b/services/incremental/Android.bp
index b8bd3b4..de639c5 100644
--- a/services/incremental/Android.bp
+++ b/services/incremental/Android.bp
@@ -19,6 +19,21 @@
     proto: {
         type: "lite",
     },
+    tidy: true,
+    tidy_checks: [
+        "android-*",
+        "cert-*",
+        "clang-analyzer-security*",
+        "-cert-err34-c",
+        "clang-analyzer-security*",
+        // Disabling due to many unavoidable warnings from POSIX API usage.
+        "-google-runtime-int",
+        "-google-explicit-constructor",
+        // do not define variadic C function - JNI headers
+        "-cert-dcl50-cpp",
+        // operator=() does not handle self-assignment properly - all protobuf-generated classes
+        "-cert-oop54-cpp",
+    ],
 }
 
 cc_defaults {
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index dc05cb6..a6c45cc 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -1395,7 +1395,7 @@
         auto startFileTs = Clock::now();
 
         const auto libName = path::basename(fileName);
-        const auto targetLibPath = path::join(libDirRelativePath, libName);
+        auto targetLibPath = path::join(libDirRelativePath, libName);
         const auto targetLibPathAbsolute = normalizePathToStorage(*ifs, storage, targetLibPath);
         // If the extract file already exists, skip
         if (access(targetLibPathAbsolute.c_str(), F_OK) == 0) {
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 32aa849..1e8c3a1 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -36,7 +36,7 @@
 
 class RealVoldService : public VoldServiceWrapper {
 public:
-    RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {}
+    RealVoldService(sp<os::IVold> vold) : mInterface(std::move(vold)) {}
     ~RealVoldService() = default;
     binder::Status mountIncFs(
             const std::string& backingPath, const std::string& targetDir, int32_t flags,
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 ac51750..f5d58a1 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -3142,6 +3142,44 @@
     }
 
     @Test
+    public void testGetConversations_notDemoted() {
+        String convoId = "convo";
+        NotificationChannel messages =
+                new NotificationChannel("messages", "Messages", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, messages, true, false);
+        NotificationChannel calls =
+                new NotificationChannel("calls", "Calls", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_O, UID_O, calls, true, false);
+        NotificationChannel p =
+                new NotificationChannel("p calls", "Calls", IMPORTANCE_DEFAULT);
+        mHelper.createNotificationChannel(PKG_P, UID_P, p, true, false);
+
+        NotificationChannel channel =
+                new NotificationChannel("A person msgs", "messages from A", IMPORTANCE_DEFAULT);
+        channel.setConversationId(messages.getId(), convoId);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel, true, false);
+
+        NotificationChannel diffConvo =
+                new NotificationChannel("B person msgs", "messages from B", IMPORTANCE_DEFAULT);
+        diffConvo.setConversationId(p.getId(), "different convo");
+        diffConvo.setDemoted(true);
+        mHelper.createNotificationChannel(PKG_P, UID_P, diffConvo, true, false);
+
+        NotificationChannel channel2 =
+                new NotificationChannel("A person calls", "calls from A", IMPORTANCE_DEFAULT);
+        channel2.setConversationId(calls.getId(), convoId);
+        channel2.setImportantConversation(true);
+        mHelper.createNotificationChannel(PKG_O, UID_O, channel2, true, false);
+
+        List<ConversationChannelWrapper> convos = mHelper.getConversations(false);
+
+        assertEquals(2, convos.size());
+        assertTrue(conversationWrapperContainsChannel(convos, channel));
+        assertFalse(conversationWrapperContainsChannel(convos, diffConvo));
+        assertTrue(conversationWrapperContainsChannel(convos, channel2));
+    }
+
+    @Test
     public void testGetConversations_onlyImportant() {
         String convoId = "convo";
         NotificationChannel messages =
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 1debd8c..e3bb1b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -270,6 +272,28 @@
         anotherAlwaysOnTopStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
         assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
         assertEquals(anotherAlwaysOnTopStack, taskDisplayArea.getStackAt(topPosition - 1));
+
+        final ActivityStack dreamStack = taskDisplayArea.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_DREAM, true /* onTop */);
+        assertEquals(taskDisplayArea, dreamStack.getDisplayArea());
+        assertTrue(dreamStack.isAlwaysOnTop());
+        topPosition = taskDisplayArea.getStackCount() - 1;
+        // Ensure dream shows above all activities, including PiP
+        assertEquals(dreamStack, taskDisplayArea.getTopStack());
+        assertEquals(pinnedStack, taskDisplayArea.getStackAt(topPosition - 1));
+
+        final ActivityStack assistStack = taskDisplayArea.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, true /* onTop */);
+        assertEquals(taskDisplayArea, assistStack.getDisplayArea());
+        assertFalse(assistStack.isAlwaysOnTop());
+        topPosition = taskDisplayArea.getStackCount() - 1;
+
+        // Ensure Assistant shows as a non-always-on-top activity when config_assistantOnTopOfDream
+        // is false and on top of everything when true.
+        final boolean isAssistantOnTop = mContext.getResources()
+                .getBoolean(com.android.internal.R.bool.config_assistantOnTopOfDream);
+        assertEquals(assistStack, taskDisplayArea.getStackAt(
+                    isAssistantOnTop ? topPosition : topPosition - 4));
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 93ded1b..6c209e4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -471,23 +471,39 @@
         assertEquals(STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT,
                 splitScreenSecondary2.getVisibility(null /* starting */));
 
-        // Assistant stack shouldn't be visible behind translucent split-screen stack
+        // Assistant stack shouldn't be visible behind translucent split-screen stack,
+        // unless it is configured to show on top of everything.
         doReturn(false).when(assistantStack).isTranslucent(any());
         doReturn(true).when(splitScreenPrimary).isTranslucent(any());
         doReturn(true).when(splitScreenSecondary2).isTranslucent(any());
         splitScreenSecondary2.moveToFront("testShouldBeVisible_SplitScreen");
         splitScreenPrimary.moveToFront("testShouldBeVisible_SplitScreen");
-        assertFalse(assistantStack.shouldBeVisible(null /* starting */));
-        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
-        assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
-                assistantStack.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
-                splitScreenPrimary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_INVISIBLE,
-                splitScreenSecondary.getVisibility(null /* starting */));
-        assertEquals(STACK_VISIBILITY_VISIBLE,
-                splitScreenSecondary2.getVisibility(null /* starting */));
+
+        if (isAssistantOnTop()) {
+            assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+            assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
+            assertFalse(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+            assertEquals(STACK_VISIBILITY_VISIBLE,
+                    assistantStack.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_INVISIBLE,
+                    splitScreenPrimary.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_INVISIBLE,
+                    splitScreenSecondary.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_INVISIBLE,
+                    splitScreenSecondary2.getVisibility(null /* starting */));
+        } else {
+            assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+            assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+            assertTrue(splitScreenSecondary2.shouldBeVisible(null /* starting */));
+            assertEquals(STACK_VISIBILITY_INVISIBLE,
+                    assistantStack.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_VISIBLE,
+                    splitScreenPrimary.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_INVISIBLE,
+                    splitScreenSecondary.getVisibility(null /* starting */));
+            assertEquals(STACK_VISIBILITY_VISIBLE,
+                    splitScreenSecondary2.getVisibility(null /* starting */));
+        }
     }
 
     @Test
@@ -927,9 +943,15 @@
 
         splitScreenSecondary.moveToFront("testSplitScreenMoveToFront");
 
-        assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
-        assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
-        assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+        if (isAssistantOnTop()) {
+            assertFalse(splitScreenPrimary.shouldBeVisible(null /* starting */));
+            assertFalse(splitScreenSecondary.shouldBeVisible(null /* starting */));
+            assertTrue(assistantStack.shouldBeVisible(null /* starting */));
+        } else {
+            assertTrue(splitScreenPrimary.shouldBeVisible(null /* starting */));
+            assertTrue(splitScreenSecondary.shouldBeVisible(null /* starting */));
+            assertFalse(assistantStack.shouldBeVisible(null /* starting */));
+        }
     }
 
     private ActivityStack createStandardStackForVisibilityTest(int windowingMode,
@@ -1344,6 +1366,11 @@
                 anyBoolean());
     }
 
+    private boolean isAssistantOnTop() {
+        return mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_assistantOnTopOfDream);
+    }
+
     private void verifyShouldSleepActivities(boolean focusedStack,
             boolean keyguardGoingAway, boolean displaySleeping, boolean expected) {
         final DisplayContent display = mock(DisplayContent.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java
new file mode 100644
index 0000000..307b40f
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaOrganizerTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.window.DisplayAreaOrganizer.FEATURE_VENDOR_FIRST;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.window.IDisplayAreaOrganizer;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class DisplayAreaOrganizerTest extends WindowTestsBase {
+
+    private DisplayArea mTestDisplayArea;
+
+    @Before
+    public void setUp() {
+        WindowContainer parentWindow = mDisplayContent.getDefaultTaskDisplayArea().getParent();
+        mTestDisplayArea = new DisplayArea(mWm, DisplayArea.Type.ANY,
+                "TestDisplayArea", FEATURE_VENDOR_FIRST);
+        parentWindow.addChild(mTestDisplayArea,
+                parentWindow.mChildren.indexOf(mDisplayContent.getDefaultTaskDisplayArea()) + 1);
+    }
+
+    @After
+    public void tearDown() {
+        mTestDisplayArea.removeImmediately();
+    }
+
+    private IDisplayAreaOrganizer registerMockOrganizer(int feature) {
+        final IDisplayAreaOrganizer organizer = mock(IDisplayAreaOrganizer.class);
+        when(organizer.asBinder()).thenReturn(new Binder());
+
+        mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController
+                .registerOrganizer(organizer, feature);
+        return organizer;
+    }
+
+    private void unregisterMockOrganizer(IDisplayAreaOrganizer organizer) {
+        mWm.mAtmService.mWindowOrganizerController.mDisplayAreaOrganizerController
+                .unregisterOrganizer(organizer);
+    }
+
+    @Test
+    public void testAppearedVanished() throws RemoteException {
+        IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
+        verify(organizer).onDisplayAreaAppeared(any());
+
+        unregisterMockOrganizer(organizer);
+        verify(organizer).onDisplayAreaVanished(any());
+    }
+
+    @Test
+    public void testChanged() throws RemoteException {
+        IDisplayAreaOrganizer organizer = registerMockOrganizer(FEATURE_VENDOR_FIRST);
+        verify(organizer).onDisplayAreaAppeared(any());
+
+        mDisplayContent.setBounds(new Rect(0, 0, 1000, 1000));
+        verify(organizer).onDisplayAreaInfoChanged(any());
+    }
+}
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 15417d7..2251ee0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxTest.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.clearInvocations;
@@ -53,10 +54,102 @@
         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 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)));
+    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);
+        }
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index dcc2ff1..60875de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -372,7 +372,9 @@
         final int longSide = 1200;
         final int shortSide = 600;
         final Rect parentBounds = new Rect(0, 0, 250, 500);
+        final Rect parentAppBounds = new Rect(0, 0, 250, 480);
         parentConfig.windowConfiguration.setBounds(parentBounds);
+        parentConfig.windowConfiguration.setAppBounds(parentAppBounds);
         parentConfig.densityDpi = 400;
         parentConfig.screenHeightDp = (parentBounds.bottom * 160) / parentConfig.densityDpi; // 200
         parentConfig.screenWidthDp = (parentBounds.right * 160) / parentConfig.densityDpi; // 100
@@ -383,21 +385,25 @@
 
         assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
         assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+        assertEquals(parentAppBounds, inOutConfig.windowConfiguration.getAppBounds());
         assertEquals(Configuration.ORIENTATION_PORTRAIT, inOutConfig.orientation);
 
         // If bounds are overridden, config properties should be made to match. Surface hierarchy
         // will crop for policy.
         inOutConfig.setToDefaults();
-        inOutConfig.windowConfiguration.getBounds().set(0, 0, shortSide, longSide);
-        // By default, the parent bounds should limit the existing input bounds.
+        final Rect largerPortraitBounds = new Rect(0, 0, shortSide, longSide);
+        inOutConfig.windowConfiguration.setBounds(largerPortraitBounds);
         task.computeConfigResourceOverrides(inOutConfig, parentConfig);
-
+        // The override bounds are beyond the parent, the out appBounds should not be intersected
+        // by parent appBounds.
+        assertEquals(largerPortraitBounds, inOutConfig.windowConfiguration.getAppBounds());
         assertEquals(longSide, inOutConfig.screenHeightDp * parentConfig.densityDpi / 160);
         assertEquals(shortSide, inOutConfig.screenWidthDp * parentConfig.densityDpi / 160);
 
         inOutConfig.setToDefaults();
         // Landscape bounds.
-        inOutConfig.windowConfiguration.getBounds().set(0, 0, longSide, shortSide);
+        final Rect largerLandscapeBounds = new Rect(0, 0, longSide, shortSide);
+        inOutConfig.windowConfiguration.setBounds(largerLandscapeBounds);
 
         // Setup the display with a top stable inset. The later assertion will ensure the inset is
         // excluded from screenHeightDp.
@@ -415,6 +421,7 @@
                 new ActivityRecord.CompatDisplayInsets(display, task);
         task.computeConfigResourceOverrides(inOutConfig, parentConfig, compatIntsets);
 
+        assertEquals(largerLandscapeBounds, inOutConfig.windowConfiguration.getAppBounds());
         assertEquals((shortSide - statusBarHeight) * DENSITY_DEFAULT / parentConfig.densityDpi,
                 inOutConfig.screenHeightDp);
         assertEquals(longSide * DENSITY_DEFAULT / parentConfig.densityDpi,