Merge "Add the min aspect ratio to ActivityRecordProto and populate it"
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index c3f9c20..9af6c1b 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -297,6 +297,10 @@
     method @Nullable public android.os.IBinder getOrThrow() throws android.os.StatsServiceManager.ServiceNotFoundException;
   }
 
+  public class SystemConfigManager {
+    method @NonNull public java.util.List<android.content.ComponentName> getEnabledComponentOverrides(@NonNull String);
+  }
+
 }
 
 package android.os.storage {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ac6943c..78e6a07 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -8581,7 +8581,6 @@
   public class SystemConfigManager {
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Set<java.lang.String> getDisabledUntilUsedPreinstalledCarrierApps();
     method @NonNull @RequiresPermission(android.Manifest.permission.READ_CARRIER_APP_INFO) public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
-    method @NonNull public java.util.List<java.lang.String> getEnabledComponentOverrides(@NonNull String);
     method @NonNull @RequiresPermission(android.Manifest.permission.GET_RUNTIME_PERMISSIONS) public int[] getSystemPermissionUids(@NonNull String);
   }
 
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 2a344f6..ad3de25 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -103,7 +103,7 @@
      * are unparcelled, mParcelledData willbe set to null.
      */
     @UnsupportedAppUsage
-    Parcel mParcelledData = null;
+    volatile Parcel mParcelledData = null;
 
     /**
      * Whether {@link #mParcelledData} was generated by native code or not.
@@ -182,13 +182,56 @@
      * @param b a Bundle to be copied.
      */
     BaseBundle(BaseBundle b) {
-        copyInternal(b, false);
+        this(b, /* deep */ false);
     }
 
     /**
-     * Special constructor that does not initialize the bundle.
+     * Constructs a {@link BaseBundle} containing a copy of {@code from}.
+     *
+     * @param from The bundle to be copied.
+     * @param deep Whether is a deep or shallow copy.
+     *
+     * @hide
      */
-    BaseBundle(boolean doInit) {
+    BaseBundle(BaseBundle from, boolean deep) {
+        synchronized (from) {
+            mClassLoader = from.mClassLoader;
+
+            if (from.mMap != null) {
+                if (!deep) {
+                    mMap = new ArrayMap<>(from.mMap);
+                } else {
+                    final ArrayMap<String, Object> fromMap = from.mMap;
+                    final int n = fromMap.size();
+                    mMap = new ArrayMap<>(n);
+                    for (int i = 0; i < n; i++) {
+                        mMap.append(fromMap.keyAt(i), deepCopyValue(fromMap.valueAt(i)));
+                    }
+                }
+            } else {
+                mMap = null;
+            }
+
+            final Parcel parcelledData;
+            if (from.mParcelledData != null) {
+                if (from.isEmptyParcel()) {
+                    parcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
+                    mParcelledByNative = false;
+                } else {
+                    parcelledData = Parcel.obtain();
+                    parcelledData.appendFrom(from.mParcelledData, 0,
+                            from.mParcelledData.dataSize());
+                    parcelledData.setDataPosition(0);
+                    mParcelledByNative = from.mParcelledByNative;
+                }
+            } else {
+                parcelledData = null;
+                mParcelledByNative = false;
+            }
+
+            // Keep as last statement to ensure visibility of other fields
+            mParcelledData = parcelledData;
+        }
     }
 
     /**
@@ -323,8 +366,8 @@
             } else {
                 mMap.erase();
             }
-            mParcelledData = null;
             mParcelledByNative = false;
+            mParcelledData = null;
             return;
         }
 
@@ -358,8 +401,8 @@
             if (recycleParcel) {
                 recycleParcel(parcelledData);
             }
-            mParcelledData = null;
             mParcelledByNative = false;
+            mParcelledData = null;
         }
         if (DEBUG) {
             Log.d(TAG, "unparcel " + Integer.toHexString(System.identityHashCode(this))
@@ -501,44 +544,7 @@
         mMap.clear();
     }
 
-    void copyInternal(BaseBundle from, boolean deep) {
-        synchronized (from) {
-            if (from.mParcelledData != null) {
-                if (from.isEmptyParcel()) {
-                    mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
-                    mParcelledByNative = false;
-                } else {
-                    mParcelledData = Parcel.obtain();
-                    mParcelledData.appendFrom(from.mParcelledData, 0,
-                            from.mParcelledData.dataSize());
-                    mParcelledData.setDataPosition(0);
-                    mParcelledByNative = from.mParcelledByNative;
-                }
-            } else {
-                mParcelledData = null;
-                mParcelledByNative = false;
-            }
-
-            if (from.mMap != null) {
-                if (!deep) {
-                    mMap = new ArrayMap<>(from.mMap);
-                } else {
-                    final ArrayMap<String, Object> fromMap = from.mMap;
-                    final int N = fromMap.size();
-                    mMap = new ArrayMap<>(N);
-                    for (int i = 0; i < N; i++) {
-                        mMap.append(fromMap.keyAt(i), deepCopyValue(fromMap.valueAt(i)));
-                    }
-                }
-            } else {
-                mMap = null;
-            }
-
-            mClassLoader = from.mClassLoader;
-        }
-    }
-
-    Object deepCopyValue(Object value) {
+    private Object deepCopyValue(Object value) {
         if (value == null) {
             return null;
         }
@@ -570,7 +576,7 @@
         return value;
     }
 
-    ArrayList deepcopyArrayList(ArrayList from) {
+    private ArrayList deepcopyArrayList(ArrayList from) {
         final int N = from.size();
         ArrayList out = new ArrayList(N);
         for (int i=0; i<N; i++) {
@@ -1717,9 +1723,9 @@
         if (length < 0) {
             throw new RuntimeException("Bad length in parcel: " + length);
         } else if (length == 0) {
+            mParcelledByNative = false;
             // Empty Bundle or end of data.
             mParcelledData = NoImagePreloadHolder.EMPTY_PARCEL;
-            mParcelledByNative = false;
             return;
         } else if (length % 4 != 0) {
             throw new IllegalStateException("Bundle length is not aligned by 4: " + length);
@@ -1757,8 +1763,8 @@
                 + ": " + length + " bundle bytes starting at " + offset);
         p.setDataPosition(0);
 
-        mParcelledData = p;
         mParcelledByNative = isNativeBundle;
+        mParcelledData = p;
     }
 
     /** {@hide} */
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 92eb7a5..b2bbfd6 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -102,6 +102,18 @@
     }
 
     /**
+     * Constructs a {@link Bundle} containing a copy of {@code from}.
+     *
+     * @param from The bundle to be copied.
+     * @param deep Whether is a deep or shallow copy.
+     *
+     * @hide
+     */
+    Bundle(Bundle from, boolean deep) {
+        super(from, deep);
+    }
+
+    /**
      * If {@link #mParcelledData} is not null, copy the HAS FDS bit from it because it's fast.
      * Otherwise (if {@link #mParcelledData} is already null), leave {@link #FLAG_HAS_FDS_KNOWN}
      * unset, because scanning a map is slower.  We'll do it lazily in
@@ -167,13 +179,6 @@
     }
 
     /**
-     * Constructs a Bundle without initializing it.
-     */
-    Bundle(boolean doInit) {
-        super(doInit);
-    }
-
-    /**
      * Make a Bundle for a single key/value pair.
      *
      * @hide
@@ -260,9 +265,7 @@
      * are referenced as-is and not copied in any way.
      */
     public Bundle deepCopy() {
-        Bundle b = new Bundle(false);
-        b.copyInternal(this, true);
-        return b;
+        return new Bundle(this, /* deep */ true);
     }
 
     /**
@@ -324,28 +327,10 @@
      */
     public boolean hasFileDescriptors() {
         if ((mFlags & FLAG_HAS_FDS_KNOWN) == 0) {
-            boolean fdFound = false;    // keep going until we find one or run out of data
-
-            if (mParcelledData != null) {
-                if (mParcelledData.hasFileDescriptors()) {
-                    fdFound = true;
-                }
-            } else {
-                // It's been unparcelled, so we need to walk the map
-                for (int i=mMap.size()-1; i>=0; i--) {
-                    Object obj = mMap.valueAt(i);
-                    if (Parcel.hasFileDescriptors(obj)) {
-                        fdFound = true;
-                        break;
-                    }
-                }
-            }
-
-            if (fdFound) {
-                mFlags |= FLAG_HAS_FDS;
-            } else {
-                mFlags &= ~FLAG_HAS_FDS;
-            }
+            Parcel p = mParcelledData;
+            mFlags = (Parcel.hasFileDescriptors((p != null) ? p : mMap))
+                    ? mFlags | FLAG_HAS_FDS
+                    : mFlags & ~FLAG_HAS_FDS;
             mFlags |= FLAG_HAS_FDS_KNOWN;
         }
         return (mFlags & FLAG_HAS_FDS) != 0;
diff --git a/core/java/android/os/ISystemConfig.aidl b/core/java/android/os/ISystemConfig.aidl
index d83d94a..15e3ce2 100644
--- a/core/java/android/os/ISystemConfig.aidl
+++ b/core/java/android/os/ISystemConfig.aidl
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import android.content.ComponentName;
+
 /**
   * Binder interface to query SystemConfig in the system server.
   * {@hide}
@@ -44,5 +46,5 @@
     /**
      * @see SystemConfigManager#getEnabledComponentOverrides
      */
-    List<String> getEnabledComponentOverrides(String packageName);
+    List<ComponentName> getEnabledComponentOverrides(String packageName);
 }
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index dd0cb8c..d1e6716 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -747,57 +747,70 @@
     }
 
     /**
-     * Check if the object used in {@link #readValue(ClassLoader)} / {@link #writeValue(Object)}
-     * has file descriptors.
+     * Check if the object has file descriptors.
+     *
+     * <p>Objects supported are {@link Parcel} and objects that can be passed to {@link
+     * #writeValue(Object)}}
      *
      * <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
      * for that.
      *
-     * @throws IllegalArgumentException if you provide any object not supported by above methods.
-     *         Most notably, if you pass {@link Parcel}, this method will throw, for that check
-     *         {@link Parcel#hasFileDescriptors()}
+     * @throws IllegalArgumentException if you provide any object not supported by above methods
+     *     (including if the unsupported object is inside a nested container).
      *
      * @hide
      */
     public static boolean hasFileDescriptors(Object value) {
-        if (value instanceof LazyValue) {
-            return ((LazyValue) value).hasFileDescriptors();
-        } else if (value instanceof Parcelable) {
-            if ((((Parcelable) value).describeContents()
-                    & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+        if (value instanceof Parcel) {
+            Parcel parcel = (Parcel) value;
+            if (parcel.hasFileDescriptors()) {
                 return true;
             }
-        } else if (value instanceof Parcelable[]) {
-            Parcelable[] array = (Parcelable[]) value;
-            for (int n = array.length - 1; n >= 0; n--) {
-                Parcelable p = array[n];
-                if (p != null && ((p.describeContents()
-                        & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
+        } else if (value instanceof LazyValue) {
+            LazyValue lazy = (LazyValue) value;
+            if (lazy.hasFileDescriptors()) {
+                return true;
+            }
+        } else if (value instanceof Parcelable) {
+            Parcelable parcelable = (Parcelable) value;
+            if ((parcelable.describeContents() & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
+                return true;
+            }
+        } else if (value instanceof ArrayMap<?, ?>) {
+            ArrayMap<?, ?> map = (ArrayMap<?, ?>) value;
+            for (int i = 0, n = map.size(); i < n; i++) {
+                if (hasFileDescriptors(map.keyAt(i))
+                        || hasFileDescriptors(map.valueAt(i))) {
+                    return true;
+                }
+            }
+        } else if (value instanceof Map<?, ?>) {
+            Map<?, ?> map = (Map<?, ?>) value;
+            for (Map.Entry<?, ?> entry : map.entrySet()) {
+                if (hasFileDescriptors(entry.getKey())
+                        || hasFileDescriptors(entry.getValue())) {
+                    return true;
+                }
+            }
+        } else if (value instanceof List<?>) {
+            List<?> list = (List<?>) value;
+            for (int i = 0, n = list.size(); i < n; i++) {
+                if (hasFileDescriptors(list.get(i))) {
                     return true;
                 }
             }
         } else if (value instanceof SparseArray<?>) {
             SparseArray<?> array = (SparseArray<?>) value;
-            for (int n = array.size() - 1; n >= 0; n--) {
-                Object object = array.valueAt(n);
-                if (object instanceof Parcelable) {
-                    Parcelable p = (Parcelable) object;
-                    if (p != null && (p.describeContents()
-                            & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0) {
-                        return true;
-                    }
+            for (int i = 0, n = array.size(); i < n; i++) {
+                if (hasFileDescriptors(array.valueAt(i))) {
+                    return true;
                 }
             }
-        } else if (value instanceof ArrayList<?>) {
-            ArrayList<?> array = (ArrayList<?>) value;
-            for (int n = array.size() - 1; n >= 0; n--) {
-                Object object = array.get(n);
-                if (object instanceof Parcelable) {
-                    Parcelable p = (Parcelable) object;
-                    if (p != null && ((p.describeContents()
-                            & Parcelable.CONTENTS_FILE_DESCRIPTOR) != 0)) {
-                        return true;
-                    }
+        } else if (value instanceof Object[]) {
+            Object[] array = (Object[]) value;
+            for (int i = 0, n = array.length; i < n; i++) {
+                if (hasFileDescriptors(array[i])) {
+                    return true;
                 }
             }
         } else {
diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java
index 7b55e710..f4edcb1 100644
--- a/core/java/android/os/PersistableBundle.java
+++ b/core/java/android/os/PersistableBundle.java
@@ -156,10 +156,15 @@
     }
 
     /**
-     * Constructs a PersistableBundle without initializing it.
+     * Constructs a {@link PersistableBundle} containing a copy of {@code from}.
+     *
+     * @param from The bundle to be copied.
+     * @param deep Whether is a deep or shallow copy.
+     *
+     * @hide
      */
-    PersistableBundle(boolean doInit) {
-        super(doInit);
+    PersistableBundle(PersistableBundle from, boolean deep) {
+        super(from, deep);
     }
 
     /**
@@ -190,9 +195,7 @@
      * are referenced as-is and not copied in any way.
      */
     public PersistableBundle deepCopy() {
-        PersistableBundle b = new PersistableBundle(false);
-        b.copyInternal(this, true);
-        return b;
+        return new PersistableBundle(this, /* deep */ true);
     }
 
     /**
diff --git a/core/java/android/os/SystemConfigManager.java b/core/java/android/os/SystemConfigManager.java
index a6316df..cde2063 100644
--- a/core/java/android/os/SystemConfigManager.java
+++ b/core/java/android/os/SystemConfigManager.java
@@ -17,10 +17,10 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.content.ComponentName;
 import android.content.Context;
 import android.util.ArraySet;
 import android.util.Log;
@@ -138,9 +138,9 @@
      * @return The enabled component
      * {@hide}
      */
-    @SystemApi
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @NonNull
-    public List<String> getEnabledComponentOverrides(@NonNull String packageName) {
+    public List<ComponentName> getEnabledComponentOverrides(@NonNull String packageName) {
         try {
             return mInterface.getEnabledComponentOverrides(packageName);
         } catch (RemoteException e) {
diff --git a/rs/jni/Android.bp b/rs/jni/Android.bp
new file mode 100644
index 0000000..9a6fa8e
--- /dev/null
+++ b/rs/jni/Android.bp
@@ -0,0 +1,54 @@
+//
+// Copyright (C) 2021 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 {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+cc_library_shared {
+    name: "librs_jni",
+
+    srcs: ["android_renderscript_RenderScript.cpp"],
+
+    shared_libs: [
+        "libandroid",
+        "libandroid_runtime",
+        "libandroidfw",
+        "libRS",
+        "libcutils",
+        "libhwui",
+        "liblog",
+        "libutils",
+        "libui",
+        "libgui",
+        "libjnigraphics",
+    ],
+
+    header_libs: [
+        "jni_headers",
+        "libbase_headers",
+    ],
+
+    include_dirs: ["frameworks/rs"],
+
+    cflags: [
+        "-Wno-unused-parameter",
+        "-Wunused",
+        "-Wunreachable-code",
+        "-Wno-deprecated-declarations",
+    ],
+}
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
deleted file mode 100644
index 0caba42..0000000
--- a/rs/jni/Android.mk
+++ /dev/null
@@ -1,37 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    android_renderscript_RenderScript.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libandroid \
-    libandroid_runtime \
-    libandroidfw \
-    libRS \
-    libcutils \
-    libhwui \
-    liblog \
-    libutils \
-    libui \
-    libgui \
-    libjnigraphics
-
-LOCAL_HEADER_LIBRARIES := \
-    jni_headers \
-    libbase_headers
-
-LOCAL_C_INCLUDES += \
-    frameworks/rs
-
-LOCAL_CFLAGS += -Wno-unused-parameter
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-deprecated-declarations
-
-LOCAL_MODULE:= librs_jni
-LOCAL_LICENSE_KINDS:= SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS:= notice
-LOCAL_NOTICE_FILE:= $(LOCAL_PATH)/../../NOTICE
-LOCAL_MODULE_TAGS := optional
-LOCAL_REQUIRED_MODULES := libRS
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/java/com/android/server/SystemConfigService.java b/services/java/com/android/server/SystemConfigService.java
index 3a9b2dc..cb52e5f 100644
--- a/services/java/com/android/server/SystemConfigService.java
+++ b/services/java/com/android/server/SystemConfigService.java
@@ -19,6 +19,7 @@
 import static java.util.stream.Collectors.toMap;
 
 import android.Manifest;
+import android.content.ComponentName;
 import android.content.Context;
 import android.os.ISystemConfig;
 import android.util.ArrayMap;
@@ -87,14 +88,14 @@
         }
 
         @Override
-        public List<String> getEnabledComponentOverrides(String packageName) {
+        public List<ComponentName> getEnabledComponentOverrides(String packageName) {
             ArrayMap<String, Boolean> systemComponents = SystemConfig.getInstance()
                     .getComponentsEnabledStates(packageName);
-            List<String> enabledComponent = new ArrayList<>();
+            List<ComponentName> enabledComponent = new ArrayList<>();
             if (systemComponents != null) {
                 for (Map.Entry<String, Boolean> entry : systemComponents.entrySet()) {
                     if (Boolean.TRUE.equals(entry.getValue())) {
-                        enabledComponent.add(entry.getKey());
+                        enabledComponent.add(new ComponentName(packageName, entry.getKey()));
                     }
                 }
             }