diff options
38 files changed, 385 insertions, 194 deletions
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index f2aea08a91ec..8d035b738a72 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -61,12 +61,12 @@ import dalvik.system.VMRuntime; * 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 @@ import dalvik.system.VMRuntime; * {@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 @@ import dalvik.system.VMRuntime; * <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 @@ import dalvik.system.VMRuntime; * 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 @@ import dalvik.system.VMRuntime; * 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 @@ import dalvik.system.VMRuntime; * 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 @@ import dalvik.system.VMRuntime; * {@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 @@ import dalvik.system.VMRuntime; * 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 @@ public final class Parcel { 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 @@ public final class Parcel { * 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 @@ public final class Parcel { } 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 @@ public final class Parcel { * 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 @@ public final class Parcel { * <li>{@link SecurityException} * <li>{@link NetworkOnMainThreadException} * </ul> - * + * * @param e The Exception to be written. * * @see #writeNoException @@ -1835,7 +1839,7 @@ public final class Parcel { 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 @@ public final class Parcel { return readArrayList(loader); case VAL_BOOLEANARRAY: - return createBooleanArray(); + return createBooleanArray(); case VAL_BYTEARRAY: return createByteArray(); @@ -2396,6 +2400,9 @@ public final class Parcel { 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 4ee9807da850..bdb1fdcb9ff8 100644 --- a/core/java/android/util/ArrayMap.java +++ b/core/java/android/util/ArrayMap.java @@ -60,6 +60,11 @@ public final class ArrayMap<K, V> implements Map<K, V> { 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 @@ public final class ArrayMap<K, V> implements Map<K, V> { 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 68166467c3a9..554d367f6cea 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -1879,6 +1879,33 @@ public class StateMachine { } /** + * 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 000000000000..b7b295aeca99 --- /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 1a5043254e09..1b6560322a13 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 @@ public class NetworkStatsBenchmark extends SimpleBenchmark { 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 5a29adc9b000..09de412b5560 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 21cfb0988ebd..eff8c8e4abdf 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 @@ public class ParcelArrayBenchmark extends SimpleBenchmark { private Parcel mIntParcel; private Parcel mLongParcel; - @Override + @BeforeExperiment protected void setUp() { mWriteParcel = Parcel.obtain(); @@ -50,7 +51,7 @@ public class ParcelArrayBenchmark extends SimpleBenchmark { mLongParcel.writeLongArray(mLongArray); } - @Override + @AfterExperiment protected void tearDown() { mWriteParcel.recycle(); mWriteParcel = null; @@ -118,5 +119,4 @@ public class ParcelArrayBenchmark extends SimpleBenchmark { mLongParcel.readLongArray(mLongArray); } } - } diff --git a/core/tests/benchmarks/src/android/os/ParcelBenchmark.java b/core/tests/benchmarks/src/android/os/ParcelBenchmark.java index 6a7b7c890edb..4bd2d009dcf3 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 41af382071ca..a1109062303b 100644 --- a/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java +++ b/core/tests/benchmarks/src/android/os/StrictModeBenchmark.java @@ -18,9 +18,7 @@ package android.os; 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 2858128b3c8d..028dd1d14a18 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 @@ public class FloatMathBenchmark extends SimpleBenchmark { } 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 2174be5dc0a3..e62fbd6568f7 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 @@ package com.android.internal.net; 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 @@ public class NetworkStatsFactoryBenchmark extends SimpleBenchmark { 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 34c73e831923..1112d5c40e95 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 @@ public class IndentingPrintWriterBenchmark extends SimpleBenchmark { 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 @@ public class IndentingPrintWriterBenchmark extends SimpleBenchmark { manyChildren); } - @Override + @AfterExperiment protected void tearDown() { mIndenting.close(); mIndenting = null; diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index d98497bc046b..0d1ee46712ee 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -90,6 +90,9 @@ hwui_src_files := \ 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_WHOLE_STATIC_LIBRARIES := libhwui_static 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 index ba763a8def62..146e735839d1 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 index 2bbe5dffd9b8..2bbe5dffd9b8 100644 --- a/libs/hwui/tests/macrobench/TestContext.h +++ b/libs/hwui/tests/common/TestContext.h diff --git a/libs/hwui/tests/macrobench/Benchmark.h b/libs/hwui/tests/common/TestScene.cpp index aad8eb3716a6..02bcd4768a65 100644 --- a/libs/hwui/tests/macrobench/Benchmark.h +++ b/libs/hwui/tests/common/TestScene.cpp @@ -13,49 +13,24 @@ * 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 { +namespace test { -struct BenchmarkOptions { - int count; -}; - -typedef test::TestScene* (*CreateScene)(const BenchmarkOptions&); - -template <class T> -test::TestScene* simpleCreateScene(const BenchmarkOptions&) { - return new T(); +// 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; } -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); -}; +void TestScene::registerScene(const TestScene::Info& info) { + testMap()[info.name] = info; +} +} /* namespace test */ } /* namespace uirenderer */ } /* namespace android */ - -#endif /* TESTS_BENCHMARK_H */ diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h index b5d8954652a3..df8d194f641b 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 @@ namespace test { 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 e316eca79be8..c212df4f978d 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 6c64a327013e..43e247e68bc0 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 936aba184c88..082c6287e86f 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 c31ddd1d531b..84265a4774a5 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 5d4ef9663d34..6509edd4077f 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 a1f04d67c785..a9293ab244dd 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 c73e97ba003c..78fcd8bf30ac 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 26c86aa6f9d5..d3249b8f585a 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 ee3c590c4e0d..5ffedf09bc70 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 8a2414971515..ac781243c25e 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/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp index 1e1c6a1e318a..82612206cac8 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 @@ public: } }; -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 48566e8f6ecd..619713c58c9a 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 @@ OPTIONS:\n\ 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 @@ void parseOptions(int argc, char* argv[]) { 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 @@ void parseOptions(int argc, char* argv[]) { } } 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 ac2b15cc620a..6bfe5a9a1028 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 @@ void BM_OpReorderer_defer::Run(int iters) { 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 @@ void BM_OpReorderer_deferAndRender::Run(int iters) { 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 a0a1baccfe64..7ae686e42602 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 f65dba1fc2f9..d94e5f491f75 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.FLAG_PERMISSION_USER_SET; 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.AppGlobals; 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { /** 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 99aa30bed5a9..22f8e96ce69d 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 @@ final class Settings { } } - 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]); + } + synchronized (mPackages) { + applyDefaultPreferredAppsLPw(service, userHandle); + writePackageRestrictionsLPr(userHandle); + writePackageListLPr(userHandle); } - 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 c7f3d0a86e11..12b36b2425f8 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -673,12 +673,15 @@ public class CarrierConfigManager { @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 class CarrierConfigManager { */ 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 @@ public class CarrierConfigManager { @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 @@ public class CarrierConfigManager { } /** @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 c29bb482c159..c4495509614e 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -127,6 +127,12 @@ public: 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 @@ private: 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 64112867a4b4..c424cc516b56 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -220,7 +220,9 @@ void usage(void) " 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 @@ int main(int argc, char* const argv[]) 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 fb0fe38da1ff..576f076f4a3f 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1161,6 +1161,12 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets, sp<ApkBuil 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 0e470d924f5a..e87c7d40f1d4 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -1141,7 +1141,15 @@ status_t compileResourceFile(Bundle* bundle, } 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) { |