Merge "Mount storage after unlock, fix leaving emulation."
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f2aea08..8d035b7 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -61,12 +61,12 @@
  * appropriate to place any Parcel data in to persistent storage: changes
  * in the underlying implementation of any of the data in the Parcel can
  * render older data unreadable.</p>
- * 
+ *
  * <p>The bulk of the Parcel API revolves around reading and writing data
  * of various types.  There are six major classes of such functions available.</p>
- * 
+ *
  * <h3>Primitives</h3>
- * 
+ *
  * <p>The most basic data functions are for writing and reading primitive
  * data types: {@link #writeByte}, {@link #readByte}, {@link #writeDouble},
  * {@link #readDouble}, {@link #writeFloat}, {@link #readFloat}, {@link #writeInt},
@@ -74,15 +74,15 @@
  * {@link #writeString}, {@link #readString}.  Most other
  * data operations are built on top of these.  The given data is written and
  * read using the endianess of the host CPU.</p>
- * 
+ *
  * <h3>Primitive Arrays</h3>
- * 
+ *
  * <p>There are a variety of methods for reading and writing raw arrays
  * of primitive objects, which generally result in writing a 4-byte length
  * followed by the primitive data items.  The methods for reading can either
  * read the data into an existing array, or create and return a new array.
  * These available types are:</p>
- * 
+ *
  * <ul>
  * <li> {@link #writeBooleanArray(boolean[])},
  * {@link #readBooleanArray(boolean[])}, {@link #createBooleanArray()}
@@ -104,9 +104,9 @@
  * <li> {@link #writeSparseBooleanArray(SparseBooleanArray)},
  * {@link #readSparseBooleanArray()}.
  * </ul>
- * 
+ *
  * <h3>Parcelables</h3>
- * 
+ *
  * <p>The {@link Parcelable} protocol provides an extremely efficient (but
  * low-level) protocol for objects to write and read themselves from Parcels.
  * You can use the direct methods {@link #writeParcelable(Parcelable, int)}
@@ -116,7 +116,7 @@
  * methods write both the class type and its data to the Parcel, allowing
  * that class to be reconstructed from the appropriate class loader when
  * later reading.</p>
- * 
+ *
  * <p>There are also some methods that provide a more efficient way to work
  * with Parcelables: {@link #writeTypedObject}, {@link #writeTypedArray},
  * {@link #writeTypedList}, {@link #readTypedObject},
@@ -129,9 +129,9 @@
  * call {@link Parcelable#writeToParcel Parcelable.writeToParcel} and
  * {@link Parcelable.Creator#createFromParcel Parcelable.Creator.createFromParcel}
  * yourself.)</p>
- * 
+ *
  * <h3>Bundles</h3>
- * 
+ *
  * <p>A special type-safe container, called {@link Bundle}, is available
  * for key/value maps of heterogeneous values.  This has many optimizations
  * for improved performance when reading and writing data, and its type-safe
@@ -139,16 +139,16 @@
  * data contents into a Parcel.  The methods to use are
  * {@link #writeBundle(Bundle)}, {@link #readBundle()}, and
  * {@link #readBundle(ClassLoader)}.
- * 
+ *
  * <h3>Active Objects</h3>
- * 
+ *
  * <p>An unusual feature of Parcel is the ability to read and write active
  * objects.  For these objects the actual contents of the object is not
  * written, rather a special token referencing the object is written.  When
  * reading the object back from the Parcel, you do not get a new instance of
  * the object, but rather a handle that operates on the exact same object that
  * was originally written.  There are two forms of active objects available.</p>
- * 
+ *
  * <p>{@link Binder} objects are a core facility of Android's general cross-process
  * communication system.  The {@link IBinder} interface describes an abstract
  * protocol with a Binder object.  Any such interface can be written in to
@@ -161,7 +161,7 @@
  * {@link #createBinderArray()},
  * {@link #writeBinderList(List)}, {@link #readBinderList(List)},
  * {@link #createBinderArrayList()}.</p>
- * 
+ *
  * <p>FileDescriptor objects, representing raw Linux file descriptor identifiers,
  * can be written and {@link ParcelFileDescriptor} objects returned to operate
  * on the original file descriptor.  The returned file descriptor is a dup
@@ -169,9 +169,9 @@
  * operating on the same underlying file stream, with the same position, etc.
  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
  * {@link #readFileDescriptor()}.
- * 
+ *
  * <h3>Untyped Containers</h3>
- * 
+ *
  * <p>A final class of methods are for writing and reading standard Java
  * containers of arbitrary types.  These all revolve around the
  * {@link #writeValue(Object)} and {@link #readValue(ClassLoader)} methods
@@ -233,6 +233,7 @@
     private static final int VAL_PERSISTABLEBUNDLE = 25;
     private static final int VAL_SIZE = 26;
     private static final int VAL_SIZEF = 27;
+    private static final int VAL_DOUBLEARRAY = 28;
 
     // The initial int32 in a Binder call's reply Parcel header:
     private static final int EX_SECURITY = -1;
@@ -663,7 +664,7 @@
      * growing dataCapacity() if needed.  The Map keys must be String objects.
      * The Map values are written using {@link #writeValue} and must follow
      * the specification there.
-     * 
+     *
      * <p>It is strongly recommended to use {@link #writeBundle} instead of
      * this method, since the Bundle class provides a type-safe API that
      * allows you to avoid mysterious type errors at the point of marshalling.
@@ -1429,6 +1430,9 @@
         } else if (v instanceof SizeF) {
             writeInt(VAL_SIZEF);
             writeSizeF((SizeF) v);
+        } else if (v instanceof double[]) {
+            writeInt(VAL_DOUBLEARRAY);
+            writeDoubleArray((double[]) v);
         } else {
             Class<?> clazz = v.getClass();
             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -1504,7 +1508,7 @@
      * exception will be re-thrown by this function as a RuntimeException
      * (to be caught by the system's last-resort exception handling when
      * dispatching a transaction).
-     * 
+     *
      * <p>The supported exception types are:
      * <ul>
      * <li>{@link BadParcelableException}
@@ -1514,7 +1518,7 @@
      * <li>{@link SecurityException}
      * <li>{@link NetworkOnMainThreadException}
      * </ul>
-     * 
+     *
      * @param e The Exception to be written.
      *
      * @see #writeNoException
@@ -1835,7 +1839,7 @@
             if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
             return null;
         }
-        
+
         final Bundle bundle = new Bundle(this, length);
         if (loader != null) {
             bundle.setClassLoader(loader);
@@ -2346,7 +2350,7 @@
             return readArrayList(loader);
 
         case VAL_BOOLEANARRAY:
-            return createBooleanArray();        
+            return createBooleanArray();
 
         case VAL_BYTEARRAY:
             return createByteArray();
@@ -2396,6 +2400,9 @@
         case VAL_SIZEF:
             return readSizeF();
 
+        case VAL_DOUBLEARRAY:
+            return createDoubleArray();
+
         default:
             int off = dataPosition() - 4;
             throw new RuntimeException(
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 4ee9807..bdb1fdc 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -60,6 +60,11 @@
     private static final int CACHE_SIZE = 10;
 
     /**
+     * Special hash array value that indicates the container is immutable.
+     */
+    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
+
+    /**
      * @hide Special immutable empty ArrayMap.
      */
     public static final ArrayMap EMPTY = new ArrayMap(true);
@@ -75,11 +80,6 @@
     static Object[] mTwiceBaseCache;
     static int mTwiceBaseCacheSize;
 
-    /**
-     * Special hash array value that indicates the container is immutable.
-     */
-    static final int[] EMPTY_IMMUTABLE_INTS = new int[0];
-
     int[] mHashes;
     Object[] mArray;
     int mSize;
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 6816646..554d367 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1879,6 +1879,33 @@
     }
 
     /**
+     * Check if there are any pending messages with code 'what' in deferred messages queue.
+     */
+    protected final boolean hasDeferredMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        Iterator<Message> iterator = smh.mDeferredMessages.iterator();
+        while (iterator.hasNext()) {
+            Message msg = iterator.next();
+            if (msg.what == what) return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Check if there are any pending posts of messages with code 'what' in
+     * the message queue. This does NOT check messages in deferred message queue.
+     */
+    protected final boolean hasMessages(int what) {
+        SmHandler smh = mSmHandler;
+        if (smh == null) return false;
+
+        return smh.hasMessages(what);
+    }
+
+    /**
      * Validate that the message was sent by
      * {@link StateMachine#quit} or {@link StateMachine#quitNow}.
      * */
diff --git a/core/tests/benchmarks/Android.mk b/core/tests/benchmarks/Android.mk
new file mode 100644
index 0000000..b7b295a
--- /dev/null
+++ b/core/tests/benchmarks/Android.mk
@@ -0,0 +1,32 @@
+# -*- mode: makefile -*-
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+# build framework base core benchmarks
+# ============================================================
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := frameworks-base-core-benchmarks
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := $(call all-java-files-under, src/)
+LOCAL_NO_STANDARD_LIBRARIES := true
+
+LOCAL_JAVA_LIBRARIES := \
+  caliper-api-target \
+  framework
+
+include $(BUILD_JAVA_LIBRARY)
diff --git a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
index 1a50432..1b65603 100644
--- a/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/NetworkStatsBenchmark.java
@@ -16,10 +16,10 @@
 
 package android.net;
 
+import com.google.caliper.BeforeExperiment;
 import com.google.caliper.Param;
-import com.google.caliper.SimpleBenchmark;
 
-public class NetworkStatsBenchmark extends SimpleBenchmark {
+public class NetworkStatsBenchmark {
     private static final String UNDERLYING_IFACE = "wlan0";
     private static final String TUN_IFACE = "tun0";
     private static final int TUN_UID = 999999999;
@@ -28,10 +28,8 @@
     private int mSize;
     private NetworkStats mNetworkStats;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() throws Exception {
-        super.setUp();
-
         mNetworkStats = new NetworkStats(0, mSize + 2);
         int uid = 0;
         NetworkStats.Entry recycle = new NetworkStats.Entry();
diff --git a/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
index 5a29adc..09de412 100644
--- a/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
+++ b/core/tests/benchmarks/src/android/net/TrafficStatsBenchmark.java
@@ -16,9 +16,7 @@
 
 package android.net;
 
-import com.google.caliper.SimpleBenchmark;
-
-public class TrafficStatsBenchmark extends SimpleBenchmark {
+public class TrafficStatsBenchmark {
     public void timeGetUidRxBytes(int reps) {
         for (int i = 0; i < reps; i++) {
             TrafficStats.getUidRxBytes(android.os.Process.myUid());
diff --git a/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
index 21cfb09..eff8c8e 100644
--- a/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelArrayBenchmark.java
@@ -16,10 +16,11 @@
 
 package android.os;
 
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import com.google.caliper.Param;
-import com.google.caliper.SimpleBenchmark;
 
-public class ParcelArrayBenchmark extends SimpleBenchmark {
+public class ParcelArrayBenchmark {
 
     @Param({ "1", "10", "100", "1000" })
     private int mSize;
@@ -34,7 +35,7 @@
     private Parcel mIntParcel;
     private Parcel mLongParcel;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mWriteParcel = Parcel.obtain();
 
@@ -50,7 +51,7 @@
         mLongParcel.writeLongArray(mLongArray);
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mWriteParcel.recycle();
         mWriteParcel = null;
@@ -118,5 +119,4 @@
             mLongParcel.readLongArray(mLongArray);
         }
     }
-
 }
diff --git a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
index 6a7b7c89..4bd2d00 100644
--- a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java
@@ -16,18 +16,19 @@
 
 package android.os;
 
-import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 
-public class ParcelBenchmark extends SimpleBenchmark {
+public class ParcelBenchmark {
 
     private Parcel mParcel;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mParcel = Parcel.obtain();
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mParcel.recycle();
         mParcel = null;
diff --git a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
index 41af3820..a110906 100644
--- a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
+++ b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java
@@ -18,9 +18,7 @@
 
 import android.os.StrictMode.ThreadPolicy;
 
-import com.google.caliper.SimpleBenchmark;
-
-public class StrictModeBenchmark extends SimpleBenchmark {
+public class StrictModeBenchmark {
 
     private ThreadPolicy mOff = new ThreadPolicy.Builder().build();
     private ThreadPolicy mOn = new ThreadPolicy.Builder().detectAll().build();
diff --git a/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
index 2858128..028dd1d 100644
--- a/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
+++ b/core/tests/benchmarks/src/android/util/FloatMathBenchmark.java
@@ -15,13 +15,9 @@
  */
 package android.util;
 
-import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
 import android.util.FloatMath;
 
-public class FloatMathBenchmark extends SimpleBenchmark {
+public class FloatMathBenchmark {
 
     public float timeFloatMathCeil(int reps) {
         // Keep an answer so we don't optimize the method call away.
@@ -112,5 +108,4 @@
         }
         return f;
     }
-
 }
diff --git a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java b/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
index 2174be5..e62fbd6 100644
--- a/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
+++ b/core/tests/benchmarks/src/com/android/internal/net/NetworkStatsFactoryBenchmark.java
@@ -18,29 +18,31 @@
 
 import android.net.NetworkStats;
 import android.os.SystemClock;
-
-import com.google.caliper.SimpleBenchmark;
-
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import java.io.File;
 
-public class NetworkStatsFactoryBenchmark extends SimpleBenchmark {
+public class NetworkStatsFactoryBenchmark {
     private File mStats;
 
     // TODO: consider staging stats file with different number of rows
 
-    @Override
+    @BeforeExperiment
     protected void setUp() {
         mStats = new File("/proc/net/xt_qtaguid/stats");
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mStats = null;
     }
 
     public void timeReadNetworkStatsDetailJava(int reps) throws Exception {
         for (int i = 0; i < reps; i++) {
-            NetworkStatsFactory.javaReadNetworkStatsDetail(mStats, NetworkStats.UID_ALL);
+            NetworkStatsFactory.javaReadNetworkStatsDetail(mStats, NetworkStats.UID_ALL,
+                    // Looks like this was broken by change d0c5b9abed60b7bc056d026bf0f2b2235410fb70
+                    // Fixed compilation problem but needs addressing properly.
+                    new String[0], 999);
         }
     }
 
@@ -48,7 +50,10 @@
         for (int i = 0; i < reps; i++) {
             final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
             NetworkStatsFactory.nativeReadNetworkStatsDetail(
-                    stats, mStats.getAbsolutePath(), NetworkStats.UID_ALL);
+                    stats, mStats.getAbsolutePath(), NetworkStats.UID_ALL,
+                    // Looks like this was broken by change d0c5b9abed60b7bc056d026bf0f2b2235410fb70
+                    // Fixed compilation problem but needs addressing properly.
+                    new String[0], 999);
         }
     }
 }
diff --git a/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java b/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
index 34c73e8..1112d5c 100644
--- a/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
+++ b/core/tests/benchmarks/src/com/android/internal/util/IndentingPrintWriterBenchmark.java
@@ -17,15 +17,15 @@
 package com.android.internal.util;
 
 import com.google.android.collect.Lists;
-import com.google.caliper.SimpleBenchmark;
-
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 
-public class IndentingPrintWriterBenchmark extends SimpleBenchmark {
+public class IndentingPrintWriterBenchmark {
 
     private PrintWriter mDirect;
     private IndentingPrintWriter mIndenting;
@@ -33,7 +33,7 @@
     private Node mSimple;
     private Node mComplex;
 
-    @Override
+    @BeforeExperiment
     protected void setUp() throws IOException {
         final FileOutputStream os = new FileOutputStream(new File("/dev/null"));
         mDirect = new PrintWriter(os);
@@ -49,7 +49,7 @@
                 manyChildren);
     }
 
-    @Override
+    @AfterExperiment
     protected void tearDown() {
         mIndenting.close();
         mIndenting = null;
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index d98497b..0d1ee46 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -90,6 +90,9 @@
     protos/hwui.proto
 
 hwui_test_common_src_files := \
+    $(call all-cpp-files-under, tests/common/scenes) \
+    tests/common/TestContext.cpp \
+    tests/common/TestScene.cpp \
     tests/common/TestUtils.cpp
 
 hwui_cflags := \
@@ -259,12 +262,9 @@
 
 LOCAL_SRC_FILES += \
     $(hwui_test_common_src_files) \
-    tests/macrobench/TestContext.cpp \
     tests/macrobench/TestSceneRunner.cpp \
     tests/macrobench/main.cpp
 
-LOCAL_SRC_FILES += $(call all-cpp-files-under, tests/common/scenes)
-
 include $(BUILD_EXECUTABLE)
 
 # ------------------------
diff --git a/libs/hwui/tests/macrobench/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
similarity index 98%
rename from libs/hwui/tests/macrobench/TestContext.cpp
rename to libs/hwui/tests/common/TestContext.cpp
index ba763a8..146e735 100644
--- a/libs/hwui/tests/macrobench/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "TestContext.h"
+#include "tests/common/TestContext.h"
 
 namespace android {
 namespace uirenderer {
diff --git a/libs/hwui/tests/macrobench/TestContext.h b/libs/hwui/tests/common/TestContext.h
similarity index 100%
rename from libs/hwui/tests/macrobench/TestContext.h
rename to libs/hwui/tests/common/TestContext.h
diff --git a/libs/hwui/tests/common/TestScene.cpp b/libs/hwui/tests/common/TestScene.cpp
new file mode 100644
index 0000000..02bcd47
--- /dev/null
+++ b/libs/hwui/tests/common/TestScene.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tests/common/TestScene.h"
+
+namespace android {
+namespace uirenderer {
+namespace test {
+
+// Not a static global because we need to force the map to be constructed
+// before we try to add things to it.
+std::unordered_map<std::string, TestScene::Info>& TestScene::testMap() {
+    static std::unordered_map<std::string, TestScene::Info> testMap;
+    return testMap;
+}
+
+void TestScene::registerScene(const TestScene::Info& info) {
+    testMap()[info.name] = info;
+}
+
+} /* namespace test */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h
index b5d8954..df8d194 100644
--- a/libs/hwui/tests/common/TestScene.h
+++ b/libs/hwui/tests/common/TestScene.h
@@ -16,6 +16,9 @@
 #ifndef TESTS_TESTSCENE_H
 #define TESTS_TESTSCENE_H
 
+#include <string>
+#include <unordered_map>
+
 namespace android {
 namespace uirenderer {
 class RenderNode;
@@ -32,9 +35,40 @@
 
 class TestScene {
 public:
+    struct Options {
+        int count = 0;
+    };
+
+    template <class T>
+    static test::TestScene* simpleCreateScene(const TestScene::Options&) {
+        return new T();
+    }
+
+    typedef test::TestScene* (*CreateScene)(const TestScene::Options&);
+
+    struct Info {
+        std::string name;
+        std::string description;
+        CreateScene createScene;
+    };
+
+    class Registrar {
+    public:
+        Registrar(const TestScene::Info& info) {
+            TestScene::registerScene(info);
+        }
+    private:
+        Registrar() = delete;
+        Registrar(const Registrar&) = delete;
+        Registrar& operator=(const Registrar&) = delete;
+    };
+
     virtual ~TestScene() {}
     virtual void createContent(int width, int height, TestCanvas& renderer) = 0;
     virtual void doFrame(int frameNr) = 0;
+
+    static std::unordered_map<std::string, Info>& testMap();
+    static void registerScene(const Info& info);
 };
 
 } // namespace test
diff --git a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
index e316eca..c212df4 100644
--- a/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/HwLayerAnimation.cpp
@@ -18,11 +18,11 @@
 
 class HwLayerAnimation;
 
-static Benchmark _HwLayer(BenchmarkInfo{
+static TestScene::Registrar _HwLayer(TestScene::Info{
     "hwlayer",
     "A nested pair of nodes with LAYER_TYPE_HARDWARE set on each. "
     "Tests the hardware layer codepath.",
-    simpleCreateScene<HwLayerAnimation>
+    TestScene::simpleCreateScene<HwLayerAnimation>
 });
 
 class HwLayerAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index 6c64a32..43e247e 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -21,11 +21,11 @@
 
 class ListViewAnimation;
 
-static Benchmark _ListView(BenchmarkInfo{
+static TestScene::Registrar _ListView(TestScene::Info{
     "listview",
     "A mock ListView of scrolling content. Doesn't re-bind/re-record views as they are recycled, so"
     "won't upload much content (either glyphs, or bitmaps).",
-    simpleCreateScene<ListViewAnimation>
+    TestScene::simpleCreateScene<ListViewAnimation>
 });
 
 class ListViewAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/OvalAnimation.cpp b/libs/hwui/tests/common/scenes/OvalAnimation.cpp
index 936aba1..082c628 100644
--- a/libs/hwui/tests/common/scenes/OvalAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/OvalAnimation.cpp
@@ -18,10 +18,10 @@
 
 class OvalAnimation;
 
-static Benchmark _Oval(BenchmarkInfo{
+static TestScene::Registrar _Oval(TestScene::Info{
     "oval",
     "Draws 1 oval.",
-    simpleCreateScene<OvalAnimation>
+    TestScene::simpleCreateScene<OvalAnimation>
 });
 
 class OvalAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
index c31ddd1..84265a4 100644
--- a/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/PartialDamageAnimation.cpp
@@ -18,12 +18,12 @@
 
 class PartialDamageAnimation;
 
-static Benchmark _PartialDamage(BenchmarkInfo{
+static TestScene::Registrar _PartialDamage(TestScene::Info{
     "partialdamage",
     "Tests the partial invalidation path. Draws a grid of rects and animates 1 "
     "of them, should be low CPU & GPU load if EGL_EXT_buffer_age or "
     "EGL_KHR_partial_update is supported by the device & are enabled in hwui.",
-    simpleCreateScene<PartialDamageAnimation>
+    TestScene::simpleCreateScene<PartialDamageAnimation>
 });
 
 class PartialDamageAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 5d4ef96..6509edd 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -19,11 +19,11 @@
 
 class RecentsAnimation;
 
-static Benchmark _Recents(BenchmarkInfo{
+static TestScene::Registrar _Recents(TestScene::Info{
     "recents",
     "A recents-like scrolling list of textures. "
     "Consists of updating a texture every frame",
-    simpleCreateScene<RecentsAnimation>
+    TestScene::simpleCreateScene<RecentsAnimation>
 });
 
 class RecentsAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
index a1f04d6..a9293ab 100644
--- a/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RectGridAnimation.cpp
@@ -19,11 +19,11 @@
 
 class RectGridAnimation;
 
-static Benchmark _RectGrid(BenchmarkInfo{
+static TestScene::Registrar _RectGrid(TestScene::Info{
     "rectgrid",
     "A dense grid of 1x1 rects that should visually look like a single rect. "
     "Low CPU/GPU load.",
-    simpleCreateScene<RectGridAnimation>
+    TestScene::simpleCreateScene<RectGridAnimation>
 });
 
 class RectGridAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
index c73e97b..78fcd8b 100644
--- a/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SaveLayerAnimation.cpp
@@ -18,11 +18,11 @@
 
 class SaveLayerAnimation;
 
-static Benchmark _SaveLayer(BenchmarkInfo{
+static TestScene::Registrar _SaveLayer(TestScene::Info{
     "savelayer",
     "A nested pair of clipped saveLayer operations. "
     "Tests the clipped saveLayer codepath. Draws content into offscreen buffers and back again.",
-    simpleCreateScene<SaveLayerAnimation>
+    TestScene::simpleCreateScene<SaveLayerAnimation>
 });
 
 class SaveLayerAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
index 26c86aa..d3249b8 100644
--- a/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
+++ b/libs/hwui/tests/common/scenes/ShadowGrid2Animation.cpp
@@ -18,11 +18,11 @@
 
 class ShadowGrid2Animation;
 
-static Benchmark _ShadowGrid2(BenchmarkInfo{
+static TestScene::Registrar _ShadowGrid2(TestScene::Info{
     "shadowgrid2",
     "A dense grid of rounded rects that cast a shadow. This is a higher CPU load "
     "variant of shadowgrid. Very high CPU load, high GPU load.",
-    simpleCreateScene<ShadowGrid2Animation>
+    TestScene::simpleCreateScene<ShadowGrid2Animation>
 });
 
 class ShadowGrid2Animation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
index ee3c590..5ffedf0 100644
--- a/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShadowGridAnimation.cpp
@@ -18,11 +18,11 @@
 
 class ShadowGridAnimation;
 
-static Benchmark _ShadowGrid(BenchmarkInfo{
+static TestScene::Registrar _ShadowGrid(TestScene::Info{
     "shadowgrid",
     "A grid of rounded rects that cast a shadow. Simplified scenario of an "
     "Android TV-style launcher interface. High CPU/GPU load.",
-    simpleCreateScene<ShadowGridAnimation>
+    TestScene::simpleCreateScene<ShadowGridAnimation>
 });
 
 class ShadowGridAnimation : public TestScene {
diff --git a/libs/hwui/tests/common/scenes/TestSceneBase.h b/libs/hwui/tests/common/scenes/TestSceneBase.h
index 8a24149..ac78124 100644
--- a/libs/hwui/tests/common/scenes/TestSceneBase.h
+++ b/libs/hwui/tests/common/scenes/TestSceneBase.h
@@ -19,8 +19,7 @@
 #include "DisplayListCanvas.h"
 #include "RecordingCanvas.h"
 #include "RenderNode.h"
-#include "tests/macrobench/Benchmark.h"
-#include "tests/macrobench/TestContext.h"
+#include "tests/common/TestContext.h"
 #include "tests/common/TestScene.h"
 #include "tests/common/TestUtils.h"
 
diff --git a/libs/hwui/tests/macrobench/Benchmark.h b/libs/hwui/tests/macrobench/Benchmark.h
deleted file mode 100644
index aad8eb3..0000000
--- a/libs/hwui/tests/macrobench/Benchmark.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef TESTS_BENCHMARK_H
-#define TESTS_BENCHMARK_H
-
-#include "tests/common/TestScene.h"
-
-#include <string>
-#include <vector>
-
-namespace android {
-namespace uirenderer {
-
-struct BenchmarkOptions {
-    int count;
-};
-
-typedef test::TestScene* (*CreateScene)(const BenchmarkOptions&);
-
-template <class T>
-test::TestScene* simpleCreateScene(const BenchmarkOptions&) {
-    return new T();
-}
-
-struct BenchmarkInfo {
-    std::string name;
-    std::string description;
-    CreateScene createScene;
-};
-
-class Benchmark {
-public:
-    Benchmark(const BenchmarkInfo& info) {
-        registerBenchmark(info);
-    }
-
-private:
-    Benchmark() = delete;
-    Benchmark(const Benchmark&) = delete;
-    Benchmark& operator=(const Benchmark&) = delete;
-
-    static void registerBenchmark(const BenchmarkInfo& info);
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif /* TESTS_BENCHMARK_H */
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 1e1c6a1..8261220 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -15,9 +15,9 @@
  */
 
 #include "AnimationContext.h"
-#include "Benchmark.h"
 #include "RenderNode.h"
-#include "TestContext.h"
+#include "tests/common/TestContext.h"
+#include "tests/common/TestScene.h"
 #include "tests/common/scenes/TestSceneBase.h"
 #include "renderthread/RenderProxy.h"
 #include "renderthread/RenderTask.h"
@@ -38,7 +38,7 @@
     }
 };
 
-void run(const BenchmarkInfo& info, const BenchmarkOptions& opts) {
+void run(const TestScene::Info& info, const TestScene::Options& opts) {
     // Switch to the real display
     gDisplay = getBuiltInDisplay();
 
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index 48566e8..619713c 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "Benchmark.h"
+#include "tests/common/TestScene.h"
 
 #include "protos/hwui.pb.h"
 
@@ -27,23 +27,13 @@
 
 using namespace android;
 using namespace android::uirenderer;
-
-// Not a static global because we need to force the map to be constructed
-// before we try to add things to it.
-std::unordered_map<std::string, BenchmarkInfo>& testMap() {
-    static std::unordered_map<std::string, BenchmarkInfo> testMap;
-    return testMap;
-}
-
-void Benchmark::registerBenchmark(const BenchmarkInfo& info) {
-    testMap()[info.name] = info;
-}
+using namespace android::uirenderer::test;
 
 static int gFrameCount = 150;
 static int gRepeatCount = 1;
-static std::vector<BenchmarkInfo> gRunTests;
+static std::vector<TestScene::Info> gRunTests;
 
-void run(const BenchmarkInfo& info, const BenchmarkOptions& opts);
+void run(const TestScene::Info& info, const TestScene::Options& opts);
 
 static void printHelp() {
     printf("\
@@ -59,7 +49,7 @@
 
 static void listTests() {
     printf("Tests: \n");
-    for (auto&& test : testMap()) {
+    for (auto&& test : TestScene::testMap()) {
         auto&& info = test.second;
         const char* col1 = info.name.c_str();
         int dlen = info.description.length();
@@ -168,8 +158,8 @@
     if (optind < argc) {
         do {
             const char* test = argv[optind++];
-            auto pos = testMap().find(test);
-            if (pos == testMap().end()) {
+            auto pos = TestScene::testMap().find(test);
+            if (pos == TestScene::testMap().end()) {
                 fprintf(stderr, "Unknown test '%s'\n", test);
                 exit(EXIT_FAILURE);
             } else {
@@ -177,14 +167,14 @@
             }
         } while (optind < argc);
     } else {
-        gRunTests.push_back(testMap()["shadowgrid"]);
+        gRunTests.push_back(TestScene::testMap()["shadowgrid"]);
     }
 }
 
 int main(int argc, char* argv[]) {
     parseOptions(argc, argv);
 
-    BenchmarkOptions opts;
+    TestScene::Options opts;
     opts.count = gFrameCount;
     for (int i = 0; i < gRepeatCount; i++) {
         for (auto&& test : gRunTests) {
diff --git a/libs/hwui/tests/microbench/OpReordererBench.cpp b/libs/hwui/tests/microbench/OpReordererBench.cpp
index ac2b15c..6bfe5a9 100644
--- a/libs/hwui/tests/microbench/OpReordererBench.cpp
+++ b/libs/hwui/tests/microbench/OpReordererBench.cpp
@@ -23,6 +23,8 @@
 #include "OpReorderer.h"
 #include "RecordedOp.h"
 #include "RecordingCanvas.h"
+#include "tests/common/TestContext.h"
+#include "tests/common/TestScene.h"
 #include "tests/common/TestUtils.h"
 #include "Vector.h"
 #include "tests/microbench/MicroBench.h"
@@ -31,6 +33,8 @@
 
 using namespace android;
 using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+using namespace android::uirenderer::test;
 
 const LayerUpdateQueue sEmptyLayerUpdateQueue;
 const Vector3 sLightCenter = {100, 100, 100};
@@ -71,7 +75,7 @@
 
 BENCHMARK_NO_ARG(BM_OpReorderer_deferAndRender);
 void BM_OpReorderer_deferAndRender::Run(int iters) {
-    TestUtils::runOnRenderThread([this, iters](renderthread::RenderThread& thread) {
+    TestUtils::runOnRenderThread([this, iters](RenderThread& thread) {
         auto nodes = createTestNodeList();
         BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 };
 
@@ -90,3 +94,67 @@
         StopBenchmarkTiming();
     });
 }
+
+static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) {
+    gDisplay = getBuiltInDisplay(); // switch to real display if present
+
+    TestContext testContext;
+    TestScene::Options opts;
+    std::unique_ptr<TestScene> scene(TestScene::testMap()[sceneName].createScene(opts));
+
+    sp<RenderNode> rootNode = TestUtils::createNode(0, 0, gDisplay.w, gDisplay.h,
+                [&scene](RenderProperties& props, TestCanvas& canvas) {
+            scene->createContent(gDisplay.w, gDisplay.h, canvas);
+    });
+
+    TestUtils::syncHierarchyPropertiesAndDisplayList(rootNode);
+    std::vector<sp<RenderNode>> nodes;
+    nodes.emplace_back(rootNode);
+    return nodes;
+}
+
+static void benchDeferScene(testing::Benchmark& benchmark, int iters, const char* sceneName) {
+    auto nodes = getSyncedSceneNodes(sceneName);
+    benchmark.StartBenchmarkTiming();
+    for (int i = 0; i < iters; i++) {
+        OpReorderer reorderer(sEmptyLayerUpdateQueue,
+                SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
+                nodes, sLightCenter);
+        MicroBench::DoNotOptimize(&reorderer);
+    }
+    benchmark.StopBenchmarkTiming();
+}
+
+static void benchDeferAndRenderScene(testing::Benchmark& benchmark,
+        int iters, const char* sceneName) {
+    TestUtils::runOnRenderThread([&benchmark, iters, sceneName](RenderThread& thread) {
+        auto nodes = getSyncedSceneNodes(sceneName);
+        BakedOpRenderer::LightInfo lightInfo = {50.0f, 128, 128 }; // TODO!
+
+        RenderState& renderState = thread.renderState();
+        Caches& caches = Caches::getInstance();
+
+        benchmark.StartBenchmarkTiming();
+        for (int i = 0; i < iters; i++) {
+            OpReorderer reorderer(sEmptyLayerUpdateQueue,
+                    SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h,
+                    nodes, sLightCenter);
+
+            BakedOpRenderer renderer(caches, renderState, true, lightInfo);
+            reorderer.replayBakedOps<BakedOpDispatcher>(renderer);
+            MicroBench::DoNotOptimize(&renderer);
+        }
+        benchmark.StopBenchmarkTiming();
+    });
+}
+
+BENCHMARK_NO_ARG(BM_OpReorderer_listview_defer);
+void BM_OpReorderer_listview_defer::Run(int iters) {
+    benchDeferScene(*this, iters, "listview");
+}
+
+BENCHMARK_NO_ARG(BM_OpReorderer_listview_deferAndRender);
+void BM_OpReorderer_listview_deferAndRender::Run(int iters) {
+    benchDeferAndRenderScene(*this, iters, "listview");
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index a0a1bac..7ae686e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -411,6 +411,8 @@
             RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
             if (launchState.launchedViaDragGesture) {
                 setTranslationY(getMeasuredHeight());
+            } else {
+                setTranslationY(0f);
             }
         }
     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f65dba1..d94e5f4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -34,7 +34,6 @@
 import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
 import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
 import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
-import static android.content.pm.PackageManager.INSTALL_FAILED_DEXOPT;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
 import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
@@ -94,8 +93,6 @@
 import android.app.IActivityManager;
 import android.app.admin.IDevicePolicyManager;
 import android.app.backup.IBackupManager;
-import android.app.usage.UsageStats;
-import android.app.usage.UsageStatsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -16842,13 +16839,11 @@
             mPendingBroadcasts.remove(userHandle);
         }
         synchronized (mInstallLock) {
-            if (mInstaller != null) {
-                final StorageManager storage = mContext.getSystemService(StorageManager.class);
-                for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
-                    final String volumeUuid = vol.getFsUuid();
-                    if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
-                    mInstaller.removeUserDataDirs(volumeUuid, userHandle);
-                }
+            final StorageManager storage = mContext.getSystemService(StorageManager.class);
+            for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
+                final String volumeUuid = vol.getFsUuid();
+                if (DEBUG_INSTALL) Slog.d(TAG, "Removing user data on volume " + volumeUuid);
+                mInstaller.removeUserDataDirs(volumeUuid, userHandle);
             }
             synchronized (mPackages) {
                 removeUnusedPackagesLILPw(userManager, userHandle);
@@ -16910,17 +16905,13 @@
 
     /** Called by UserManagerService */
     void createNewUser(int userHandle) {
-        if (mInstaller != null) {
-            synchronized (mInstallLock) {
-                synchronized (mPackages) {
-                    mInstaller.createUserConfig(userHandle);
-                    mSettings.createNewUserLILPw(this, mInstaller, userHandle);
-                }
-            }
-            synchronized (mPackages) {
-                applyFactoryDefaultBrowserLPw(userHandle);
-                primeDomainVerificationsLPw(userHandle);
-            }
+        synchronized (mInstallLock) {
+            mInstaller.createUserConfig(userHandle);
+            mSettings.createNewUserLI(this, mInstaller, userHandle);
+        }
+        synchronized (mPackages) {
+            applyFactoryDefaultBrowserLPw(userHandle);
+            primeDomainVerificationsLPw(userHandle);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 99aa30b..22f8e96 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3644,21 +3644,47 @@
         }
     }
 
-    void createNewUserLILPw(PackageManagerService service, Installer installer, int userHandle) {
-        for (PackageSetting ps : mPackages.values()) {
-            if (ps.pkg == null || ps.pkg.applicationInfo == null) {
+    void createNewUserLI(@NonNull PackageManagerService service, @NonNull Installer installer,
+            int userHandle) {
+        String[] volumeUuids;
+        String[] names;
+        int[] uids;
+        String[] seinfos;
+        int packagesCount;
+        synchronized (mPackages) {
+            Collection<PackageSetting> packages = mPackages.values();
+            packagesCount = packages.size();
+            volumeUuids = new String[packagesCount];
+            names = new String[packagesCount];
+            uids = new int[packagesCount];
+            seinfos = new String[packagesCount];
+            Iterator<PackageSetting> packagesIterator = packages.iterator();
+            for (int i = 0; i < packagesCount; i++) {
+                PackageSetting ps = packagesIterator.next();
+                if (ps.pkg == null || ps.pkg.applicationInfo == null) {
+                    continue;
+                }
+                // Only system apps are initially installed.
+                ps.setInstalled(ps.isSystem(), userHandle);
+                // Need to create a data directory for all apps under this user. Accumulate all
+                // required args and call the installer after mPackages lock has been released
+                volumeUuids[i] = ps.volumeUuid;
+                names[i] = ps.name;
+                uids[i] = UserHandle.getUid(userHandle, ps.appId);
+                seinfos[i] = ps.pkg.applicationInfo.seinfo;
+            }
+        }
+        for (int i = 0; i < packagesCount; i++) {
+            if (names[i] == null) {
                 continue;
             }
-            // Only system apps are initially installed.
-            ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
-            // Need to create a data directory for all apps under this user.
-            installer.createUserData(ps.volumeUuid, ps.name,
-                    UserHandle.getUid(userHandle, ps.appId), userHandle,
-                    ps.pkg.applicationInfo.seinfo);
+            installer.createUserData(volumeUuids[i], names[i], uids[i], userHandle, seinfos[i]);
         }
-        applyDefaultPreferredAppsLPw(service, userHandle);
-        writePackageRestrictionsLPr(userHandle);
-        writePackageListLPr(userHandle);
+        synchronized (mPackages) {
+            applyDefaultPreferredAppsLPw(service, userHandle);
+            writePackageRestrictionsLPr(userHandle);
+            writePackageListLPr(userHandle);
+        }
     }
 
     void removeUserLPw(int userId) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index c7f3d0a..12b36b2 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -673,12 +673,15 @@
     @Nullable
     public PersistableBundle getConfigForSubId(int subId) {
         try {
-            return getICarrierConfigLoader().getConfigForSubId(subId);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error getting config for subId " + subId
+                        + " ICarrierConfigLoader is null");
+                return null;
+            }
+            return loader.getConfigForSubId(subId);
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
-                    + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error getting config for subId " + Integer.toString(subId) + ": "
+            Rlog.e(TAG, "Error getting config for subId " + subId + ": "
                     + ex.toString());
         }
         return null;
@@ -714,11 +717,15 @@
      */
     public void notifyConfigChangedForSubId(int subId) {
         try {
-            getICarrierConfigLoader().notifyConfigChangedForSubId(subId);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error reloading config for subId=" + subId
+                        + " ICarrierConfigLoader is null");
+                return;
+            }
+            loader.notifyConfigChangedForSubId(subId);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error reloading config for subId=" + subId + ": " + ex.toString());
         }
     }
 
@@ -734,11 +741,15 @@
     @SystemApi
     public void updateConfigForPhoneId(int phoneId, String simState) {
         try {
-            getICarrierConfigLoader().updateConfigForPhoneId(phoneId, simState);
+            ICarrierConfigLoader loader = getICarrierConfigLoader();
+            if (loader == null) {
+                Rlog.w(TAG, "Error updating config for phoneId=" + phoneId
+                        + " ICarrierConfigLoader is null");
+                return;
+            }
+            loader.updateConfigForPhoneId(phoneId, simState);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
-        } catch (NullPointerException ex) {
-            Rlog.e(TAG, "Error updating config for phoneId=" + phoneId + ": " + ex.toString());
         }
     }
 
@@ -754,6 +765,7 @@
     }
 
     /** @hide */
+    @Nullable
     private ICarrierConfigLoader getICarrierConfigLoader() {
         return ICarrierConfigLoader.Stub
                 .asInterface(ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE));
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index c29bb48..c449550 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -127,6 +127,12 @@
     const android::String8& getPlatformBuildVersionName() { return mPlatformVersionName; }
     void setPlatformBuildVersionName(const android::String8& name) { mPlatformVersionName = name; }
 
+    const android::String8& getPrivateSymbolsPackage() const { return mPrivateSymbolsPackage; }
+
+    void setPrivateSymbolsPackage(const android::String8& package) {
+        mPrivateSymbolsPackage = package;
+    }
+
     bool getUTF16StringsOption() {
         return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
     }
@@ -333,6 +339,7 @@
     bool        mBuildAppAsSharedLibrary;
     android::String8 mPlatformVersionCode;
     android::String8 mPlatformVersionName;
+    android::String8 mPrivateSymbolsPackage;
 
     /* file specification */
     int         mArgc;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 6411286..c424cc5 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -220,7 +220,9 @@
         "       Prevents symbols from being generated for strings that do not have a default\n"
         "       localization\n"
         "   --no-version-vectors\n"
-        "       Do not automatically generate versioned copies of vector XML resources.\n",
+        "       Do not automatically generate versioned copies of vector XML resources.\n"
+        "   --private-symbols\n"
+        "       Java package name to use when generating R.java for private resources.\n",
         gDefaultIgnoreAssets);
 }
 
@@ -689,6 +691,16 @@
                     bundle.setPseudolocalize(PSEUDO_ACCENTED | PSEUDO_BIDI);
                 } else if (strcmp(cp, "-no-version-vectors") == 0) {
                     bundle.setNoVersionVectors(true);
+                } else if (strcmp(cp, "-private-symbols") == 0) {
+                    argc--;
+                    argv++;
+                    if (!argc) {
+                        fprintf(stderr, "ERROR: No argument supplied for "
+                                "'--private-symbols' option\n");
+                        wantUsage = true;
+                        goto bail;
+                    }
+                    bundle.setPrivateSymbolsPackage(String8(argv[0]));
                 } else {
                     fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
                     wantUsage = true;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index fb0fe38..576f076 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1161,6 +1161,12 @@
         printf("Creating resources for package %s\n", assets->getPackage().string());
     }
 
+    // Set the private symbols package if it was declared.
+    // This can also be declared in XML as <private-symbols name="package" />
+    if (bundle->getPrivateSymbolsPackage().size() != 0) {
+        assets->setSymbolsPrivatePackage(bundle->getPrivateSymbolsPackage());
+    }
+
     ResourceTable::PackageType packageType = ResourceTable::App;
     if (bundle->getBuildSharedLibrary()) {
         packageType = ResourceTable::SharedLibrary;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 0e470d9..e87c7d4 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1141,7 +1141,15 @@
                 }
                 pkg = String16(block.getAttributeStringValue(pkgIdx, &len));
                 if (!localHasErrors) {
-                    assets->setSymbolsPrivatePackage(String8(pkg));
+                    SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+                            "<private-symbols> is deprecated. Use the command line flag "
+                            "--private-symbols instead.\n");
+                    if (assets->havePrivateSymbols()) {
+                        SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+                                "private symbol package already specified. Ignoring...\n");
+                    } else {
+                        assets->setSymbolsPrivatePackage(String8(pkg));
+                    }
                 }
 
                 while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {