summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/statsd/Android.mk15
-rw-r--r--cmds/statsd/src/matchers/LogEntryMatcherManager.cpp182
-rw-r--r--cmds/statsd/src/matchers/LogEntryMatcherManager.h60
-rw-r--r--cmds/statsd/src/statsd_config.proto19
-rw-r--r--cmds/statsd/tests/LogEntryMatcher_test.cpp366
-rw-r--r--config/compiled-classes-phone4
-rw-r--r--config/preloaded-classes4
-rw-r--r--core/java/android/animation/AnimatorSet.java5
-rw-r--r--core/java/android/app/Notification.java39
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java23
-rwxr-xr-xcore/java/android/bluetooth/BluetoothClass.java46
-rw-r--r--core/java/android/text/Layout.java3
-rw-r--r--core/java/android/text/StaticLayout.java76
-rw-r--r--core/java/android/widget/RemoteViews.java476
-rw-r--r--core/jni/android_text_StaticLayout.cpp50
-rw-r--r--core/proto/android/os/incident.proto5
-rw-r--r--core/res/res/values/strings.xml7
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--graphics/java/android/graphics/Shader.java6
-rw-r--r--libs/hwui/pipeline/skia/LayerDrawable.cpp40
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java1117
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java30
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java52
-rw-r--r--tools/aapt2/Android.bp1
-rw-r--r--tools/aapt2/ConfigDescription.cpp6
-rw-r--r--tools/aapt2/ConfigDescription.h3
-rw-r--r--tools/aapt2/Configuration.proto207
-rw-r--r--tools/aapt2/Locale.cpp137
-rw-r--r--tools/aapt2/Locale.h5
-rw-r--r--tools/aapt2/Resources.proto12
-rw-r--r--tools/aapt2/ResourcesInternal.proto3
-rw-r--r--tools/aapt2/proto/ProtoHelpers.cpp510
-rw-r--r--tools/aapt2/proto/ProtoHelpers.h9
-rw-r--r--tools/aapt2/proto/TableProtoDeserializer.cpp10
-rw-r--r--tools/aapt2/proto/TableProtoSerializer.cpp12
-rw-r--r--tools/aapt2/proto/TableProtoSerializer_test.cpp94
41 files changed, 2433 insertions, 1250 deletions
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index b9ee7ff201d5..3f120166d974 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -54,6 +54,7 @@ LOCAL_SRC_FILES := \
src/statsd_config.proto \
src/stats_constants.proto \
src/DropboxReader.cpp \
+ src/matchers/LogEntryMatcherManager.cpp \
LOCAL_CFLAGS += \
@@ -107,6 +108,9 @@ LOCAL_MODULE := statsd_test
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_MODULE_TAGS := tests
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \
+ STATSD_PROTO_INCLUDES
+
LOCAL_CFLAGS += \
-Wall \
-Werror \
@@ -115,21 +119,24 @@ LOCAL_CFLAGS += \
-Wno-unused-function \
-Wno-unused-parameter
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src \
- STATSD_PROTO_INCLUDES
-
LOCAL_SRC_FILES := \
+ src/stats_log.proto \
+ src/statsd_config.proto \
+ src/stats_constants.proto \
../../core/java/android/os/IStatsCompanionService.aidl \
../../core/java/android/os/IStatsManager.aidl \
src/StatsService.cpp \
tests/indexed_priority_queue_test.cpp \
+ src/parse_util.cpp \
src/LogEntryPrinter.cpp \
src/LogReader.cpp \
+ src/matchers/LogEntryMatcherManager.cpp \
tests/LogReader_test.cpp \
+ tests/LogEntryMatcher_test.cpp \
LOCAL_STATIC_LIBRARIES := \
libgmock \
- statsd_proto
+ statsd_proto \
LOCAL_SHARED_LIBRARIES := \
libbase \
diff --git a/cmds/statsd/src/matchers/LogEntryMatcherManager.cpp b/cmds/statsd/src/matchers/LogEntryMatcherManager.cpp
new file mode 100644
index 000000000000..bb0951ce4fab
--- /dev/null
+++ b/cmds/statsd/src/matchers/LogEntryMatcherManager.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2017 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 "LogEntryMatcherManager.h"
+#include <log/event_tag_map.h>
+#include <log/logprint.h>
+#include <utils/Errors.h>
+#include <cutils/log.h>
+#include <unordered_map>
+#include <frameworks/base/cmds/statsd/src/statsd_config.pb.h>
+
+using std::unordered_map;
+using std::string;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+bool LogEntryMatcherManager::matches(const LogEntryMatcher &matcher, const int tagId,
+ const unordered_map<int, long> &intMap,
+ const unordered_map<int, string> &strMap,
+ const unordered_map<int, float> &floatMap,
+ const unordered_map<int, bool> &boolMap) {
+ if (matcher.has_combination()) { // Need to evaluate composite matching
+ switch (matcher.combination().operation()) {
+ case LogicalOperation::AND:
+ for (auto nestedMatcher : matcher.combination().matcher()) {
+ if (!matches(nestedMatcher, tagId, intMap, strMap, floatMap, boolMap)) {
+ return false; // return false if any nested matcher is false;
+ }
+ }
+ return true; // Otherwise, return true.
+ case LogicalOperation::OR:
+ for (auto nestedMatcher : matcher.combination().matcher()) {
+ if (matches(nestedMatcher, tagId, intMap, strMap, floatMap, boolMap)) {
+ return true; // return true if any nested matcher is true;
+ }
+ }
+ return false;
+ case LogicalOperation::NOT:
+ return !matches(matcher.combination().matcher(0), tagId, intMap, strMap, floatMap,
+ boolMap);
+
+ // Case NAND is just inverting the return statement of AND
+ case LogicalOperation::NAND:
+ for (auto nestedMatcher : matcher.combination().matcher()) {
+ auto simple = nestedMatcher.simple_log_entry_matcher();
+ if (!matches(nestedMatcher, tagId, intMap, strMap, floatMap, boolMap)) {
+ return true; // return false if any nested matcher is false;
+ }
+ }
+ return false; // Otherwise, return true.
+ case LogicalOperation::NOR:
+ for (auto nestedMatcher : matcher.combination().matcher()) {
+ if (matches(nestedMatcher, tagId, intMap, strMap, floatMap, boolMap)) {
+ return false; // return true if any nested matcher is true;
+ }
+ }
+ return true;
+ }
+ return false;
+ } else {
+ return matchesSimple(matcher.simple_log_entry_matcher(), tagId, intMap, strMap, floatMap,
+ boolMap);
+ }
+}
+
+bool LogEntryMatcherManager::matchesSimple(const SimpleLogEntryMatcher &simpleMatcher,
+ const int tagId,
+ const unordered_map<int, long> &intMap,
+ const unordered_map<int, string> &strMap,
+ const unordered_map<int, float> &floatMap,
+ const unordered_map<int, bool> &boolMap) {
+ for (int i = 0; i < simpleMatcher.tag_size(); i++) {
+ if (simpleMatcher.tag(i) != tagId) {
+ continue;
+ }
+
+ // now see if this event is interesting to us -- matches ALL the matchers
+ // defined in the metrics.
+ bool allMatched = true;
+ for (int j = 0; j < simpleMatcher.key_value_matcher_size(); j++) {
+ auto cur = simpleMatcher.key_value_matcher(j);
+
+ // TODO: Check if this key is a magic key (eg package name).
+ int key = cur.key_matcher().key();
+
+ switch (cur.value_matcher_case()) {
+ case KeyValueMatcher::ValueMatcherCase::kEqString: {
+ auto it = strMap.find(key);
+ if (it == strMap.end() || cur.eq_string().compare(it->second) != 0) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kEqInt: {
+ auto it = intMap.find(key);
+ if (it == intMap.end() || cur.eq_int() != it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kEqBool: {
+ auto it = boolMap.find(key);
+ if (it == boolMap.end() || cur.eq_bool() != it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ // Begin numeric comparisons
+ case KeyValueMatcher::ValueMatcherCase::kLtInt: {
+ auto it = intMap.find(key);
+ if (it == intMap.end() || cur.lt_int() <= it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kGtInt: {
+ auto it = intMap.find(key);
+ if (it == intMap.end() || cur.gt_int() >= it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kLtFloat: {
+ auto it = floatMap.find(key);
+ if (it == floatMap.end() || cur.lt_float() <= it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kGtFloat: {
+ auto it = floatMap.find(key);
+ if (it == floatMap.end() || cur.gt_float() >= it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ // Begin comparisons with equality
+ case KeyValueMatcher::ValueMatcherCase::kLteInt: {
+ auto it = intMap.find(key);
+ if (it == intMap.end() || cur.lte_int() < it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::kGteInt: {
+ auto it = intMap.find(key);
+ if (it == intMap.end() || cur.gte_int() > it->second) {
+ allMatched = false;
+ }
+ break;
+ }
+ case KeyValueMatcher::ValueMatcherCase::VALUE_MATCHER_NOT_SET:
+ // If value matcher is not present, assume that we match.
+ break;
+ }
+ }
+
+ if (allMatched) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android
diff --git a/cmds/statsd/src/matchers/LogEntryMatcherManager.h b/cmds/statsd/src/matchers/LogEntryMatcherManager.h
new file mode 100644
index 000000000000..10ac0e2e9145
--- /dev/null
+++ b/cmds/statsd/src/matchers/LogEntryMatcherManager.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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 LOG_ENTRY_MATCHER_MANAGER_H
+#define LOG_ENTRY_MATCHER_MANAGER_H
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include <log/logprint.h>
+#include <log/log_read.h>
+#include <set>
+#include <vector>
+#include <unordered_map>
+
+using std::unordered_map;
+using std::string;
+
+namespace android {
+namespace os {
+namespace statsd {
+
+/**
+ * Keeps track per log entry which simple log entry matchers match.
+ */
+class LogEntryMatcherManager {
+public:
+ LogEntryMatcherManager();
+
+ ~LogEntryMatcherManager() {};
+
+ static bool matches(const LogEntryMatcher &matcher, const int tagId,
+ const unordered_map<int, long> &intMap,
+ const unordered_map<int, string> &strMap,
+ const unordered_map<int, float> &floatMap,
+ const unordered_map<int, bool> &boolMap);
+
+ static bool matchesSimple(const SimpleLogEntryMatcher &simpleMatcher,
+ const int tagId,
+ const unordered_map<int, long> &intMap,
+ const unordered_map<int, string> &strMap,
+ const unordered_map<int, float> &floatMap,
+ const unordered_map<int, bool> &boolMap);
+};
+
+} // namespace statsd
+} // namespace os
+} // namespace android
+#endif //LOG_ENTRY_MATCHER_MANAGER_H
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index c6119df691a3..c7f030559cd3 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -19,14 +19,17 @@ message KeyValueMatcher {
oneof value_matcher {
bool eq_bool = 2;
string eq_string = 3;
- int32 eq_int32 = 4;
- int64 eq_int64 = 5;
- int32 lt_int32 = 6;
- int32 gt_int32 = 7;
- int64 lt_int64 = 8;
- int64 gt_int64 = 9;
- float lt_float = 10;
- float gt_float = 11;
+ int32 eq_int = 4;
+
+ // Numeric comparisons. Lt means strictly less than.
+ int64 lt_int = 5;
+ int64 gt_int = 6;
+ float lt_float = 7;
+ float gt_float = 8;
+
+ // Numeric comparisons with equality. Lte means less than or equal.
+ int64 lte_int = 9;
+ int64 gte_int = 10;
}
}
diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp
new file mode 100644
index 000000000000..eb807cad9085
--- /dev/null
+++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp
@@ -0,0 +1,366 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#define LOG_TAG "statsd_test"
+
+#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
+#include "../src/matchers/LogEntryMatcherManager.h"
+#include "../src/parse_util.h"
+#include <log/logprint.h>
+#include <log/log_read.h>
+#include <log/log_event_list.h>
+#include <gtest/gtest.h>
+
+#include <stdio.h>
+
+using namespace android::os::statsd;
+using std::unordered_map;
+
+#ifdef __ANDROID__
+TEST(LogEntryMatcherTest, TestSimpleMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap, boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestBoolMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(KeyId::STATE);
+
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ keyValue->set_eq_bool(true);
+ boolMap[KeyId::STATE] = true;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+
+ keyValue->set_eq_bool(false);
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+
+ boolMap[TagId::WAKELOCK] = false;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestStringMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(KeyId::STATE);
+ keyValue->set_eq_string("wakelock_name");
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ strMap[KeyId::STATE] = "wakelock_name";
+
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap, boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestIntComparisonMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(KeyId::STATE);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ keyValue->set_lt_int(10);
+ intMap[KeyId::STATE] = 11;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 10;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 9;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+
+ keyValue->set_gt_int(10);
+ intMap[KeyId::STATE] = 11;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 10;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 9;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestIntWithEqualityComparisonMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(KeyId::STATE);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ keyValue->set_lte_int(10);
+ intMap[KeyId::STATE] = 11;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 10;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 9;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+
+ keyValue->set_gte_int(10);
+ intMap[KeyId::STATE] = 11;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 10;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ intMap[KeyId::STATE] = 9;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestFloatComparisonMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto simpleMatcher = matcher.mutable_simple_log_entry_matcher();
+ simpleMatcher->add_tag(TagId::WAKELOCK);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(KeyId::STATE);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ keyValue->set_lt_float(10.0);
+ floatMap[KeyId::STATE] = 10.1;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ floatMap[KeyId::STATE] = 9.9;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+
+ keyValue->set_gt_float(10.0);
+ floatMap[KeyId::STATE] = 10.1;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+ floatMap[KeyId::STATE] = 9.9;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap,
+ floatMap, boolMap));
+}
+
+// Helper for the composite matchers.
+void addSimpleMatcher(SimpleLogEntryMatcher* simpleMatcher, TagId tag, KeyId key, int val) {
+ simpleMatcher->add_tag(tag);
+ auto keyValue = simpleMatcher->add_key_value_matcher();
+ keyValue->mutable_key_matcher()->set_key(key);
+ keyValue->set_eq_int(val);
+}
+
+TEST(LogEntryMatcherTest, TestAndMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::AND);
+
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(), TagId::WAKELOCK, KeyId::STATE, 3);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(), TagId::WAKELOCK, KeyId::PACKAGE_VERSION, 4);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ intMap[1003] = 4;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap, boolMap));
+ intMap.clear();
+ intMap[1] = 3;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap, boolMap));
+ intMap.clear();
+ intMap[1] = 3;
+ intMap[1003] = 4;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap, boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestOrMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::OR);
+
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::STATE, 3);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::PACKAGE_VERSION, 4);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ // Don't set any key-value pairs.
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[1003] = 4;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap.clear();
+ intMap[1] = 3;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap.clear();
+ intMap[1] = 3;
+ intMap[1003] = 4;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestNotMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::NOT);
+
+ // Define first simpleMatcher
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::STATE, 3);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ // Don't set any key-value pairs.
+ intMap[KeyId::STATE] = 3;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestNANDMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::NAND);
+
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::STATE, 3);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::PACKAGE_VERSION, 4);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ // Don't set any key-value pairs.
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::STATE] = 3;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::PACKAGE_VERSION] = 4;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+
+TEST(LogEntryMatcherTest, TestNORMatcher) {
+ // Set up the matcher
+ LogEntryMatcher matcher;
+ auto combination = matcher.mutable_combination();
+ combination->set_operation(LogicalOperation::NOR);
+
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::STATE, 3);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::PACKAGE_VERSION, 4);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ // Don't set any key-value pairs.
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::STATE] = 3;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::PACKAGE_VERSION] = 4;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+
+// Tests that a NOT on top of AND is the same as NAND
+TEST(LogEntryMatcherTest, TestMultipleLayerMatcher) {
+ LogEntryMatcher matcher;
+ auto not_combination = matcher.mutable_combination();
+ not_combination->set_operation(LogicalOperation::NOT);
+
+ // Now add the AND
+ auto combination = not_combination->add_matcher()->mutable_combination();
+ combination->set_operation(LogicalOperation::AND);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::STATE, 3);
+ addSimpleMatcher(combination->add_matcher()->mutable_simple_log_entry_matcher(),
+ TagId::WAKELOCK, KeyId::PACKAGE_VERSION, 4);
+
+ unordered_map<int, long> intMap;
+ unordered_map<int, string> strMap;
+ unordered_map<int, float> floatMap;
+ unordered_map<int, bool> boolMap;
+
+ // Don't set any key-value pairs.
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::STATE] = 3;
+ EXPECT_TRUE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+ intMap[KeyId::PACKAGE_VERSION] = 4;
+ EXPECT_FALSE(LogEntryMatcherManager::matches(matcher, TagId::WAKELOCK, intMap, strMap, floatMap,
+ boolMap));
+}
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
diff --git a/config/compiled-classes-phone b/config/compiled-classes-phone
index df68f14efec9..42e6ecf79229 100644
--- a/config/compiled-classes-phone
+++ b/config/compiled-classes-phone
@@ -5022,8 +5022,6 @@ android.widget.RemoteViews$AsyncApplyTask
android.widget.RemoteViews$BitmapCache
android.widget.RemoteViews$BitmapReflectionAction
android.widget.RemoteViews$LayoutParamAction
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
android.widget.RemoteViews$OnClickHandler
android.widget.RemoteViews$OnViewAppliedListener
android.widget.RemoteViews$ReflectionAction
@@ -5031,7 +5029,7 @@ android.widget.RemoteViews$RemoteView
android.widget.RemoteViews$RemoteViewsContextWrapper
android.widget.RemoteViews$RunnableAction
android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetDrawableParameters
+android.widget.RemoteViews$SetDrawableTint
android.widget.RemoteViews$SetOnClickPendingIntent
android.widget.RemoteViews$SetOnClickPendingIntent$1
android.widget.RemoteViews$ViewGroupAction
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 337d7a0ad8bb..c0819a98a64c 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2723,13 +2723,11 @@ android.widget.RemoteViews$3
android.widget.RemoteViews$Action
android.widget.RemoteViews$BitmapCache
android.widget.RemoteViews$LayoutParamAction
-android.widget.RemoteViews$MemoryUsageCounter
-android.widget.RemoteViews$MutablePair
android.widget.RemoteViews$OnClickHandler
android.widget.RemoteViews$ReflectionAction
android.widget.RemoteViews$RemoteView
android.widget.RemoteViews$RuntimeAction
-android.widget.RemoteViews$SetDrawableParameters
+android.widget.RemoteViews$SetDrawableTint
android.widget.RemoteViewsAdapter$RemoteAdapterConnectionCallback
android.widget.RtlSpacingHelper
android.widget.ScrollBarDrawable
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 00d6657efd0d..1a2dc5cde4e5 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -843,7 +843,7 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
// Assumes forward playing from here on.
for (int i = 0; i < mEvents.size(); i++) {
AnimationEvent event = mEvents.get(i);
- if (event.getTime() > currentPlayTime) {
+ if (event.getTime() > currentPlayTime || event.getTime() == DURATION_INFINITE) {
break;
}
@@ -1264,7 +1264,8 @@ public final class AnimatorSet extends Animator implements AnimationHandler.Anim
} else {
for (int i = mLastEventId + 1; i < size; i++) {
AnimationEvent event = mEvents.get(i);
- if (event.getTime() <= currentPlayTime) {
+ // TODO: need a function that accounts for infinite duration to compare time
+ if (event.getTime() != DURATION_INFINITE && event.getTime() <= currentPlayTime) {
latestId = i;
}
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 60f4ed01805c..fee7d6c8ba2b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3839,8 +3839,8 @@ public class Notification implements Parcelable
contentView.setImageViewBitmap(R.id.profile_badge, profileBadge);
contentView.setViewVisibility(R.id.profile_badge, View.VISIBLE);
if (isColorized()) {
- contentView.setDrawableParameters(R.id.profile_badge, false, -1,
- getPrimaryTextColor(), PorterDuff.Mode.SRC_ATOP, -1);
+ contentView.setDrawableTint(R.id.profile_badge, false,
+ getPrimaryTextColor(), PorterDuff.Mode.SRC_ATOP);
}
}
}
@@ -4130,18 +4130,14 @@ public class Notification implements Parcelable
if (action != null) {
int contrastColor = resolveContrastColor();
- contentView.setDrawableParameters(R.id.reply_icon_action,
+ contentView.setDrawableTint(R.id.reply_icon_action,
true /* targetBackground */,
- -1,
- contrastColor,
- PorterDuff.Mode.SRC_ATOP, -1);
+ contrastColor, PorterDuff.Mode.SRC_ATOP);
int iconColor = NotificationColorUtil.isColorLight(contrastColor)
? Color.BLACK : Color.WHITE;
- contentView.setDrawableParameters(R.id.reply_icon_action,
+ contentView.setDrawableTint(R.id.reply_icon_action,
false /* targetBackground */,
- -1,
- iconColor,
- PorterDuff.Mode.SRC_ATOP, -1);
+ iconColor, PorterDuff.Mode.SRC_ATOP);
contentView.setOnClickPendingIntent(R.id.right_icon,
action.actionIntent);
contentView.setOnClickPendingIntent(R.id.reply_icon_action,
@@ -4185,8 +4181,8 @@ public class Notification implements Parcelable
private void bindExpandButton(RemoteViews contentView) {
int color = getPrimaryHighlightColor();
- contentView.setDrawableParameters(R.id.expand_button, false, -1, color,
- PorterDuff.Mode.SRC_ATOP, -1);
+ contentView.setDrawableTint(R.id.expand_button, false, color,
+ PorterDuff.Mode.SRC_ATOP);
contentView.setInt(R.id.notification_header, "setOriginalNotificationColor",
color);
}
@@ -4293,8 +4289,7 @@ public class Notification implements Parcelable
mN.mSmallIcon = Icon.createWithResource(mContext, mN.icon);
}
contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
- contentView.setDrawableParameters(R.id.icon, false /* targetBackground */,
- -1 /* alpha */, -1 /* colorFilter */, null /* mode */, mN.iconLevel);
+ contentView.setInt(R.id.icon, "setImageLevel", mN.iconLevel);
processSmallIconColor(mN.mSmallIcon, contentView, ambient);
}
@@ -4684,8 +4679,8 @@ public class Notification implements Parcelable
bgColor = mContext.getColor(oddAction ? R.color.notification_action_list
: R.color.notification_action_list_dark);
}
- button.setDrawableParameters(R.id.button_holder, true, -1, bgColor,
- PorterDuff.Mode.SRC_ATOP, -1);
+ button.setDrawableTint(R.id.button_holder, true,
+ bgColor, PorterDuff.Mode.SRC_ATOP);
CharSequence title = action.title;
ColorStateList[] outResultColor = null;
if (isLegacy()) {
@@ -4818,8 +4813,8 @@ public class Notification implements Parcelable
boolean colorable = !isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon);
int color = ambient ? resolveAmbientColor() : getPrimaryHighlightColor();
if (colorable) {
- contentView.setDrawableParameters(R.id.icon, false, -1, color,
- PorterDuff.Mode.SRC_ATOP, -1);
+ contentView.setDrawableTint(R.id.icon, false, color,
+ PorterDuff.Mode.SRC_ATOP);
}
contentView.setInt(R.id.notification_header, "setOriginalIconColor",
@@ -4835,8 +4830,8 @@ public class Notification implements Parcelable
if (largeIcon != null && isLegacy()
&& getColorUtil().isGrayscaleIcon(mContext, largeIcon)) {
// resolve color will fall back to the default when legacy
- contentView.setDrawableParameters(R.id.icon, false, -1, resolveContrastColor(),
- PorterDuff.Mode.SRC_ATOP, -1);
+ contentView.setDrawableTint(R.id.icon, false, resolveContrastColor(),
+ PorterDuff.Mode.SRC_ATOP);
}
}
@@ -6750,8 +6745,8 @@ public class Notification implements Parcelable
: NotificationColorUtil.resolveColor(mBuilder.mContext,
Notification.COLOR_DEFAULT);
- button.setDrawableParameters(R.id.action0, false, -1, tintColor,
- PorterDuff.Mode.SRC_ATOP, -1);
+ button.setDrawableTint(R.id.action0, false, tintColor,
+ PorterDuff.Mode.SRC_ATOP);
if (!tombstone) {
button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 70591d4d0587..84765f6d7280 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1134,6 +1134,29 @@ public final class BluetoothAdapter {
}
/**
+ * Sets the {@link BluetoothClass} Bluetooth Class of Device (CoD) of
+ * the local Bluetooth adapter.
+ *
+ * @param bluetoothClass {@link BluetoothClass} to set the local Bluetooth adapter to.
+ * @return true if successful, false if unsuccessful.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
+ public boolean setBluetoothClass(BluetoothClass bluetoothClass) {
+ if (getState() != STATE_ON) return false;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.setBluetoothClass(bluetoothClass);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return false;
+ }
+
+ /**
* Get the current Bluetooth scan mode of the local Bluetooth adapter.
* <p>The Bluetooth scan mode determines if the local adapter is
* connectable and/or discoverable from remote Bluetooth devices.
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 57e4abb12987..f22ea6e88e04 100755
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -19,6 +19,10 @@ package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+
/**
* Represents a Bluetooth class, which describes general characteristics
* and capabilities of a device. For example, a Bluetooth class will
@@ -275,6 +279,48 @@ public final class BluetoothClass implements Parcelable {
return (mClass & Device.BITMASK);
}
+ /**
+ * Return the Bluetooth Class of Device (CoD) value including the
+ * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
+ * minor device fields.
+ *
+ * <p>This value is an integer representation of Bluetooth CoD as in
+ * Bluetooth specification.
+ *
+ * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
+ *
+ * @hide
+ */
+ public int getClassOfDevice() {
+ return mClass;
+ }
+
+ /**
+ * Return the Bluetooth Class of Device (CoD) value including the
+ * {@link BluetoothClass.Service}, {@link BluetoothClass.Device.Major} and
+ * minor device fields.
+ *
+ * <p>This value is a byte array representation of Bluetooth CoD as in
+ * Bluetooth specification.
+ *
+ * <p>Bluetooth COD information is 3 bytes, but stored as an int. Hence the
+ * MSB is useless and needs to be thrown away. The lower 3 bytes are
+ * converted into a byte array MSB to LSB. Hence, using BIG_ENDIAN.
+ *
+ * @see <a href="Bluetooth CoD">https://www.bluetooth.com/specifications/assigned-numbers/baseband</a>
+ *
+ * @hide
+ */
+ public byte[] getClassOfDeviceBytes() {
+ byte[] bytes = ByteBuffer.allocate(4)
+ .order(ByteOrder.BIG_ENDIAN)
+ .putInt(mClass)
+ .array();
+
+ // Discard the top byte
+ return Arrays.copyOfRange(bytes, 1, bytes.length);
+ }
+
/** @hide */
public static final int PROFILE_HEADSET = 0;
/** @hide */
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 25f791bc8cc6..c3b2a16cc986 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1915,8 +1915,7 @@ public abstract class Layout {
return margin;
}
- /* package */
- static float measurePara(TextPaint paint, CharSequence text, int start, int end,
+ private static float measurePara(TextPaint paint, CharSequence text, int start, int end,
TextDirectionHeuristic textDir) {
MeasuredText mt = MeasuredText.obtain();
TextLine tl = TextLine.obtain();
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 3303b54e462b..8e0ad6352081 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -101,6 +101,7 @@ public class StaticLayout extends Layout {
b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
+ b.mLocales = null;
b.mMeasuredText = MeasuredText.obtain();
return b;
@@ -117,6 +118,9 @@ public class StaticLayout extends Layout {
b.mMeasuredText = null;
b.mLeftIndents = null;
b.mRightIndents = null;
+ b.mLocales = null;
+ b.mLeftPaddings = null;
+ b.mRightPaddings = null;
nFinishBuilder(b.mNativePtr);
sPool.release(b);
}
@@ -128,6 +132,8 @@ public class StaticLayout extends Layout {
mPaint = null;
mLeftIndents = null;
mRightIndents = null;
+ mLeftPaddings = null;
+ mRightPaddings = null;
mMeasuredText.finish();
}
@@ -356,6 +362,28 @@ public class StaticLayout extends Layout {
}
/**
+ * Set available paddings to draw overhanging text on. Arguments are arrays holding the
+ * amount of padding available, one per line, measured in pixels. For lines past the last
+ * element in the array, the last element repeats.
+ *
+ * The individual padding amounts should be non-negative. The result of passing negative
+ * paddings is undefined.
+ *
+ * @param leftPaddings array of amounts of available padding for left margin, in pixels
+ * @param rightPaddings array of amounts of available padding for right margin, in pixels
+ * @return this builder, useful for chaining
+ *
+ * @hide
+ */
+ @NonNull
+ public Builder setAvailablePaddings(@Nullable int[] leftPaddings,
+ @Nullable int[] rightPaddings) {
+ mLeftPaddings = leftPaddings;
+ mRightPaddings = rightPaddings;
+ return this;
+ }
+
+ /**
* Set paragraph justification mode. The default value is
* {@link Layout#JUSTIFICATION_MODE_NONE}. If the last line is too short for justification,
* the last line will be displayed with the alignment set by {@link #setAlignment}.
@@ -401,7 +429,6 @@ public class StaticLayout extends Layout {
* future).
*
* Then, for each run within the paragraph:
- * - setLocales (this must be done at least for the first run, optional afterwards)
* - one of the following, depending on the type of run:
* + addStyleRun (a text run, to be measured in native code)
* + addMeasuredRun (a run already measured in Java, passed into native code)
@@ -413,16 +440,21 @@ public class StaticLayout extends Layout {
* After all paragraphs, call finish() to release expensive buffers.
*/
- private void setLocales(LocaleList locales) {
+ /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
+ final LocaleList locales = paint.getTextLocales();
+ final String languageTags;
+ long[] hyphenators;
if (!locales.equals(mLocales)) {
- nSetLocales(mNativePtr, locales.toLanguageTags(), getHyphenators(locales));
- mLocales = locales;
+ languageTags = locales.toLanguageTags();
+ hyphenators = getHyphenators(locales);
+ } else {
+ // passing null means keep current locale.
+ // TODO: move locale change detection to native.
+ languageTags = null;
+ hyphenators = null;
}
- }
-
- /* package */ float addStyleRun(TextPaint paint, int start, int end, boolean isRtl) {
- setLocales(paint.getTextLocales());
- return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl);
+ return nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl,
+ languageTags, hyphenators);
}
/* package */ void addMeasuredRun(int start, int end, float[] widths) {
@@ -478,6 +510,8 @@ public class StaticLayout extends Layout {
private int mHyphenationFrequency;
@Nullable private int[] mLeftIndents;
@Nullable private int[] mRightIndents;
+ @Nullable private int[] mLeftPaddings;
+ @Nullable private int[] mRightPaddings;
private int mJustificationMode;
private boolean mAddLastLineLineSpacing;
@@ -638,6 +672,8 @@ public class StaticLayout extends Layout {
mLeftIndents = b.mLeftIndents;
mRightIndents = b.mRightIndents;
+ mLeftPaddings = b.mLeftPaddings;
+ mRightPaddings = b.mRightPaddings;
setJustificationMode(b.mJustificationMode);
generate(b, b.mIncludePad, b.mIncludePad);
@@ -662,7 +698,6 @@ public class StaticLayout extends Layout {
// store fontMetrics per span range
// must be a multiple of 4 (and > 0) (store top, bottom, ascent, and descent per range)
int[] fmCache = new int[4 * 4];
- b.setLocales(paint.getTextLocales());
mLineCount = 0;
mEllipsized = false;
@@ -780,7 +815,10 @@ public class StaticLayout extends Layout {
firstWidth, firstWidthLineCount, restWidth,
variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency,
// TODO: Support more justification mode, e.g. letter spacing, stretching.
- b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, indents, mLineCount);
+ b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE,
+ // TODO: indents and paddings don't need to get passed to native code for every
+ // paragraph. Pass them to native code just once.
+ indents, mLeftPaddings, mRightPaddings, mLineCount);
// measurement has to be done before performing line breaking
// but we don't want to recompute fontmetrics or span ranges the
@@ -1494,20 +1532,20 @@ public class StaticLayout extends Layout {
/* package */ static native long nLoadHyphenator(ByteBuffer buf, int offset,
int minPrefix, int minSuffix);
- private static native void nSetLocales(long nativePtr, String locales,
- long[] nativeHyphenators);
-
// Set up paragraph text and settings; done as one big method to minimize jni crossings
private static native void nSetupParagraph(
- @NonNull long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length,
+ /* non zero */ long nativePtr, @NonNull char[] text, @IntRange(from = 0) int length,
@FloatRange(from = 0.0f) float firstWidth, @IntRange(from = 0) int firstWidthLineCount,
@FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops,
int defaultTabStop, @BreakStrategy int breakStrategy,
@HyphenationFrequency int hyphenationFrequency, boolean isJustified,
- @Nullable int[] indents, @IntRange(from = 0) int indentsOffset);
+ @Nullable int[] indents, @Nullable int[] leftPaddings, @Nullable int[] rightPaddings,
+ @IntRange(from = 0) int indentsOffset);
- private static native float nAddStyleRun(long nativePtr, long nativePaint, int start, int end,
- boolean isRtl);
+ private static native float nAddStyleRun(
+ /* non zero */ long nativePtr, /* non zero */ long nativePaint,
+ @IntRange(from = 0) int start, @IntRange(from = 0) int end, boolean isRtl,
+ @Nullable String languageTags, @Nullable long[] hyphenators);
private static native void nAddMeasuredRun(long nativePtr,
int start, int end, float[] widths);
@@ -1590,4 +1628,6 @@ public class StaticLayout extends Layout {
@Nullable private int[] mLeftIndents;
@Nullable private int[] mRightIndents;
+ @Nullable private int[] mLeftPaddings;
+ @Nullable private int[] mRightPaddings;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a5d964951af1..1b26f8e2fd9f 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -20,6 +20,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import android.annotation.ColorInt;
import android.annotation.DimenRes;
+import android.annotation.NonNull;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.Application;
@@ -108,9 +109,9 @@ public class RemoteViews implements Parcelable, Filter {
// The unique identifiers for each custom {@link Action}.
private static final int SET_ON_CLICK_PENDING_INTENT_TAG = 1;
private static final int REFLECTION_ACTION_TAG = 2;
- private static final int SET_DRAWABLE_PARAMETERS_TAG = 3;
+ private static final int SET_DRAWABLE_TINT_TAG = 3;
private static final int VIEW_GROUP_ACTION_ADD_TAG = 4;
- private static final int SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG = 5;
+ private static final int VIEW_CONTENT_NAVIGATION_TAG = 5;
private static final int SET_EMPTY_VIEW_ACTION_TAG = 6;
private static final int VIEW_GROUP_ACTION_REMOVE_TAG = 7;
private static final int SET_PENDING_INTENT_TEMPLATE_TAG = 8;
@@ -121,7 +122,6 @@ public class RemoteViews implements Parcelable, Filter {
private static final int TEXT_VIEW_SIZE_ACTION_TAG = 13;
private static final int VIEW_PADDING_ACTION_TAG = 14;
private static final int SET_REMOTE_VIEW_ADAPTER_LIST_TAG = 15;
- private static final int TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG = 17;
private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18;
private static final int LAYOUT_PARAM_ACTION_TAG = 19;
private static final int OVERRIDE_TEXT_COLORS_TAG = 20;
@@ -389,10 +389,10 @@ public class RemoteViews implements Parcelable, Filter {
return MERGE_REPLACE;
}
- public abstract String getActionName();
+ public abstract int getActionTag();
public String getUniqueKey() {
- return (getActionName() + viewId);
+ return (getActionTag() + "_" + viewId);
}
/**
@@ -424,8 +424,8 @@ public class RemoteViews implements Parcelable, Filter {
*/
private static abstract class RuntimeAction extends Action {
@Override
- public final String getActionName() {
- return "RuntimeAction";
+ public final int getActionTag() {
+ return 0;
}
@Override
@@ -514,7 +514,6 @@ public class RemoteViews implements Parcelable, Filter {
}
private class SetEmptyView extends Action {
- int viewId;
int emptyViewId;
SetEmptyView(int viewId, int emptyViewId) {
@@ -528,7 +527,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(SET_EMPTY_VIEW_ACTION_TAG);
out.writeInt(this.viewId);
out.writeInt(this.emptyViewId);
}
@@ -546,8 +544,9 @@ public class RemoteViews implements Parcelable, Filter {
adapterView.setEmptyView(emptyView);
}
- public String getActionName() {
- return "SetEmptyView";
+ @Override
+ public int getActionTag() {
+ return SET_EMPTY_VIEW_ACTION_TAG;
}
}
@@ -559,13 +558,12 @@ public class RemoteViews implements Parcelable, Filter {
public SetOnClickFillInIntent(Parcel parcel) {
viewId = parcel.readInt();
- fillInIntent = Intent.CREATOR.createFromParcel(parcel);
+ fillInIntent = parcel.readTypedObject(Intent.CREATOR);
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_ON_CLICK_FILL_IN_INTENT_TAG);
dest.writeInt(viewId);
- fillInIntent.writeToParcel(dest, 0 /* no flags */);
+ dest.writeTypedObject(fillInIntent, 0 /* no flags */);
}
@Override
@@ -624,8 +622,9 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- public String getActionName() {
- return "SetOnClickFillInIntent";
+ @Override
+ public int getActionTag() {
+ return SET_ON_CLICK_FILL_IN_INTENT_TAG;
}
Intent fillInIntent;
@@ -643,9 +642,8 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_PENDING_INTENT_TEMPLATE_TAG);
dest.writeInt(viewId);
- pendingIntentTemplate.writeToParcel(dest, 0 /* no flags */);
+ PendingIntent.writePendingIntentOrNullToParcel(pendingIntentTemplate, dest);
}
@Override
@@ -699,8 +697,9 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- public String getActionName() {
- return "SetPendingIntentTemplate";
+ @Override
+ public int getActionTag() {
+ return SET_PENDING_INTENT_TEMPLATE_TAG;
}
PendingIntent pendingIntentTemplate;
@@ -716,30 +715,13 @@ public class RemoteViews implements Parcelable, Filter {
public SetRemoteViewsAdapterList(Parcel parcel) {
viewId = parcel.readInt();
viewTypeCount = parcel.readInt();
- int count = parcel.readInt();
- list = new ArrayList<RemoteViews>();
-
- for (int i = 0; i < count; i++) {
- RemoteViews rv = RemoteViews.CREATOR.createFromParcel(parcel);
- list.add(rv);
- }
+ list = parcel.createTypedArrayList(RemoteViews.CREATOR);
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_REMOTE_VIEW_ADAPTER_LIST_TAG);
dest.writeInt(viewId);
dest.writeInt(viewTypeCount);
-
- if (list == null || list.size() == 0) {
- dest.writeInt(0);
- } else {
- int count = list.size();
- dest.writeInt(count);
- for (int i = 0; i < count; i++) {
- RemoteViews rv = list.get(i);
- rv.writeToParcel(dest, flags);
- }
- }
+ dest.writeTypedList(list, flags);
}
@Override
@@ -779,8 +761,9 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- public String getActionName() {
- return "SetRemoteViewsAdapterList";
+ @Override
+ public int getActionTag() {
+ return SET_REMOTE_VIEW_ADAPTER_LIST_TAG;
}
int viewTypeCount;
@@ -795,13 +778,12 @@ public class RemoteViews implements Parcelable, Filter {
public SetRemoteViewsAdapterIntent(Parcel parcel) {
viewId = parcel.readInt();
- intent = Intent.CREATOR.createFromParcel(parcel);
+ intent = parcel.readTypedObject(Intent.CREATOR);
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_REMOTE_VIEW_ADAPTER_INTENT_TAG);
dest.writeInt(viewId);
- intent.writeToParcel(dest, flags);
+ dest.writeTypedObject(intent, flags);
}
@Override
@@ -845,8 +827,9 @@ public class RemoteViews implements Parcelable, Filter {
return copy;
}
- public String getActionName() {
- return "SetRemoteViewsAdapterIntent";
+ @Override
+ public int getActionTag() {
+ return SET_REMOTE_VIEW_ADAPTER_INTENT_TAG;
}
Intent intent;
@@ -866,22 +849,12 @@ public class RemoteViews implements Parcelable, Filter {
public SetOnClickPendingIntent(Parcel parcel) {
viewId = parcel.readInt();
-
- // We check a flag to determine if the parcel contains a PendingIntent.
- if (parcel.readInt() != 0) {
- pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
- }
+ pendingIntent = PendingIntent.readPendingIntentOrNullFromParcel(parcel);
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_ON_CLICK_PENDING_INTENT_TAG);
dest.writeInt(viewId);
-
- // We use a flag to indicate whether the parcel contains a valid object.
- dest.writeInt(pendingIntent != null ? 1 : 0);
- if (pendingIntent != null) {
- pendingIntent.writeToParcel(dest, 0 /* no flags */);
- }
+ PendingIntent.writePendingIntentOrNullToParcel(pendingIntent, dest);
}
@Override
@@ -922,8 +895,9 @@ public class RemoteViews implements Parcelable, Filter {
target.setOnClickListener(listener);
}
- public String getActionName() {
- return "SetOnClickPendingIntent";
+ @Override
+ public int getActionTag() {
+ return SET_ON_CLICK_PENDING_INTENT_TAG;
}
PendingIntent pendingIntent;
@@ -1012,55 +986,37 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
- * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
+ * Equivalent to calling
* {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
- * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given view.
+ * on the {@link Drawable} of a given view.
* <p>
- * These operations will be performed on the {@link Drawable} returned by the
+ * The operation will be performed on the {@link Drawable} returned by the
* target {@link View#getBackground()} by default. If targetBackground is false,
* we assume the target is an {@link ImageView} and try applying the operations
* to {@link ImageView#getDrawable()}.
* <p>
- * You can omit specific calls by marking their values with null or -1.
*/
- private class SetDrawableParameters extends Action {
- public SetDrawableParameters(int id, boolean targetBackground, int alpha,
- int colorFilter, PorterDuff.Mode mode, int level) {
+ private class SetDrawableTint extends Action {
+ SetDrawableTint(int id, boolean targetBackground,
+ int colorFilter, @NonNull PorterDuff.Mode mode) {
this.viewId = id;
this.targetBackground = targetBackground;
- this.alpha = alpha;
this.colorFilter = colorFilter;
this.filterMode = mode;
- this.level = level;
}
- public SetDrawableParameters(Parcel parcel) {
+ SetDrawableTint(Parcel parcel) {
viewId = parcel.readInt();
targetBackground = parcel.readInt() != 0;
- alpha = parcel.readInt();
colorFilter = parcel.readInt();
- boolean hasMode = parcel.readInt() != 0;
- if (hasMode) {
- filterMode = PorterDuff.Mode.valueOf(parcel.readString());
- } else {
- filterMode = null;
- }
- level = parcel.readInt();
+ filterMode = PorterDuff.intToMode(parcel.readInt());
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_DRAWABLE_PARAMETERS_TAG);
dest.writeInt(viewId);
dest.writeInt(targetBackground ? 1 : 0);
- dest.writeInt(alpha);
dest.writeInt(colorFilter);
- if (filterMode != null) {
- dest.writeInt(1);
- dest.writeString(filterMode.toString());
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(level);
+ dest.writeInt(PorterDuff.modeToInt(filterMode));
}
@Override
@@ -1078,47 +1034,36 @@ public class RemoteViews implements Parcelable, Filter {
}
if (targetDrawable != null) {
- // Perform modifications only if values are set correctly
- if (alpha != -1) {
- targetDrawable.mutate().setAlpha(alpha);
- }
- if (filterMode != null) {
- targetDrawable.mutate().setColorFilter(colorFilter, filterMode);
- }
- if (level != -1) {
- targetDrawable.mutate().setLevel(level);
- }
+ targetDrawable.mutate().setColorFilter(colorFilter, filterMode);
}
}
- public String getActionName() {
- return "SetDrawableParameters";
+ @Override
+ public int getActionTag() {
+ return SET_DRAWABLE_TINT_TAG;
}
boolean targetBackground;
- int alpha;
int colorFilter;
PorterDuff.Mode filterMode;
- int level;
}
- private final class ReflectionActionWithoutParams extends Action {
- final String methodName;
+ private final class ViewContentNavigation extends Action {
+ final boolean mNext;
- ReflectionActionWithoutParams(int viewId, String methodName) {
+ ViewContentNavigation(int viewId, boolean next) {
this.viewId = viewId;
- this.methodName = methodName;
+ this.mNext = next;
}
- ReflectionActionWithoutParams(Parcel in) {
+ ViewContentNavigation(Parcel in) {
this.viewId = in.readInt();
- this.methodName = in.readString();
+ this.mNext = in.readBoolean();
}
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG);
out.writeInt(this.viewId);
- out.writeString(this.methodName);
+ out.writeBoolean(this.mNext);
}
@Override
@@ -1127,23 +1072,20 @@ public class RemoteViews implements Parcelable, Filter {
if (view == null) return;
try {
- getMethod(view, this.methodName, null, false /* async */).invoke(view);
+ getMethod(view,
+ mNext ? "showNext" : "showPrevious", null, false /* async */).invoke(view);
} catch (Throwable ex) {
throw new ActionException(ex);
}
}
public int mergeBehavior() {
- // we don't need to build up showNext or showPrevious calls
- if (methodName.equals("showNext") || methodName.equals("showPrevious")) {
- return MERGE_IGNORE;
- } else {
- return MERGE_REPLACE;
- }
+ return MERGE_IGNORE;
}
- public String getActionName() {
- return "ReflectionActionWithoutParams";
+ @Override
+ public int getActionTag() {
+ return VIEW_CONTENT_NAVIGATION_TAG;
}
}
@@ -1157,12 +1099,7 @@ public class RemoteViews implements Parcelable, Filter {
}
public BitmapCache(Parcel source) {
- int count = source.readInt();
- mBitmaps = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- Bitmap b = Bitmap.CREATOR.createFromParcel(source);
- mBitmaps.add(b);
- }
+ mBitmaps = source.createTypedArrayList(Bitmap.CREATOR);
}
public int getBitmapId(Bitmap b) {
@@ -1188,11 +1125,7 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeBitmapsToParcel(Parcel dest, int flags) {
- int count = mBitmaps.size();
- dest.writeInt(count);
- for (int i = 0; i < count; i++) {
- mBitmaps.get(i).writeToParcel(dest, flags);
- }
+ dest.writeTypedList(mBitmaps, flags);
}
public int getBitmapMemory() {
@@ -1228,7 +1161,6 @@ public class RemoteViews implements Parcelable, Filter {
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(BITMAP_REFLECTION_ACTION_TAG);
dest.writeInt(viewId);
dest.writeString(methodName);
dest.writeInt(bitmapId);
@@ -1247,8 +1179,9 @@ public class RemoteViews implements Parcelable, Filter {
bitmapId = bitmapCache.getBitmapId(bitmap);
}
- public String getActionName() {
- return "BitmapReflectionAction";
+ @Override
+ public int getActionTag() {
+ return BITMAP_REFLECTION_ACTION_TAG;
}
}
@@ -1300,7 +1233,7 @@ public class RemoteViews implements Parcelable, Filter {
// written to the parcel.
switch (this.type) {
case BOOLEAN:
- this.value = in.readInt() != 0;
+ this.value = in.readBoolean();
break;
case BYTE:
this.value = in.readByte();
@@ -1330,39 +1263,28 @@ public class RemoteViews implements Parcelable, Filter {
this.value = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
break;
case URI:
- if (in.readInt() != 0) {
- this.value = Uri.CREATOR.createFromParcel(in);
- }
+ this.value = in.readTypedObject(Uri.CREATOR);
break;
case BITMAP:
- if (in.readInt() != 0) {
- this.value = Bitmap.CREATOR.createFromParcel(in);
- }
+ this.value = in.readTypedObject(Bitmap.CREATOR);
break;
case BUNDLE:
this.value = in.readBundle();
break;
case INTENT:
- if (in.readInt() != 0) {
- this.value = Intent.CREATOR.createFromParcel(in);
- }
+ this.value = in.readTypedObject(Intent.CREATOR);
break;
case COLOR_STATE_LIST:
- if (in.readInt() != 0) {
- this.value = ColorStateList.CREATOR.createFromParcel(in);
- }
+ this.value = in.readTypedObject(ColorStateList.CREATOR);
break;
case ICON:
- if (in.readInt() != 0) {
- this.value = Icon.CREATOR.createFromParcel(in);
- }
+ this.value = in.readTypedObject(Icon.CREATOR);
default:
break;
}
}
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(REFLECTION_ACTION_TAG);
out.writeInt(this.viewId);
out.writeString(this.methodName);
out.writeInt(this.type);
@@ -1376,7 +1298,7 @@ public class RemoteViews implements Parcelable, Filter {
// we have written a valid value to the parcel.
switch (this.type) {
case BOOLEAN:
- out.writeInt((Boolean) this.value ? 1 : 0);
+ out.writeBoolean((Boolean) this.value);
break;
case BYTE:
out.writeByte((Byte) this.value);
@@ -1413,10 +1335,7 @@ public class RemoteViews implements Parcelable, Filter {
case INTENT:
case COLOR_STATE_LIST:
case ICON:
- out.writeInt(this.value != null ? 1 : 0);
- if (this.value != null) {
- ((Parcelable) this.value).writeToParcel(out, flags);
- }
+ out.writeTypedObject((Parcelable) this.value, flags);
break;
default:
break;
@@ -1522,10 +1441,16 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- public String getActionName() {
+ @Override
+ public int getActionTag() {
+ return REFLECTION_ACTION_TAG;
+ }
+
+ @Override
+ public String getUniqueKey() {
// Each type of reflection action corresponds to a setter, so each should be seen as
// unique from the standpoint of merging.
- return "ReflectionAction" + this.methodName + this.type;
+ return super.getUniqueKey() + this.methodName + this.type;
}
@Override
@@ -1587,7 +1512,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(VIEW_GROUP_ACTION_ADD_TAG);
dest.writeInt(viewId);
dest.writeInt(mIndex);
mNestedViews.writeToParcel(dest, flags);
@@ -1662,10 +1586,9 @@ public class RemoteViews implements Parcelable, Filter {
return mNestedViews.prefersAsyncApply();
}
-
@Override
- public String getActionName() {
- return "ViewGroupActionAdd";
+ public int getActionTag() {
+ return VIEW_GROUP_ACTION_ADD_TAG;
}
}
@@ -1697,7 +1620,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(VIEW_GROUP_ACTION_REMOVE_TAG);
dest.writeInt(viewId);
dest.writeInt(mViewIdToKeep);
}
@@ -1763,8 +1685,8 @@ public class RemoteViews implements Parcelable, Filter {
}
@Override
- public String getActionName() {
- return "ViewGroupActionRemove";
+ public int getActionTag() {
+ return VIEW_GROUP_ACTION_REMOVE_TAG;
}
@Override
@@ -1804,18 +1726,10 @@ public class RemoteViews implements Parcelable, Filter {
isRelative = (parcel.readInt() != 0);
useIcons = (parcel.readInt() != 0);
if (useIcons) {
- if (parcel.readInt() != 0) {
- i1 = Icon.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
- i2 = Icon.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
- i3 = Icon.CREATOR.createFromParcel(parcel);
- }
- if (parcel.readInt() != 0) {
- i4 = Icon.CREATOR.createFromParcel(parcel);
- }
+ i1 = parcel.readTypedObject(Icon.CREATOR);
+ i2 = parcel.readTypedObject(Icon.CREATOR);
+ i3 = parcel.readTypedObject(Icon.CREATOR);
+ i4 = parcel.readTypedObject(Icon.CREATOR);
} else {
d1 = parcel.readInt();
d2 = parcel.readInt();
@@ -1825,35 +1739,14 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TEXT_VIEW_DRAWABLE_ACTION_TAG);
dest.writeInt(viewId);
dest.writeInt(isRelative ? 1 : 0);
dest.writeInt(useIcons ? 1 : 0);
if (useIcons) {
- if (i1 != null) {
- dest.writeInt(1);
- i1.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
- if (i2 != null) {
- dest.writeInt(1);
- i2.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
- if (i3 != null) {
- dest.writeInt(1);
- i3.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
- if (i4 != null) {
- dest.writeInt(1);
- i4.writeToParcel(dest, 0);
- } else {
- dest.writeInt(0);
- }
+ dest.writeTypedObject(i1, 0);
+ dest.writeTypedObject(i2, 0);
+ dest.writeTypedObject(i3, 0);
+ dest.writeTypedObject(i4, 0);
} else {
dest.writeInt(d1);
dest.writeInt(d2);
@@ -1924,8 +1817,9 @@ public class RemoteViews implements Parcelable, Filter {
return useIcons;
}
- public String getActionName() {
- return "TextViewDrawableAction";
+ @Override
+ public int getActionTag() {
+ return TEXT_VIEW_DRAWABLE_ACTION_TAG;
}
boolean isRelative = false;
@@ -1954,7 +1848,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TEXT_VIEW_SIZE_ACTION_TAG);
dest.writeInt(viewId);
dest.writeInt(units);
dest.writeFloat(size);
@@ -1967,8 +1860,9 @@ public class RemoteViews implements Parcelable, Filter {
target.setTextSize(units, size);
}
- public String getActionName() {
- return "TextViewSizeAction";
+ @Override
+ public int getActionTag() {
+ return TEXT_VIEW_SIZE_ACTION_TAG;
}
int units;
@@ -1996,7 +1890,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(VIEW_PADDING_ACTION_TAG);
dest.writeInt(viewId);
dest.writeInt(left);
dest.writeInt(top);
@@ -2011,8 +1904,9 @@ public class RemoteViews implements Parcelable, Filter {
target.setPadding(left, top, right, bottom);
}
- public String getActionName() {
- return "ViewPaddingAction";
+ @Override
+ public int getActionTag() {
+ return VIEW_PADDING_ACTION_TAG;
}
int left, top, right, bottom;
@@ -2029,6 +1923,9 @@ public class RemoteViews implements Parcelable, Filter {
public static final int LAYOUT_WIDTH = 2;
public static final int LAYOUT_MARGIN_BOTTOM_DIMEN = 3;
+ final int mProperty;
+ final int mValue;
+
/**
* @param viewId ID of the view alter
* @param property which layout parameter to alter
@@ -2036,21 +1933,20 @@ public class RemoteViews implements Parcelable, Filter {
*/
public LayoutParamAction(int viewId, int property, int value) {
this.viewId = viewId;
- this.property = property;
- this.value = value;
+ this.mProperty = property;
+ this.mValue = value;
}
public LayoutParamAction(Parcel parcel) {
viewId = parcel.readInt();
- property = parcel.readInt();
- value = parcel.readInt();
+ mProperty = parcel.readInt();
+ mValue = parcel.readInt();
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(LAYOUT_PARAM_ACTION_TAG);
dest.writeInt(viewId);
- dest.writeInt(property);
- dest.writeInt(value);
+ dest.writeInt(mProperty);
+ dest.writeInt(mValue);
}
@Override
@@ -2063,27 +1959,27 @@ public class RemoteViews implements Parcelable, Filter {
if (layoutParams == null) {
return;
}
- switch (property) {
+ switch (mProperty) {
case LAYOUT_MARGIN_END_DIMEN:
if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
- int resolved = resolveDimenPixelOffset(target, value);
+ int resolved = resolveDimenPixelOffset(target, mValue);
((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(resolved);
target.setLayoutParams(layoutParams);
}
break;
case LAYOUT_MARGIN_BOTTOM_DIMEN:
if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
- int resolved = resolveDimenPixelOffset(target, value);
+ int resolved = resolveDimenPixelOffset(target, mValue);
((ViewGroup.MarginLayoutParams) layoutParams).bottomMargin = resolved;
target.setLayoutParams(layoutParams);
}
break;
case LAYOUT_WIDTH:
- layoutParams.width = value;
+ layoutParams.width = mValue;
target.setLayoutParams(layoutParams);
break;
default:
- throw new IllegalArgumentException("Unknown property " + property);
+ throw new IllegalArgumentException("Unknown property " + mProperty);
}
}
@@ -2094,79 +1990,15 @@ public class RemoteViews implements Parcelable, Filter {
return target.getContext().getResources().getDimensionPixelOffset(value);
}
- public String getActionName() {
- return "LayoutParamAction" + property + ".";
- }
-
- int property;
- int value;
- }
-
- /**
- * Helper action to set a color filter on a compound drawable on a TextView. Supports relative
- * (s/t/e/b) or cardinal (l/t/r/b) arrangement.
- */
- private class TextViewDrawableColorFilterAction extends Action {
- public TextViewDrawableColorFilterAction(int viewId, boolean isRelative, int index,
- int color, PorterDuff.Mode mode) {
- this.viewId = viewId;
- this.isRelative = isRelative;
- this.index = index;
- this.color = color;
- this.mode = mode;
- }
-
- public TextViewDrawableColorFilterAction(Parcel parcel) {
- viewId = parcel.readInt();
- isRelative = (parcel.readInt() != 0);
- index = parcel.readInt();
- color = parcel.readInt();
- mode = readPorterDuffMode(parcel);
- }
-
- private PorterDuff.Mode readPorterDuffMode(Parcel parcel) {
- int mode = parcel.readInt();
- if (mode >= 0 && mode < PorterDuff.Mode.values().length) {
- return PorterDuff.Mode.values()[mode];
- } else {
- return PorterDuff.Mode.CLEAR;
- }
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG);
- dest.writeInt(viewId);
- dest.writeInt(isRelative ? 1 : 0);
- dest.writeInt(index);
- dest.writeInt(color);
- dest.writeInt(mode.ordinal());
- }
-
@Override
- public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
- final TextView target = root.findViewById(viewId);
- if (target == null) return;
- Drawable[] drawables = isRelative
- ? target.getCompoundDrawablesRelative()
- : target.getCompoundDrawables();
- if (index < 0 || index >= 4) {
- throw new IllegalStateException("index must be in range [0, 3].");
- }
- Drawable d = drawables[index];
- if (d != null) {
- d.mutate();
- d.setColorFilter(color, mode);
- }
+ public int getActionTag() {
+ return LAYOUT_PARAM_ACTION_TAG;
}
- public String getActionName() {
- return "TextViewDrawableColorFilterAction";
+ @Override
+ public String getUniqueKey() {
+ return super.getUniqueKey() + mProperty;
}
-
- final boolean isRelative;
- final int index;
- final int color;
- final PorterDuff.Mode mode;
}
/**
@@ -2185,7 +2017,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(SET_REMOTE_INPUTS_ACTION_TAG);
dest.writeInt(viewId);
dest.writeTypedArray(remoteInputs, flags);
}
@@ -2198,8 +2029,9 @@ public class RemoteViews implements Parcelable, Filter {
target.setTagInternal(R.id.remote_input_tag, remoteInputs);
}
- public String getActionName() {
- return "SetRemoteInputsAction";
+ @Override
+ public int getActionTag() {
+ return SET_REMOTE_INPUTS_ACTION_TAG;
}
final Parcelable[] remoteInputs;
@@ -2221,7 +2053,6 @@ public class RemoteViews implements Parcelable, Filter {
}
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(OVERRIDE_TEXT_COLORS_TAG);
dest.writeInt(textColor);
}
@@ -2246,8 +2077,9 @@ public class RemoteViews implements Parcelable, Filter {
}
}
- public String getActionName() {
- return "OverrideTextColorsAction";
+ @Override
+ public int getActionTag() {
+ return OVERRIDE_TEXT_COLORS_TAG;
}
}
@@ -2411,16 +2243,16 @@ public class RemoteViews implements Parcelable, Filter {
switch (tag) {
case SET_ON_CLICK_PENDING_INTENT_TAG:
return new SetOnClickPendingIntent(parcel);
- case SET_DRAWABLE_PARAMETERS_TAG:
- return new SetDrawableParameters(parcel);
+ case SET_DRAWABLE_TINT_TAG:
+ return new SetDrawableTint(parcel);
case REFLECTION_ACTION_TAG:
return new ReflectionAction(parcel);
case VIEW_GROUP_ACTION_ADD_TAG:
return new ViewGroupActionAdd(parcel, mBitmapCache, mApplication, depth);
case VIEW_GROUP_ACTION_REMOVE_TAG:
return new ViewGroupActionRemove(parcel);
- case SET_REFLECTION_ACTION_WITHOUT_PARAMS_TAG:
- return new ReflectionActionWithoutParams(parcel);
+ case VIEW_CONTENT_NAVIGATION_TAG:
+ return new ViewContentNavigation(parcel);
case SET_EMPTY_VIEW_ACTION_TAG:
return new SetEmptyView(parcel);
case SET_PENDING_INTENT_TEMPLATE_TAG:
@@ -2439,8 +2271,6 @@ public class RemoteViews implements Parcelable, Filter {
return new BitmapReflectionAction(parcel);
case SET_REMOTE_VIEW_ADAPTER_LIST_TAG:
return new SetRemoteViewsAdapterList(parcel);
- case TEXT_VIEW_DRAWABLE_COLOR_FILTER_ACTION_TAG:
- return new TextViewDrawableColorFilterAction(parcel);
case SET_REMOTE_INPUTS_ACTION_TAG:
return new SetRemoteInputsAction(parcel);
case LAYOUT_PARAM_ACTION_TAG:
@@ -2597,7 +2427,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param viewId The id of the view on which to call {@link AdapterViewAnimator#showNext()}
*/
public void showNext(int viewId) {
- addAction(new ReflectionActionWithoutParams(viewId, "showNext"));
+ addAction(new ViewContentNavigation(viewId, true /* next */));
}
/**
@@ -2606,7 +2436,7 @@ public class RemoteViews implements Parcelable, Filter {
* @param viewId The id of the view on which to call {@link AdapterViewAnimator#showPrevious()}
*/
public void showPrevious(int viewId) {
- addAction(new ReflectionActionWithoutParams(viewId, "showPrevious"));
+ addAction(new ViewContentNavigation(viewId, false /* next */));
}
/**
@@ -2680,28 +2510,6 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
- * Equivalent to applying a color filter on one of the drawables in
- * {@link android.widget.TextView#getCompoundDrawablesRelative()}.
- *
- * @param viewId The id of the view whose text should change.
- * @param index The index of the drawable in the array of
- * {@link android.widget.TextView#getCompoundDrawablesRelative()} to set the color
- * filter on. Must be in [0, 3].
- * @param color The color of the color filter. See
- * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}.
- * @param mode The mode of the color filter. See
- * {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)}.
- * @hide
- */
- public void setTextViewCompoundDrawablesRelativeColorFilter(int viewId,
- int index, int color, PorterDuff.Mode mode) {
- if (index < 0 || index >= 4) {
- throw new IllegalArgumentException("index must be in range [0, 3].");
- }
- addAction(new TextViewDrawableColorFilterAction(viewId, true, index, color, mode));
- }
-
- /**
* Equivalent to calling {@link
* TextView#setCompoundDrawablesWithIntrinsicBounds(Drawable, Drawable, Drawable, Drawable)}
* using the drawables yielded by {@link Icon#loadDrawable(Context)}.
@@ -2898,12 +2706,10 @@ public class RemoteViews implements Parcelable, Filter {
/**
* @hide
- * Equivalent to calling a combination of {@link Drawable#setAlpha(int)},
+ * Equivalent to calling
* {@link Drawable#setColorFilter(int, android.graphics.PorterDuff.Mode)},
- * and/or {@link Drawable#setLevel(int)} on the {@link Drawable} of a given
- * view.
+ * on the {@link Drawable} of a given view.
* <p>
- * You can omit specific calls by marking their values with null or -1.
*
* @param viewId The id of the view that contains the target
* {@link Drawable}
@@ -2912,20 +2718,15 @@ public class RemoteViews implements Parcelable, Filter {
* {@link android.view.View#getBackground()}. Otherwise, assume
* the target view is an {@link ImageView} and apply them to
* {@link ImageView#getDrawable()}.
- * @param alpha Specify an alpha value for the drawable, or -1 to leave
- * unchanged.
* @param colorFilter Specify a color for a
* {@link android.graphics.ColorFilter} for this drawable. This will be ignored if
* {@code mode} is {@code null}.
* @param mode Specify a PorterDuff mode for this drawable, or null to leave
* unchanged.
- * @param level Specify the level for the drawable, or -1 to leave
- * unchanged.
*/
- public void setDrawableParameters(int viewId, boolean targetBackground, int alpha,
- int colorFilter, PorterDuff.Mode mode, int level) {
- addAction(new SetDrawableParameters(viewId, targetBackground, alpha,
- colorFilter, mode, level));
+ public void setDrawableTint(int viewId, boolean targetBackground,
+ int colorFilter, @NonNull PorterDuff.Mode mode) {
+ addAction(new SetDrawableTint(viewId, targetBackground, colorFilter, mode));
}
/**
@@ -3717,6 +3518,7 @@ public class RemoteViews implements Parcelable, Filter {
parcel.writeInt(count);
for (int i = 0; i < count; i++) {
Action a = mActions.get(i);
+ parcel.writeInt(a.getActionTag());
a.writeToParcel(parcel, a.hasSameAppInfo(mApplication)
? PARCELABLE_ELIDE_DUPLICATES : 0);
}
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 7442fa2d62dc..9afb7f3ed444 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -87,7 +87,8 @@ class JNILineBreakerLineWidth : public minikin::LineBreaker::LineWidthDelegate {
static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length,
jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
jintArray variableTabStops, jint defaultTabStop, jint strategy, jint hyphenFrequency,
- jboolean isJustified, jintArray indents, jint indentsOffset) {
+ jboolean isJustified, jintArray indents, jintArray leftPaddings, jintArray rightPaddings,
+ jint indentsOffset) {
minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
b->resize(length);
env->GetCharArrayRegion(text, 0, length, b->buffer());
@@ -187,24 +188,9 @@ static jlong nLoadHyphenator(JNIEnv* env, jclass, jobject buffer, jint offset,
return reinterpret_cast<jlong>(hyphenator);
}
-static void nSetLocales(JNIEnv* env, jclass, jlong nativePtr, jstring javaLocaleNames,
- jlongArray nativeHyphenators) {
- minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
-
- ScopedUtfChars localeNames(env, javaLocaleNames);
- ScopedLongArrayRO hyphArr(env, nativeHyphenators);
- const size_t numLocales = hyphArr.size();
- std::vector<minikin::Hyphenator*> hyphVec;
- hyphVec.reserve(numLocales);
- for (size_t i = 0; i < numLocales; i++) {
- hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
- }
- b->setLocales(localeNames.c_str(), hyphVec);
-}
-
// Basically similar to Paint.getTextRunAdvances but with C++ interface
static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePaint, jint start,
- jint end, jboolean isRtl) {
+ jint end, jboolean isRtl, jstring langTags, jlongArray hyphenators) {
minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
Paint* paint = reinterpret_cast<Paint*>(nativePaint);
const Typeface* typeface = paint->getAndroidTypeface();
@@ -212,8 +198,26 @@ static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, jlong nativePai
const Typeface* resolvedTypeface = Typeface::resolveDefault(typeface);
minikin::FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, paint,
typeface);
- return b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start, end,
- isRtl);
+
+ std::vector<minikin::Hyphenator*> hyphVec;
+ const char* langTagStr;
+ if (langTags == nullptr) {
+ langTagStr = nullptr; // nullptr languageTag means keeping current locale
+ } else {
+ ScopedLongArrayRO hyphArr(env, hyphenators);
+ const size_t numLocales = hyphArr.size();
+ hyphVec.reserve(numLocales);
+ for (size_t i = 0; i < numLocales; i++) {
+ hyphVec.push_back(reinterpret_cast<minikin::Hyphenator*>(hyphArr[i]));
+ }
+ langTagStr = env->GetStringUTFChars(langTags, nullptr);
+ }
+ float result = b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start,
+ end, isRtl, langTagStr, hyphVec);
+ if (langTagStr != nullptr) {
+ env->ReleaseStringUTFChars(langTags, langTagStr);
+ }
+ return result;
}
// Accept width measurements for the run, passed in from Java
@@ -221,7 +225,8 @@ static void nAddMeasuredRun(JNIEnv* env, jclass, jlong nativePtr,
jint start, jint end, jfloatArray widths) {
minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr);
env->GetFloatArrayRegion(widths, start, end - start, b->charWidths() + start);
- b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false);
+ b->addStyleRun(nullptr, nullptr, minikin::FontStyle{}, start, end, false,
+ nullptr /* keep current locale */, std::vector<minikin::Hyphenator*>());
}
static void nAddReplacementRun(JNIEnv* env, jclass, jlong nativePtr,
@@ -241,9 +246,8 @@ static const JNINativeMethod gMethods[] = {
{"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
{"nLoadHyphenator", "(Ljava/nio/ByteBuffer;III)J", (void*) nLoadHyphenator},
- {"nSetLocales", "(JLjava/lang/String;[J)V", (void*) nSetLocales},
- {"nSetupParagraph", "(J[CIFIF[IIIIZ[II)V", (void*) nSetupParagraph},
- {"nAddStyleRun", "(JJIIZ)F", (void*) nAddStyleRun},
+ {"nSetupParagraph", "(J[CIFIF[IIIIZ[I[I[II)V", (void*) nSetupParagraph},
+ {"nAddStyleRun", "(JJIIZLjava/lang/String;[J)F", (void*) nAddStyleRun},
{"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
{"nAddReplacementRun", "(JIIF)V", (void*) nAddReplacementRun},
{"nGetWidths", "(J[F)V", (void*) nGetWidths},
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index bce10dc2e2fb..15c547f0196c 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -78,7 +78,10 @@ message IncidentProto {
(section).type = SECTION_DUMPSYS,
(section).args = "notification --proto"
];
- android.service.battery.BatteryServiceDumpProto battery = 3006;
+ android.service.battery.BatteryServiceDumpProto battery = 3006 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "battery --proto"
+ ];
android.service.diskstats.DiskStatsServiceDumpProto diskstats = 3007;
android.service.pm.PackageServiceDumpProto package = 3008;
android.service.power.PowerServiceDumpProto power = 3009;
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7416113b4e90..afcb35feaedd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2709,6 +2709,8 @@
<string name="yes">OK</string>
<!-- Preference framework strings. -->
<string name="no">Cancel</string>
+ <!-- Preference framework strings. -->
+ <string name="close">CLOSE</string>
<!-- This is the generic "attention" string to be used in attention dialogs. Typically
combined with setIconAttribute(android.R.attr.alertDialogIcon)
(or setIcon(android.R.drawable.ic_dialog_alert) on legacy versions of the platform) -->
@@ -2841,6 +2843,11 @@
<!-- [CHAR LIMIT=200] Compat mode dialog: hint to re-enable compat mode dialog. -->
<string name="screen_compat_mode_hint">Re-enable this in System settings &gt; Apps &gt; Downloaded.</string>
+ <!-- Text of the alert that is displayed when a top application is killed by lmk. -->
+ <string name="top_app_killed_title">App isn\'t responding</string>
+ <!-- Top app killed by lmk dialog message. -->
+ <string name="top_app_killed_message"><xliff:g id="app_name">%1$s</xliff:g> may be using too much memory.</string>
+
<!-- [CHAR LIMIT=200] Unsupported display size dialog: message. Refers to "Display size" setting. -->
<string name="unsupported_display_size_message"><xliff:g id="app_name">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly.</string>
<!-- [CHAR LIMIT=50] Unsupported display size dialog: check box label. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4f03e7b06d97..96695538b7ce 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1893,6 +1893,9 @@
<java-symbol type="string" name="anr_application_process" />
<java-symbol type="string" name="anr_process" />
<java-symbol type="string" name="anr_title" />
+ <java-symbol type="string" name="top_app_killed_title" />
+ <java-symbol type="string" name="top_app_killed_message" />
+ <java-symbol type="string" name="close" />
<java-symbol type="string" name="car_mode_disable_notification_message" />
<java-symbol type="string" name="car_mode_disable_notification_title" />
<java-symbol type="string" name="chooser_wallpaper" />
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 0209cea4e2e5..40288f5ec8af 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -159,8 +159,10 @@ public class Shader {
if (mNativeInstance == 0) {
mNativeInstance = createNativeInstance(mLocalMatrix == null
? 0 : mLocalMatrix.native_instance);
- mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
- this, mNativeInstance);
+ if (mNativeInstance != 0) {
+ mCleaner = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
+ this, mNativeInstance);
+ }
}
return mNativeInstance;
}
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 17438e5e1cdc..5c6078d566b4 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -36,22 +36,18 @@ void LayerDrawable::onDraw(SkCanvas* canvas) {
bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer) {
// transform the matrix based on the layer
- int saveCount = -1;
- if (!layer->getTransform().isIdentity()) {
- saveCount = canvas->save();
- SkMatrix transform;
- layer->getTransform().copyTo(transform);
- canvas->concat(transform);
- }
-
+ SkMatrix layerTransform;
+ layer->getTransform().copyTo(layerTransform);
sk_sp<SkImage> layerImage;
+ int layerWidth = layer->getWidth();
+ int layerHeight = layer->getHeight();
if (layer->getApi() == Layer::Api::OpenGL) {
GlLayer* glLayer = static_cast<GlLayer*>(layer);
GrGLTextureInfo externalTexture;
externalTexture.fTarget = glLayer->getRenderTarget();
externalTexture.fID = glLayer->getTextureId();
- GrBackendTexture backendTexture(glLayer->getWidth(), glLayer->getHeight(),
- kRGBA_8888_GrPixelConfig, externalTexture);
+ GrBackendTexture backendTexture(layerWidth, layerHeight, kRGBA_8888_GrPixelConfig,
+ externalTexture);
layerImage = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
kPremul_SkAlphaType, nullptr);
} else {
@@ -62,15 +58,29 @@ bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer
}
if (layerImage) {
+ SkMatrix textureMatrix;
+ layer->getTexTransform().copyTo(textureMatrix);
+ //TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed
+ // use bottom left origin and remove flipV and invert transformations.
+ SkMatrix flipV;
+ flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1);
+ textureMatrix.preConcat(flipV);
+ textureMatrix.preScale(1.0f/layerWidth, 1.0f/layerHeight);
+ textureMatrix.postScale(layerWidth, layerHeight);
+ SkMatrix textureMatrixInv;
+ if (!textureMatrix.invert(&textureMatrixInv)) {
+ textureMatrixInv = textureMatrix;
+ }
+
+ SkMatrix matrix = SkMatrix::Concat(textureMatrixInv, layerTransform);
+
SkPaint paint;
paint.setAlpha(layer->getAlpha());
paint.setBlendMode(layer->getMode());
paint.setColorFilter(sk_ref_sp(layer->getColorFilter()));
- canvas->drawImage(layerImage, 0, 0, &paint);
- }
- // restore the original matrix
- if (saveCount >= 0) {
- canvas->restoreToCount(saveCount);
+ // draw image with a shader to avoid save/restore of the matrix
+ paint.setShader(layerImage->makeShader(&matrix));
+ canvas->drawRect(SkRect::MakeWH(layerWidth, layerHeight), paint);
}
return layerImage;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index 40c2b1f3b771..fa2499f6c144 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -52,6 +52,11 @@ import android.util.SparseArray;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnDestroy;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
import java.io.File;
import java.io.IOException;
@@ -180,7 +185,11 @@ public class ApplicationsState {
}
public Session newSession(Callbacks callbacks) {
- Session s = new Session(callbacks);
+ return newSession(callbacks, null);
+ }
+
+ public Session newSession(Callbacks callbacks, Lifecycle lifecycle) {
+ Session s = new Session(callbacks, lifecycle);
synchronized (mEntriesMap) {
mSessions.add(s);
}
@@ -586,7 +595,7 @@ public class ApplicationsState {
.replaceAll("").toLowerCase();
}
- public class Session {
+ public class Session implements LifecycleObserver, OnPause, OnResume, OnDestroy {
final Callbacks mCallbacks;
boolean mResumed;
@@ -600,11 +609,19 @@ public class ApplicationsState {
ArrayList<AppEntry> mLastAppList;
boolean mRebuildForeground;
- Session(Callbacks callbacks) {
+ private final boolean mHasLifecycle;
+
+ Session(Callbacks callbacks, Lifecycle lifecycle) {
mCallbacks = callbacks;
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ mHasLifecycle = true;
+ } else {
+ mHasLifecycle = false;
+ }
}
- public void resume() {
+ public void onResume() {
if (DEBUG_LOCKING) Log.v(TAG, "resume about to acquire lock...");
synchronized (mEntriesMap) {
if (!mResumed) {
@@ -616,7 +633,7 @@ public class ApplicationsState {
if (DEBUG_LOCKING) Log.v(TAG, "...resume releasing lock");
}
- public void pause() {
+ public void onPause() {
if (DEBUG_LOCKING) Log.v(TAG, "pause about to acquire lock...");
synchronized (mEntriesMap) {
if (mResumed) {
@@ -735,8 +752,11 @@ public class ApplicationsState {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
}
- public void release() {
- pause();
+ public void onDestroy() {
+ if (!mHasLifecycle) {
+ // TODO: Legacy, remove this later once all usages are switched to Lifecycle
+ onPause();
+ }
synchronized (mEntriesMap) {
mSessions.remove(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 44e60eed8c7c..a41fd22d4c0b 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -64,6 +64,7 @@ import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.events.activity.DockedFirstAnimationFrameEvent;
import com.android.systemui.recents.events.activity.DockedTopTaskEvent;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
import com.android.systemui.recents.events.activity.UndockingTaskEvent;
@@ -1192,6 +1193,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
}
}
+ public final void onBusEvent(DockedFirstAnimationFrameEvent event) {
+ saveSnapTargetBeforeMinimized(mSnapAlgorithm.getMiddleTarget());
+ }
+
public final void onBusEvent(DockedTopTaskEvent event) {
if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) {
mState.growAfterRecentsDrawn = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index cfe0a4a6005b..6d3bc1df00a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -437,7 +437,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks {
}
private boolean onNavigationTouch(View v, MotionEvent event) {
- mStatusBar.checkUserAutohide(v, event);
+ mStatusBar.checkUserAutohide(event);
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 67500bf4217d..274c024407bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -69,9 +69,6 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.PorterDuff;
@@ -108,7 +105,6 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
-import android.text.TextUtils;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
@@ -127,13 +123,11 @@ import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewParent;
-import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
-import android.view.animation.Interpolator;
import android.widget.DateTimeView;
import android.widget.ImageView;
import android.widget.RemoteViews;
@@ -259,7 +253,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
@@ -279,11 +272,9 @@ public class StatusBar extends SystemUI implements DemoMode,
= SystemProperties.getBoolean("debug.child_notifs", true);
public static final boolean FORCE_REMOTE_INPUT_HISTORY =
SystemProperties.getBoolean("debug.force_remoteinput_history", false);
- private static boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
+ private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
- protected static final int MSG_SHOW_RECENT_APPS = 1019;
protected static final int MSG_HIDE_RECENT_APPS = 1020;
- protected static final int MSG_TOGGLE_RECENTS_APPS = 1021;
protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
@@ -365,10 +356,6 @@ public class StatusBar extends SystemUI implements DemoMode,
/** If true, the lockscreen will show a distinct wallpaper */
private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
- /* If true, the device supports freeform window management.
- * This affects the status bar UI. */
- private static final boolean FREEFORM_WINDOW_MANAGEMENT;
-
/**
* How long to wait before auto-dismissing a notification that was kept for remote input, and
* has now sent a remote input. We auto-dismiss, because the app may not see a reason to cancel
@@ -387,19 +374,14 @@ public class StatusBar extends SystemUI implements DemoMode,
static {
boolean onlyCoreApps;
- boolean freeformWindowManagement;
try {
IPackageManager packageManager =
IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
onlyCoreApps = packageManager.isOnlyCoreApps();
- freeformWindowManagement = packageManager.hasSystemFeature(
- PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT, 0);
} catch (RemoteException e) {
onlyCoreApps = false;
- freeformWindowManagement = false;
}
ONLY_CORE_APPS = onlyCoreApps;
- FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
}
/**
@@ -410,17 +392,17 @@ public class StatusBar extends SystemUI implements DemoMode,
protected boolean mShowLockscreenNotifications;
protected boolean mAllowLockscreenRemoteInput;
- PhoneStatusBarPolicy mIconPolicy;
+ private PhoneStatusBarPolicy mIconPolicy;
- VolumeComponent mVolumeComponent;
- BrightnessMirrorController mBrightnessMirrorController;
+ private VolumeComponent mVolumeComponent;
+ private BrightnessMirrorController mBrightnessMirrorController;
protected FingerprintUnlockController mFingerprintUnlockController;
- LightBarController mLightBarController;
+ private LightBarController mLightBarController;
protected LockscreenWallpaper mLockscreenWallpaper;
- int mNaturalBarHeight = -1;
+ private int mNaturalBarHeight = -1;
- Point mCurrentDisplaySize = new Point();
+ private final Point mCurrentDisplaySize = new Point();
protected StatusBarWindowView mStatusBarWindow;
protected PhoneStatusBarView mStatusBarView;
@@ -431,15 +413,13 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mWakeUpComingFromTouch;
private PointF mWakeUpTouchLocation;
- int mPixelFormat;
- Object mQueueLock = new Object();
+ private final Object mQueueLock = new Object();
protected StatusBarIconController mIconController;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
- View mExpandedContents;
- TextView mNotificationPanelDebugText;
+ private TextView mNotificationPanelDebugText;
/**
* {@code true} if notifications not part of a group should by default be rendered in their
@@ -452,12 +432,10 @@ public class StatusBar extends SystemUI implements DemoMode,
private QSPanel mQSPanel;
// top bar
- protected KeyguardStatusBarView mKeyguardStatusBar;
- boolean mLeaveOpenOnKeyguardHide;
+ private KeyguardStatusBarView mKeyguardStatusBar;
+ private boolean mLeaveOpenOnKeyguardHide;
KeyguardIndicationController mKeyguardIndicationController;
- // Keyguard is going away soon.
- private boolean mKeyguardGoingAway;
// Keyguard is actually fading away now.
protected boolean mKeyguardFadingAway;
protected long mKeyguardFadingAwayDelay;
@@ -469,25 +447,19 @@ public class StatusBar extends SystemUI implements DemoMode,
private View mReportRejectedTouch;
- int mMaxAllowedKeyguardNotifications;
-
- boolean mExpandedVisible;
-
- // the tracker view
- int mTrackingPosition; // the position of the top of the tracking view.
+ private int mMaxAllowedKeyguardNotifications;
- // Tracking finger for opening/closing.
- boolean mTracking;
+ private boolean mExpandedVisible;
- int[] mAbsPos = new int[2];
- ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
+ private final int[] mAbsPos = new int[2];
+ private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
// for disabling the status bar
- int mDisabled1 = 0;
- int mDisabled2 = 0;
+ private int mDisabled1 = 0;
+ private int mDisabled2 = 0;
// tracking calls to View.setSystemUiVisibility()
- int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+ private int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
private final Rect mLastFullscreenStackBounds = new Rect();
private final Rect mLastDockedStackBounds = new Rect();
private final Rect mTmpRect = new Rect();
@@ -495,7 +467,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// last value sent to window manager
private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
- DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+ private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
// XXX: gesture research
private final GestureRecorder mGestureRec = DEBUG_GESTURES
@@ -508,13 +480,15 @@ public class StatusBar extends SystemUI implements DemoMode,
// ensure quick settings is disabled until the current user makes it through the setup wizard
private boolean mUserSetup = false;
- private DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
+ private final DeviceProvisionedListener mUserSetupObserver = new DeviceProvisionedListener() {
@Override
public void onUserSetupChanged() {
final boolean userSetup = mDeviceProvisionedController.isUserSetup(
mDeviceProvisionedController.getCurrentUser());
- if (MULTIUSER_DEBUG) Log.d(TAG, String.format("User setup changed: " +
- "userSetup=%s mUserSetup=%s", userSetup, mUserSetup));
+ if (MULTIUSER_DEBUG) {
+ Log.d(TAG, String.format("User setup changed: userSetup=%s mUserSetup=%s",
+ userSetup, mUserSetup));
+ }
if (userSetup != mUserSetup) {
mUserSetup = userSetup;
@@ -528,7 +502,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- protected H mHandler = createHandler();
+ protected final H mHandler = createHandler();
final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
@@ -537,8 +511,6 @@ public class StatusBar extends SystemUI implements DemoMode,
&& Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HEADS_UP_OFF);
- mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
- mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
if (wasUsing != mUseHeadsUp) {
if (!mUseHeadsUp) {
@@ -566,26 +538,21 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- private boolean mWaitingForKeyguardExit;
protected boolean mDozing;
private boolean mDozingRequested;
protected boolean mScrimSrcModeEnabled;
- public static final Interpolator ALPHA_IN = Interpolators.ALPHA_IN;
- public static final Interpolator ALPHA_OUT = Interpolators.ALPHA_OUT;
-
protected BackDropView mBackdrop;
protected ImageView mBackdropFront, mBackdropBack;
- protected PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
- protected PorterDuffXfermode mSrcOverXferMode =
+ protected final PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
+ protected final PorterDuffXfermode mSrcOverXferMode =
new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
private MediaSessionManager mMediaSessionManager;
private MediaController mMediaController;
private String mMediaNotificationKey;
private MediaMetadata mMediaMetadata;
- private MediaController.Callback mMediaListener
- = new MediaController.Callback() {
+ private final MediaController.Callback mMediaListener = new MediaController.Callback() {
@Override
public void onPlaybackStateChanged(PlaybackState state) {
super.onPlaybackStateChanged(state);
@@ -607,17 +574,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- private final OnChildLocationsChangedListener mOnChildLocationsChangedListener =
- new OnChildLocationsChangedListener() {
- @Override
- public void onChildLocationsChanged(NotificationStackScrollLayout stackScrollLayout) {
- userActivity();
- }
- };
-
- private int mDisabledUnmodified1;
- private int mDisabledUnmodified2;
-
/** Keys of notifications currently visible to the user. */
private final ArraySet<NotificationVisibility> mCurrentlyVisibleNotifications =
new ArraySet<>();
@@ -644,15 +600,6 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mWereIconsJustHidden;
private boolean mBouncerWasShowingWhenHidden;
- public boolean isStartedGoingToSleep() {
- return mStartedGoingToSleep;
- }
-
- /**
- * If set, the device has started going to sleep but isn't fully non-interactive yet.
- */
- protected boolean mStartedGoingToSleep;
-
private final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
new OnChildLocationsChangedListener() {
@Override
@@ -686,7 +633,6 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void run() {
mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
- final String mediaKey = getCurrentMediaNotificationKey();
// 1. Loop over mNotificationData entries:
// A. Keep list of visible notifications.
@@ -743,10 +689,10 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mKeyguardRequested;
private boolean mIsKeyguard;
private LogMaker mStatusBarStateLog;
- private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
+ private final LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
protected NotificationIconAreaController mNotificationIconAreaController;
private boolean mReinflateNotificationsOnUserSwitched;
- private HashMap<String, Entry> mPendingNotifications = new HashMap<>();
+ private final HashMap<String, Entry> mPendingNotifications = new HashMap<>();
private boolean mClearAllEnabled;
@Nullable private View mAmbientIndicationContainer;
private String mKeyToRemoveOnGutsClosed;
@@ -769,20 +715,21 @@ public class StatusBar extends SystemUI implements DemoMode,
goToLockedShade(null);
}
};
- private HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>> mTmpChildOrderMap
- = new HashMap<>();
+ private final HashMap<ExpandableNotificationRow, List<ExpandableNotificationRow>>
+ mTmpChildOrderMap = new HashMap<>();
private RankingMap mLatestRankingMap;
private boolean mNoAnimationOnNextBarModeChange;
private FalsingManager mFalsingManager;
- private KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
- @Override
- public void onDreamingStateChanged(boolean dreaming) {
- if (dreaming) {
- maybeEscalateHeadsUp();
- }
- }
- };
+ private final KeyguardUpdateMonitorCallback mUpdateCallback =
+ new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onDreamingStateChanged(boolean dreaming) {
+ if (dreaming) {
+ maybeEscalateHeadsUp();
+ }
+ }
+ };
private NavigationBarFragment mNavigationBar;
private View mNavigationBarView;
@@ -861,10 +808,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mRecents = getComponent(Recents.class);
- final Configuration currentConfig = res.getConfiguration();
- mLocale = currentConfig.locale;
- mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
-
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mLockPatternUtils = new LockPatternUtils(mContext);
@@ -994,9 +937,6 @@ public class StatusBar extends SystemUI implements DemoMode,
Dependency.get(ConfigurationController.class).addCallback(this);
}
- protected void createIconController() {
- }
-
// ================================================================================
// Constructing the view
// ================================================================================
@@ -1012,16 +952,14 @@ public class StatusBar extends SystemUI implements DemoMode,
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
// into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
- mNotificationPanel = (NotificationPanelView) mStatusBarWindow.findViewById(
- R.id.notification_panel);
- mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
- R.id.notification_stack_scroller);
+ mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
+ mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
mNotificationPanel.setStatusBar(this);
mNotificationPanel.setGroupManager(mGroupManager);
mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
R.id.notification_container_parent));
- mKeyguardStatusBar = (KeyguardStatusBarView) mStatusBarWindow.findViewById(R.id.keyguard_header);
+ mKeyguardStatusBar = mStatusBarWindow.findViewById(R.id.keyguard_header);
mNotificationIconAreaController = SystemUIFactory.getInstance()
.createNotificationIconAreaController(context, this);
@@ -1060,8 +998,7 @@ public class StatusBar extends SystemUI implements DemoMode,
putComponent(HeadsUpManager.class, mHeadsUpManager);
if (MULTIUSER_DEBUG) {
- mNotificationPanelDebugText = (TextView) mNotificationPanel.findViewById(
- R.id.header_debug_info);
+ mNotificationPanelDebugText = mNotificationPanel.findViewById(R.id.header_debug_info);
mNotificationPanelDebugText.setVisibility(View.VISIBLE);
}
@@ -1075,9 +1012,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// no window manager? good luck with that
}
- // figure out which pixel-format to use for the status bar.
- mPixelFormat = PixelFormat.OPAQUE;
-
mStackScroller.setLongPressListener(getNotificationLongClicker());
mStackScroller.setStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
@@ -1087,11 +1021,10 @@ public class StatusBar extends SystemUI implements DemoMode,
inflateEmptyShadeView();
inflateDismissView();
- mExpandedContents = mStackScroller;
- mBackdrop = (BackDropView) mStatusBarWindow.findViewById(R.id.backdrop);
- mBackdropFront = (ImageView) mBackdrop.findViewById(R.id.backdrop_front);
- mBackdropBack = (ImageView) mBackdrop.findViewById(R.id.backdrop_back);
+ mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
+ mBackdropFront = mBackdrop.findViewById(R.id.backdrop_front);
+ mBackdropBack = mBackdrop.findViewById(R.id.backdrop_back);
if (ENABLE_LOCKSCREEN_WALLPAPER) {
mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
@@ -1099,8 +1032,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardIndicationController =
SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
- (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
- mNotificationPanel.getLockIcon());
+ mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
+ mNotificationPanel.getLockIcon());
mNotificationPanel.setKeyguardIndicationController(mKeyguardIndicationController);
@@ -1131,8 +1064,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mNavigationBar.setLightBarController(mLightBarController);
}
- ScrimView scrimBehind = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_behind);
- ScrimView scrimInFront = (ScrimView) mStatusBarWindow.findViewById(R.id.scrim_in_front);
+ ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind);
+ ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
View headsUpScrim = mStatusBarWindow.findViewById(R.id.heads_up_scrim);
mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
scrimBehind, scrimInFront, headsUpScrim, mLockscreenWallpaper,
@@ -1142,13 +1075,10 @@ public class StatusBar extends SystemUI implements DemoMode,
}
});
if (mScrimSrcModeEnabled) {
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
- mScrimController.setDrawBehindAsSrc(asSrc);
- mStackScroller.setDrawBackgroundAsSrc(asSrc);
- }
+ Runnable runnable = () -> {
+ boolean asSrc = mBackdrop.getVisibility() != View.VISIBLE;
+ mScrimController.setDrawBehindAsSrc(asSrc);
+ mStackScroller.setDrawBackgroundAsSrc(asSrc);
};
mBackdrop.setOnVisibilityChangedRunnable(runnable);
runnable.run();
@@ -1170,11 +1100,11 @@ public class StatusBar extends SystemUI implements DemoMode,
if (container != null) {
FragmentHostManager fragmentHostManager = FragmentHostManager.get(container);
ExtensionFragmentListener.attachExtensonToFragment(container, QS.TAG, R.id.qs_frame,
- Dependency.get(ExtensionController.class).newExtension(QS.class)
+ Dependency.get(ExtensionController.class)
+ .newExtension(QS.class)
.withPlugin(QS.class)
- .withFeature(
- PackageManager.FEATURE_AUTOMOTIVE, () -> new CarQSFragment())
- .withDefault(() -> new QSFragment())
+ .withFeature(PackageManager.FEATURE_AUTOMOTIVE, CarQSFragment::new)
+ .withDefault(QSFragment::new)
.build());
final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(mContext, this,
mIconController);
@@ -1276,7 +1206,7 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
protected View.OnTouchListener getStatusBarWindowTouchListener() {
return (v, event) -> {
- checkUserAutohide(v, event);
+ checkUserAutohide(event);
checkRemoteInputOutside(event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mExpandedVisible) {
@@ -1380,8 +1310,7 @@ public class StatusBar extends SystemUI implements DemoMode,
public static SignalClusterView reinflateSignalCluster(View view) {
Context context = view.getContext();
- SignalClusterView signalCluster =
- (SignalClusterView) view.findViewById(R.id.signal_cluster);
+ SignalClusterView signalCluster = view.findViewById(R.id.signal_cluster);
if (signalCluster != null) {
ViewParent parent = signalCluster.getParent();
if (parent instanceof ViewGroup) {
@@ -1421,20 +1350,17 @@ public class StatusBar extends SystemUI implements DemoMode,
mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
- mDismissView.setOnButtonClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mMetricsLogger.action(MetricsEvent.ACTION_DISMISS_ALL_NOTES);
- clearAllNotifications();
- }
+ mDismissView.setOnButtonClickListener(v -> {
+ mMetricsLogger.action(MetricsEvent.ACTION_DISMISS_ALL_NOTES);
+ clearAllNotifications();
});
mStackScroller.setDismissView(mDismissView);
}
protected void createUserSwitcher() {
mKeyguardUserSwitcher = new KeyguardUserSwitcher(mContext,
- (ViewStub) mStatusBarWindow.findViewById(R.id.keyguard_user_switcher),
- mKeyguardStatusBar, mNotificationPanel);
+ mStatusBarWindow.findViewById(R.id.keyguard_user_switcher), mKeyguardStatusBar,
+ mNotificationPanel);
}
protected void inflateStatusBarWindow(Context context) {
@@ -1447,7 +1373,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// animate-swipe all dismissable notifications, then animate the shade closed
int numChildren = mStackScroller.getChildCount();
- final ArrayList<View> viewsToHide = new ArrayList<View>(numChildren);
+ final ArrayList<View> viewsToHide = new ArrayList<>(numChildren);
final ArrayList<ExpandableNotificationRow> viewsToRemove = new ArrayList<>(numChildren);
for (int i = 0; i < numChildren; i++) {
final View child = mStackScroller.getChildAt(i);
@@ -1487,20 +1413,18 @@ public class StatusBar extends SystemUI implements DemoMode,
return;
}
- addPostCollapseAction(new Runnable() {
- @Override
- public void run() {
- mStackScroller.setDismissAllInProgress(false);
- for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
- if (mStackScroller.canChildBeDismissed(rowToRemove)) {
- removeNotification(rowToRemove.getEntry().key, null);
- } else {
- rowToRemove.resetTranslation();
- }
+ addPostCollapseAction(() -> {
+ mStackScroller.setDismissAllInProgress(false);
+ for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
+ if (mStackScroller.canChildBeDismissed(rowToRemove)) {
+ removeNotification(rowToRemove.getEntry().key, null);
+ } else {
+ rowToRemove.resetTranslation();
}
- try {
- mBarService.onClearAllNotifications(mCurrentUserId);
- } catch (Exception ex) { }
+ }
+ try {
+ mBarService.onClearAllNotifications(mCurrentUserId);
+ } catch (Exception ex) {
}
});
@@ -1509,11 +1433,8 @@ public class StatusBar extends SystemUI implements DemoMode,
}
private void performDismissAllAnimations(ArrayList<View> hideAnimatedList) {
- Runnable animationFinishAction = new Runnable() {
- @Override
- public void run() {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
- }
+ Runnable animationFinishAction = () -> {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
};
// let's disable our normal animations
@@ -1632,10 +1553,6 @@ public class StatusBar extends SystemUI implements DemoMode,
SystemServicesProxy.getInstance(mContext).awakenDreamsAsync();
}
- public UserHandle getCurrentUserHandle() {
- return new UserHandle(mCurrentUserId);
- }
-
public void addNotification(StatusBarNotification notification, RankingMap ranking)
throws InflationException {
String key = notification.getKey();
@@ -1746,7 +1663,7 @@ public class StatusBar extends SystemUI implements DemoMode,
boolean deferRemoval = false;
abortExistingInflation(key);
if (mHeadsUpManager.isHeadsUp(key)) {
- // A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
+ // A cancel() in response to a remote input shouldn't be delayed, as it makes the
// sending look longer than it takes.
// Also we should not defer the removal if reordering isn't allowed since otherwise
// some notifications can't disappear before the panel is closed.
@@ -1772,9 +1689,7 @@ public class StatusBar extends SystemUI implements DemoMode,
newHistory = new CharSequence[1];
} else {
newHistory = new CharSequence[oldHistory.length + 1];
- for (int i = 0; i < oldHistory.length; i++) {
- newHistory[i + 1] = oldHistory[i];
- }
+ System.arraycopy(oldHistory, 0, newHistory, 1, oldHistory.length);
}
newHistory[0] = String.valueOf(entry.remoteInputText);
b.setRemoteInputHistory(newHistory);
@@ -1833,7 +1748,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mStackScroller.cleanUpViewState(entry.row);
}
// Let's remove the children if this was a summary
- handleGroupSummaryRemoved(key, ranking);
+ handleGroupSummaryRemoved(key);
StatusBarNotification old = removeNotificationViews(key, ranking);
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
@@ -1857,12 +1772,10 @@ public class StatusBar extends SystemUI implements DemoMode,
*
* This also ensures that the animation looks nice and only consists of a single disappear
* animation instead of multiple.
+ * @param key the key of the notification was removed
*
- * @param key the key of the notification was removed
- * @param ranking the current ranking
*/
- private void handleGroupSummaryRemoved(String key,
- RankingMap ranking) {
+ private void handleGroupSummaryRemoved(String key) {
Entry entry = mNotificationData.get(key);
if (entry != null && entry.row != null
&& entry.row.isSummaryWithChildren()) {
@@ -1873,15 +1786,13 @@ public class StatusBar extends SystemUI implements DemoMode,
}
List<ExpandableNotificationRow> notificationChildren =
entry.row.getNotificationChildren();
- ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
for (int i = 0; i < notificationChildren.size(); i++) {
ExpandableNotificationRow row = notificationChildren.get(i);
if ((row.getStatusBarNotification().getNotification().flags
& Notification.FLAG_FOREGROUND_SERVICE) != 0) {
- // the child is a forground service notification which we can't remove!
+ // the child is a foreground service notification which we can't remove!
continue;
}
- toRemove.add(row);
row.setKeepInParent(true);
// we need to set this state earlier as otherwise we might generate some weird
// animations
@@ -1924,19 +1835,14 @@ public class StatusBar extends SystemUI implements DemoMode,
// Do not modify the notifications during collapse.
if (isCollapsing()) {
- addPostCollapseAction(new Runnable() {
- @Override
- public void run() {
- updateNotificationShade();
- }
- });
+ addPostCollapseAction(this::updateNotificationShade);
return;
}
ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
ArrayList<ExpandableNotificationRow> toShow = new ArrayList<>(activeNotifications.size());
final int N = activeNotifications.size();
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
Entry ent = activeNotifications.get(i);
if (ent.row.isDismissed() || ent.row.isRemoved()) {
// we don't want to update removed notifications because they could
@@ -1980,7 +1886,8 @@ public class StatusBar extends SystemUI implements DemoMode,
for (ExpandableNotificationRow remove : toRemove) {
if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
- // we are only transfering this notification to its parent, don't generate an animation
+ // we are only transferring this notification to its parent, don't generate an
+ // animation
mStackScroller.setChildTransferInProgress(true);
}
if (remove.isSummaryWithChildren()) {
@@ -1992,7 +1899,7 @@ public class StatusBar extends SystemUI implements DemoMode,
removeNotificationChildren();
- for (int i=0; i<toShow.size(); i++) {
+ for (int i = 0; i < toShow.size(); i++) {
View v = toShow.get(i);
if (v.getParent() == null) {
mVisualStabilityManager.notifyViewAddition(v);
@@ -2102,7 +2009,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- // Finally after removing and adding has been beformed we can apply the order.
+ // Finally after removing and adding has been performed we can apply the order.
orderChanged |= parent.applyChildOrder(orderedChildren, mVisualStabilityManager, this);
}
if (orderChanged) {
@@ -2275,10 +2182,11 @@ public class StatusBar extends SystemUI implements DemoMode,
MediaController controller = null;
for (int i = 0; i < N; i++) {
final Entry entry = activeNotifications.get(i);
+
if (isMediaNotification(entry)) {
final MediaSession.Token token =
- entry.notification.getNotification().extras
- .getParcelable(Notification.EXTRA_MEDIA_SESSION);
+ entry.notification.getNotification().extras.getParcelable(
+ Notification.EXTRA_MEDIA_SESSION);
if (token != null) {
MediaController aController = new MediaController(mContext, token);
if (PlaybackState.STATE_PLAYING ==
@@ -2316,7 +2224,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (entry.notification.getPackageName().equals(pkg)) {
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: found controller matching "
- + entry.notification.getKey());
+ + entry.notification.getKey());
}
controller = aController;
mediaNotification = entry;
@@ -2367,12 +2275,8 @@ public class StatusBar extends SystemUI implements DemoMode,
}
private boolean isPlaybackActive(int state) {
- if (state != PlaybackState.STATE_STOPPED
- && state != PlaybackState.STATE_ERROR
- && state != PlaybackState.STATE_NONE) {
- return true;
- }
- return false;
+ return state != PlaybackState.STATE_STOPPED && state != PlaybackState.STATE_ERROR
+ && state != PlaybackState.STATE_NONE;
}
private void clearCurrentMediaNotification() {
@@ -2397,7 +2301,7 @@ public class StatusBar extends SystemUI implements DemoMode,
/**
* Hide the album artwork that is fading out and release its bitmap.
*/
- protected Runnable mHideBackdropFront = new Runnable() {
+ protected final Runnable mHideBackdropFront = new Runnable() {
@Override
public void run() {
if (DEBUG_MEDIA) {
@@ -2549,14 +2453,11 @@ public class StatusBar extends SystemUI implements DemoMode,
.setInterpolator(Interpolators.ACCELERATE_DECELERATE)
.setDuration(300)
.setStartDelay(0)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- mBackdrop.setVisibility(View.GONE);
- mBackdropFront.animate().cancel();
- mBackdropBack.setImageDrawable(null);
- mHandler.post(mHideBackdropFront);
- }
+ .withEndAction(() -> {
+ mBackdrop.setVisibility(View.GONE);
+ mBackdropFront.animate().cancel();
+ mBackdropBack.setImageDrawable(null);
+ mHandler.post(mHideBackdropFront);
});
if (mKeyguardFadingAway) {
mBackdrop.animate()
@@ -2587,8 +2488,6 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void disable(int state1, int state2, boolean animate) {
animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
- mDisabledUnmodified1 = state1;
- mDisabledUnmodified2 = state2;
final int old1 = mDisabled1;
final int diff1 = state1 ^ old1;
mDisabled1 = state1;
@@ -2742,11 +2641,8 @@ public class StatusBar extends SystemUI implements DemoMode,
// make sure that the window stays small for one frame until the touchableRegion is set.
mNotificationPanel.requestLayout();
mStatusBarWindowManager.setForceWindowCollapsed(true);
- mNotificationPanel.post(new Runnable() {
- @Override
- public void run() {
- mStatusBarWindowManager.setForceWindowCollapsed(false);
- }
+ mNotificationPanel.post(() -> {
+ mStatusBarWindowManager.setForceWindowCollapsed(false);
});
}
} else {
@@ -2758,15 +2654,12 @@ public class StatusBar extends SystemUI implements DemoMode,
// we need to keep the panel open artificially, let's wait until the animation
// is finished.
mHeadsUpManager.setHeadsUpGoingAway(true);
- mStackScroller.runAfterAnimationFinished(new Runnable() {
- @Override
- public void run() {
- if (!mHeadsUpManager.hasPinnedHeadsUp()) {
- mStatusBarWindowManager.setHeadsUpShowing(false);
- mHeadsUpManager.setHeadsUpGoingAway(false);
- }
- removeRemoteInputEntriesKeptUntilCollapsed();
+ mStackScroller.runAfterAnimationFinished(() -> {
+ if (!mHeadsUpManager.hasPinnedHeadsUp()) {
+ mStatusBarWindowManager.setHeadsUpShowing(false);
+ mHeadsUpManager.setHeadsUpGoingAway(false);
}
+ removeRemoteInputEntriesKeptUntilCollapsed();
});
}
}
@@ -3033,7 +2926,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarWindowManager.setPanelVisible(true);
visibilityChanged(true);
- mWaitingForKeyguardExit = false;
recomputeDisableFlags(!force /* animate */);
setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
}
@@ -3042,23 +2934,15 @@ public class StatusBar extends SystemUI implements DemoMode,
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
}
- private final Runnable mAnimateCollapsePanels = new Runnable() {
- @Override
- public void run() {
- animateCollapsePanels();
- }
- };
+ private final Runnable mAnimateCollapsePanels = this::animateCollapsePanels;
public void postAnimateCollapsePanels() {
mHandler.post(mAnimateCollapsePanels);
}
public void postAnimateForceCollapsePanels() {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
- }
+ mHandler.post(() -> {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
});
}
@@ -3213,7 +3097,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (SPEW) {
Log.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled1="
- + mDisabled1 + " mDisabled2=" + mDisabled2 + " mTracking=" + mTracking);
+ + mDisabled1 + " mDisabled2=" + mDisabled2);
} else if (CHATTY) {
if (event.getAction() != MotionEvent.ACTION_MOVE) {
Log.d(TAG, String.format(
@@ -3298,10 +3182,8 @@ public class StatusBar extends SystemUI implements DemoMode,
sbModeChanged = sbMode != -1;
if (sbModeChanged && sbMode != mStatusBarMode) {
- if (sbMode != mStatusBarMode) {
- mStatusBarMode = sbMode;
- checkBarModes();
- }
+ mStatusBarMode = sbMode;
+ checkBarModes();
touchAutoHide();
}
@@ -3388,12 +3270,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- private final Runnable mCheckBarModes = new Runnable() {
- @Override
- public void run() {
- checkBarModes();
- }
- };
+ private final Runnable mCheckBarModes = this::checkBarModes;
public void setInteracting(int barWindow, boolean interacting) {
final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
@@ -3452,7 +3329,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- void checkUserAutohide(View v, MotionEvent event) {
+ void checkUserAutohide(MotionEvent event) {
if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0 // a transient bar is revealed
&& event.getAction() == MotionEvent.ACTION_OUTSIDE // touch outside the source bar
&& event.getX() == 0 && event.getY() == 0 // a touch outside both bars
@@ -3519,9 +3396,7 @@ public class StatusBar extends SystemUI implements DemoMode,
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
synchronized (mQueueLock) {
pw.println("Current Status Bar state:");
- pw.println(" mExpandedVisible=" + mExpandedVisible
- + ", mTrackingPosition=" + mTrackingPosition);
- pw.println(" mTracking=" + mTracking);
+ pw.println(" mExpandedVisible=" + mExpandedVisible);
pw.println(" mDisplayMetrics=" + mDisplayMetrics);
pw.println(" mStackScroller: " + viewInfo(mStackScroller));
pw.println(" mStackScroller: " + viewInfo(mStackScroller)
@@ -3609,16 +3484,12 @@ public class StatusBar extends SystemUI implements DemoMode,
if (false) {
pw.println("see the logcat for a dump of the views we have created.");
// must happen on ui thread
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mStatusBarView.getLocationOnScreen(mAbsPos);
- Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
- + ") " + mStatusBarView.getWidth() + "x"
- + getStatusBarHeight());
- mStatusBarView.debug();
- }
- });
+ mHandler.post(() -> {
+ mStatusBarView.getLocationOnScreen(mAbsPos);
+ Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1] +
+ ") " + mStatusBarView.getWidth() + "x" + getStatusBarHeight());
+ mStatusBarView.debug();
+ });
}
}
@@ -3698,49 +3569,43 @@ public class StatusBar extends SystemUI implements DemoMode,
final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
mContext, intent, mCurrentUserId);
- Runnable runnable = new Runnable() {
- @Override
- public void run() {
- mAssistManager.hideAssist();
- intent.setFlags(
- Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- int result = ActivityManager.START_CANCELED;
- ActivityOptions options = new ActivityOptions(getActivityOptions());
- options.setDisallowEnterPictureInPictureWhileLaunching(
- disallowEnterPictureInPictureWhileLaunching);
- if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
- // Normally an activity will set it's requested rotation
- // animation on its window. However when launching an activity
- // causes the orientation to change this is too late. In these cases
- // the default animation is used. This doesn't look good for
- // the camera (as it rotates the camera contents out of sync
- // with physical reality). So, we ask the WindowManager to
- // force the crossfade animation if an orientation change
- // happens to occur during the launch.
- options.setRotationAnimationHint(
- WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
- }
- try {
- result = ActivityManager.getService().startActivityAsUser(
- null, mContext.getBasePackageName(),
- intent,
- intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
- options.toBundle(), UserHandle.CURRENT.getIdentifier());
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to start activity", e);
- }
- if (callback != null) {
- callback.onActivityStarted(result);
- }
+ Runnable runnable = () -> {
+ mAssistManager.hideAssist();
+ intent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ int result = ActivityManager.START_CANCELED;
+ ActivityOptions options = new ActivityOptions(getActivityOptions());
+ options.setDisallowEnterPictureInPictureWhileLaunching(
+ disallowEnterPictureInPictureWhileLaunching);
+ if (intent == KeyguardBottomAreaView.INSECURE_CAMERA_INTENT) {
+ // Normally an activity will set it's requested rotation
+ // animation on its window. However when launching an activity
+ // causes the orientation to change this is too late. In these cases
+ // the default animation is used. This doesn't look good for
+ // the camera (as it rotates the camera contents out of sync
+ // with physical reality). So, we ask the WindowManager to
+ // force the crossfade animation if an orientation change
+ // happens to occur during the launch.
+ options.setRotationAnimationHint(
+ WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS);
+ }
+ try {
+ result = ActivityManager.getService().startActivityAsUser(
+ null, mContext.getBasePackageName(),
+ intent,
+ intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
+ options.toBundle(), UserHandle.CURRENT.getIdentifier());
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to start activity", e);
+ }
+ if (callback != null) {
+ callback.onActivityStarted(result);
}
};
- Runnable cancelRunnable = new Runnable() {
- @Override
- public void run() {
- if (callback != null) {
- callback.onActivityStarted(ActivityManager.START_CANCELED);
- }
+ Runnable cancelRunnable = () -> {
+ if (callback != null) {
+ callback.onActivityStarted(ActivityManager.START_CANCELED);
}
};
executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShade,
@@ -3785,7 +3650,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}, cancelAction, afterKeyguardGone);
}
- private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.v(TAG, "onReceive: " + intent);
@@ -3814,7 +3679,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
+ private final BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG) Log.v(TAG, "onReceive: " + intent);
@@ -3975,7 +3840,6 @@ public class StatusBar extends SystemUI implements DemoMode,
* The LEDs are turned off when the notification panel is shown, even just a little bit.
* See also StatusBar.setPanelExpanded for another place where we attempt to do this.
*/
- // Old BaseStatusBar.handleVisibileToUserChanged
private void handleVisibleToUserChangedImpl(boolean visibleToUser) {
try {
if (visibleToUser) {
@@ -4000,8 +3864,8 @@ public class StatusBar extends SystemUI implements DemoMode,
// Report all notifications as invisible and turn down the
// reporter.
if (!mCurrentlyVisibleNotifications.isEmpty()) {
- logNotificationVisibilityChanges(Collections.<NotificationVisibility>emptyList(),
- mCurrentlyVisibleNotifications);
+ logNotificationVisibilityChanges(
+ Collections.emptyList(), mCurrentlyVisibleNotifications);
recycleAllVisibilityObjects(mCurrentlyVisibleNotifications);
}
mHandler.removeCallbacks(mVisibilityReporter);
@@ -4108,7 +3972,7 @@ public class StatusBar extends SystemUI implements DemoMode,
vib.vibrate(250, VIBRATION_ATTRIBUTES);
}
- Runnable mStartTracing = new Runnable() {
+ final Runnable mStartTracing = new Runnable() {
@Override
public void run() {
vibrate();
@@ -4119,13 +3983,10 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- Runnable mStopTracing = new Runnable() {
- @Override
- public void run() {
- android.os.Debug.stopMethodTracing();
- Log.d(TAG, "stopTracing");
- vibrate();
- }
+ final Runnable mStopTracing = () -> {
+ android.os.Debug.stopMethodTracing();
+ Log.d(TAG, "stopTracing");
+ vibrate();
};
@Override
@@ -4152,40 +4013,6 @@ public class StatusBar extends SystemUI implements DemoMode,
startActivityDismissingKeyguard(intent, onlyProvisioned, true /* dismissShade */);
}
- private static class FastColorDrawable extends Drawable {
- private final int mColor;
-
- public FastColorDrawable(int color) {
- mColor = 0xff000000 | color;
- }
-
- @Override
- public void draw(Canvas canvas) {
- canvas.drawColor(mColor, PorterDuff.Mode.SRC);
- }
-
- @Override
- public void setAlpha(int alpha) {
- }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.OPAQUE;
- }
-
- @Override
- public void setBounds(int left, int top, int right, int bottom) {
- }
-
- @Override
- public void setBounds(Rect bounds) {
- }
- }
-
public void destroy() {
// Begin old BaseStatusBar.destroy().
mContext.unregisterReceiver(mBaseBroadcastReceiver);
@@ -4403,31 +4230,23 @@ public class StatusBar extends SystemUI implements DemoMode,
Runnable endRunnable) {
mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
mLaunchTransitionEndRunnable = endRunnable;
- Runnable hideRunnable = new Runnable() {
- @Override
- public void run() {
- mLaunchTransitionFadingAway = true;
- if (beforeFading != null) {
- beforeFading.run();
- }
- mScrimController.forceHideScrims(true /* hide */, false /* animated */);
- updateMediaMetaData(false, true);
- mNotificationPanel.setAlpha(1);
- mStackScroller.setParentNotFullyVisible(true);
- mNotificationPanel.animate()
- .alpha(0)
- .setStartDelay(FADE_KEYGUARD_START_DELAY)
- .setDuration(FADE_KEYGUARD_DURATION)
- .withLayer()
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- onLaunchTransitionFadingEnded();
- }
- });
- mCommandQueue.appTransitionStarting(SystemClock.uptimeMillis(),
- LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
- }
+ Runnable hideRunnable = () -> {
+ mLaunchTransitionFadingAway = true;
+ if (beforeFading != null) {
+ beforeFading.run();
+ }
+ mScrimController.forceHideScrims(true /* hide */, false /* animated */);
+ updateMediaMetaData(false, true);
+ mNotificationPanel.setAlpha(1);
+ mStackScroller.setParentNotFullyVisible(true);
+ mNotificationPanel.animate()
+ .alpha(0)
+ .setStartDelay(FADE_KEYGUARD_START_DELAY)
+ .setDuration(FADE_KEYGUARD_DURATION)
+ .withLayer()
+ .withEndAction(this::onLaunchTransitionFadingEnded);
+ mCommandQueue.appTransitionStarting(SystemClock.uptimeMillis(),
+ LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
};
if (mNotificationPanel.isLaunchTransitionRunning()) {
mNotificationPanel.setLaunchTransitionEndRunnable(hideRunnable);
@@ -4556,7 +4375,6 @@ public class StatusBar extends SystemUI implements DemoMode,
// Treat Keyguard exit animation as an app transition to achieve nice transition for status
// bar.
- mKeyguardGoingAway = true;
mKeyguardMonitor.notifyKeyguardGoingAway(true);
mCommandQueue.appTransitionPending(true);
}
@@ -4565,14 +4383,13 @@ public class StatusBar extends SystemUI implements DemoMode,
* Notifies the status bar the Keyguard is fading away with the specified timings.
*
* @param startTime the start time of the animations in uptime millis
- * @param delay the precalculated animation delay in miliseconds
+ * @param delay the precalculated animation delay in milliseconds
* @param fadeoutDuration the duration of the exit animation, in milliseconds
*/
public void setKeyguardFadingAway(long startTime, long delay, long fadeoutDuration) {
mKeyguardFadingAway = true;
mKeyguardFadingAwayDelay = delay;
mKeyguardFadingAwayDuration = fadeoutDuration;
- mWaitingForKeyguardExit = false;
mCommandQueue.appTransitionStarting(startTime + fadeoutDuration
- LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
@@ -4592,14 +4409,9 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
public void finishKeyguardFadingAway() {
mKeyguardFadingAway = false;
- mKeyguardGoingAway = false;
mKeyguardMonitor.notifyKeyguardDoneFading();
}
- public void stopWaitingForKeyguardExit() {
- mWaitingForKeyguardExit = false;
- }
-
private void updatePublicMode() {
final boolean showingKeyguard = mStatusBarKeyguardViewManager.isShowing();
final boolean devicePublic = showingKeyguard
@@ -4813,7 +4625,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
protected void showBouncer() {
- mWaitingForKeyguardExit = mStatusBarKeyguardViewManager.isShowing();
mStatusBarKeyguardViewManager.dismiss();
}
@@ -4830,7 +4641,7 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void onActivated(ActivatableNotificationView view) {
- onActivated((View)view);
+ onActivated((View) view);
mStackScroller.setActivatedChild(view);
}
@@ -5132,51 +4943,41 @@ public class StatusBar extends SystemUI implements DemoMode,
updateNotifications();
if (mPendingWorkRemoteInputView != null && !isAnyProfilePublicMode()) {
// Expand notification panel and the notification row, then click on remote input view
- final Runnable clickPendingViewRunnable = new Runnable() {
- @Override
- public void run() {
- final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
- if (pendingWorkRemoteInputView == null) {
+ final Runnable clickPendingViewRunnable = () -> {
+ final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
+ if (pendingWorkRemoteInputView == null) {
+ return;
+ }
+
+ // Climb up the hierarchy until we get to the container for this row.
+ ViewParent p = pendingWorkRemoteInputView.getParent();
+ while (!(p instanceof ExpandableNotificationRow)) {
+ if (p == null) {
return;
}
+ p = p.getParent();
+ }
- // Climb up the hierarchy until we get to the container for this row.
- ViewParent p = pendingWorkRemoteInputView.getParent();
- while (!(p instanceof ExpandableNotificationRow)) {
- if (p == null) {
- return;
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
+ ViewParent viewParent = row.getParent();
+ if (viewParent instanceof NotificationStackScrollLayout) {
+ final NotificationStackScrollLayout scrollLayout =
+ (NotificationStackScrollLayout) viewParent;
+ row.makeActionsVisibile();
+ row.post(() -> {
+ final Runnable finishScrollingCallback = () -> {
+ mPendingWorkRemoteInputView.callOnClick();
+ mPendingWorkRemoteInputView = null;
+ scrollLayout.setFinishScrollingCallback(null);
+ };
+ if (scrollLayout.scrollTo(row)) {
+ // It scrolls! So call it when it's finished.
+ scrollLayout.setFinishScrollingCallback(finishScrollingCallback);
+ } else {
+ // It does not scroll, so call it now!
+ finishScrollingCallback.run();
}
- p = p.getParent();
- }
-
- final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
- ViewParent viewParent = row.getParent();
- if (viewParent instanceof NotificationStackScrollLayout) {
- final NotificationStackScrollLayout scrollLayout =
- (NotificationStackScrollLayout) viewParent;
- row.makeActionsVisibile();
- row.post(new Runnable() {
- @Override
- public void run() {
- final Runnable finishScrollingCallback = new Runnable() {
- @Override
- public void run() {
- mPendingWorkRemoteInputView.callOnClick();
- mPendingWorkRemoteInputView = null;
- scrollLayout.setFinishScrollingCallback(null);
- }
- };
- if (scrollLayout.scrollTo(row)) {
- // It scrolls! So call it when it's finished.
- scrollLayout.setFinishScrollingCallback(
- finishScrollingCallback);
- } else {
- // It does not scroll, so call it now!
- finishScrollingCallback.run();
- }
- }
- });
- }
+ });
}
};
mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
@@ -5239,7 +5040,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+ final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedGoingToSleep() {
mNotificationPanel.onAffordanceLaunchEnded();
@@ -5262,12 +5063,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// This gets executed before we will show Keyguard, so post it in order that the state
// is correct.
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onCameraLaunchGestureDetected(mLastCameraLaunchSource);
- }
- });
+ mHandler.post(() -> onCameraLaunchGestureDetected(mLastCameraLaunchSource));
}
updateIsKeyguard();
}
@@ -5293,7 +5089,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
+ final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@Override
public void onScreenTurningOn() {
mFalsingManager.onScreenTurningOn();
@@ -5490,7 +5286,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
private final class DozeServiceHost implements DozeHost {
- private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+ private final ArrayList<Callback> mCallbacks = new ArrayList<>();
private boolean mAnimateWakeup;
private boolean mIgnoreTouchWhilePulsing;
@@ -5703,7 +5499,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationData mNotificationData;
protected NotificationStackScrollLayout mStackScroller;
- protected NotificationGroupManager mGroupManager = new NotificationGroupManager();
+ protected final NotificationGroupManager mGroupManager = new NotificationGroupManager();
protected RemoteInputController mRemoteInputController;
@@ -5713,34 +5509,30 @@ public class StatusBar extends SystemUI implements DemoMode,
private AboveShelfObserver mAboveShelfObserver;
// handling reordering
- protected VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
+ protected final VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
protected int mCurrentUserId = 0;
- final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
+ final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
- protected int mLayoutDirection = -1; // invalid
protected AccessibilityManager mAccessibilityManager;
protected boolean mDeviceInteractive;
protected boolean mVisible;
- protected ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>();
- protected ArraySet<Entry> mRemoteInputEntriesToRemoveOnCollapse = new ArraySet<>();
+ protected final ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>();
+ protected final ArraySet<Entry> mRemoteInputEntriesToRemoveOnCollapse = new ArraySet<>();
/**
* Notifications with keys in this set are not actually around anymore. We kept them around
* when they were canceled in response to a remote input interaction. This allows us to show
* what you replied and allows you to continue typing into it.
*/
- protected ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
+ protected final ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
// mScreenOnFromKeyguard && mVisible.
private boolean mVisibleToUser;
- private Locale mLocale;
-
protected boolean mUseHeadsUp = false;
- protected boolean mHeadsUpTicker = false;
protected boolean mDisableNotificationAlerts = false;
protected DevicePolicyManager mDevicePolicyManager;
@@ -5775,13 +5567,11 @@ public class StatusBar extends SystemUI implements DemoMode,
private NotificationGuts mNotificationGutsExposed;
private MenuItem mGutsMenuItem;
- private KeyboardShortcuts mKeyboardShortcuts;
-
protected NotificationShelf mNotificationShelf;
protected DismissView mDismissView;
protected EmptyShadeView mEmptyShadeView;
- private NotificationClicker mNotificationClicker = new NotificationClicker();
+ private final NotificationClicker mNotificationClicker = new NotificationClicker();
protected AssistManager mAssistManager;
@@ -5841,15 +5631,14 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
+ private final RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
@Override
public boolean onClickHandler(
final View view, final PendingIntent pendingIntent, final Intent fillInIntent) {
wakeUpIfDozing(SystemClock.uptimeMillis(), view);
-
- if (handleRemoteInput(view, pendingIntent, fillInIntent)) {
+ if (handleRemoteInput(view, pendingIntent)) {
return true;
}
@@ -5867,33 +5656,29 @@ public class StatusBar extends SystemUI implements DemoMode,
}
final boolean isActivity = pendingIntent.isActivity();
if (isActivity) {
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
mContext, pendingIntent.getIntent(), mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- try {
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
-
- boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
+ dismissKeyguardThenExecute(() -> {
+ try {
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
- // close the shade if it was open
- if (handled && !mNotificationPanel.isFullyCollapsed()) {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */);
- visibilityChanged(false);
- mAssistManager.hideAssist();
+ boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
- // Wait for activity start.
- return true;
- } else {
- return false;
- }
+ // close the shade if it was open
+ if (handled && !mNotificationPanel.isFullyCollapsed()) {
+ animateCollapsePanels(
+ CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
+ visibilityChanged(false);
+ mAssistManager.hideAssist();
+ // Wait for activity start.
+ return true;
+ } else {
+ return false;
}
+
}, afterKeyguardGone);
return true;
} else {
@@ -5938,7 +5723,7 @@ public class StatusBar extends SystemUI implements DemoMode,
WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY);
}
- private boolean handleRemoteInput(View view, PendingIntent pendingIntent, Intent fillInIntent) {
+ private boolean handleRemoteInput(View view, PendingIntent pendingIntent) {
Object tag = view.getTag(com.android.internal.R.id.remote_input_tag);
RemoteInput[] inputs = null;
if (tag instanceof RemoteInput[]) {
@@ -6053,7 +5838,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
updateCurrentProfilesCache();
- if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
+ Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
updateLockscreenNotificationSetting();
@@ -6076,8 +5861,7 @@ public class StatusBar extends SystemUI implements DemoMode,
Toast toast = Toast.makeText(mContext,
R.string.managed_profile_foreground_toast,
Toast.LENGTH_SHORT);
- TextView text = (TextView) toast.getView().findViewById(
- android.R.id.message);
+ TextView text = toast.getView().findViewById(android.R.id.message);
text.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.stat_sys_managed_profile_status, 0, 0, 0);
int paddingPx = mContext.getResources().getDimensionPixelSize(
@@ -6153,15 +5937,12 @@ public class StatusBar extends SystemUI implements DemoMode,
return;
}
final RankingMap currentRanking = getCurrentRanking();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- for (StatusBarNotification sbn : notifications) {
- try {
- addNotification(sbn, currentRanking);
- } catch (InflationException e) {
- handleInflationException(sbn, e);
- }
+ mHandler.post(() -> {
+ for (StatusBarNotification sbn : notifications) {
+ try {
+ addNotification(sbn, currentRanking);
+ } catch (InflationException e) {
+ handleInflationException(sbn, e);
}
}
});
@@ -6172,40 +5953,37 @@ public class StatusBar extends SystemUI implements DemoMode,
final RankingMap rankingMap) {
if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- processForRemoteInput(sbn.getNotification());
- String key = sbn.getKey();
- mKeysKeptForRemoteInput.remove(key);
- boolean isUpdate = mNotificationData.get(key) != null;
- // In case we don't allow child notifications, we ignore children of
- // notifications that have a summary, since we're not going to show them
- // anyway. This is true also when the summary is canceled,
- // because children are automatically canceled by NoMan in that case.
- if (!ENABLE_CHILD_NOTIFICATIONS
+ mHandler.post(() -> {
+ processForRemoteInput(sbn.getNotification());
+ String key = sbn.getKey();
+ mKeysKeptForRemoteInput.remove(key);
+ boolean isUpdate = mNotificationData.get(key) != null;
+ // In case we don't allow child notifications, we ignore children of
+ // notifications that have a summary, since we're not going to show them
+ // anyway. This is true also when the summary is canceled,
+ // because children are automatically canceled by NoMan in that case.
+ if (!ENABLE_CHILD_NOTIFICATIONS
&& mGroupManager.isChildInGroupWithSummary(sbn)) {
- if (DEBUG) {
- Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
- }
+ if (DEBUG) {
+ Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
+ }
- // Remove existing notification to avoid stale data.
- if (isUpdate) {
- removeNotification(key, rankingMap);
- } else {
- mNotificationData.updateRanking(rankingMap);
- }
- return;
+ // Remove existing notification to avoid stale data.
+ if (isUpdate) {
+ removeNotification(key, rankingMap);
+ } else {
+ mNotificationData.updateRanking(rankingMap);
}
- try {
- if (isUpdate) {
- updateNotification(sbn, rankingMap);
- } else {
- addNotification(sbn, rankingMap);
- }
- } catch (InflationException e) {
- handleInflationException(sbn, e);
+ return;
+ }
+ try {
+ if (isUpdate) {
+ updateNotification(sbn, rankingMap);
+ } else {
+ addNotification(sbn, rankingMap);
}
+ } catch (InflationException e) {
+ handleInflationException(sbn, e);
}
});
}
@@ -6253,7 +6031,7 @@ public class StatusBar extends SystemUI implements DemoMode,
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
return;
}
- Log.d(TAG, "disabling lockecreen notifications and alerting the user");
+ Log.d(TAG, "disabling lockscreen notifications and alerting the user");
// disable lockscreen notifications until user acts on the banner.
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
@@ -6294,11 +6072,10 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override // NotificationData.Environment
public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
- final int thisUserId = mCurrentUserId;
final int notificationUserId = n.getUserId();
if (DEBUG && MULTIUSER_DEBUG) {
- Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
- n, thisUserId, notificationUserId));
+ Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d", n,
+ mCurrentUserId, notificationUserId));
}
return isCurrentProfile(notificationUserId);
}
@@ -6346,21 +6123,15 @@ public class StatusBar extends SystemUI implements DemoMode,
}
private void startNotificationGutsIntent(final Intent intent, final int appUid) {
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- TaskStackBuilder.create(mContext)
- .addNextIntentWithParentStack(intent)
- .startActivities(getActivityOptions(),
- new UserHandle(UserHandle.getUserId(appUid)));
- }
- });
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
- return true;
- }
+ dismissKeyguardThenExecute(() -> {
+ AsyncTask.execute(() -> {
+ TaskStackBuilder.create(mContext)
+ .addNextIntentWithParentStack(intent)
+ .startActivities(getActivityOptions(),
+ new UserHandle(UserHandle.getUserId(appUid)));
+ });
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
+ return true;
}, false /* afterKeyguardGone */);
}
@@ -6431,7 +6202,7 @@ public class StatusBar extends SystemUI implements DemoMode,
startNotificationGutsIntent(intent, sbn.getUid());
};
final View.OnClickListener onDoneClick = (View v) -> {
- saveAndCloseNotificationMenu(info, row, guts, v);
+ saveAndCloseNotificationMenu(row, guts, v);
};
final NotificationInfo.CheckSaveListener checkSaveListener =
(Runnable saveImportance) -> {
@@ -6448,7 +6219,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
- ArraySet<NotificationChannel> channels = new ArraySet<NotificationChannel>();
+ ArraySet<NotificationChannel> channels = new ArraySet<>();
channels.add(row.getEntry().channel);
if (row.isSummaryWithChildren()) {
// If this is a summary, then add in the children notification channels for the
@@ -6476,7 +6247,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- private void saveAndCloseNotificationMenu(NotificationInfo info,
+ private void saveAndCloseNotificationMenu(
ExpandableNotificationRow row, NotificationGuts guts, View done) {
guts.resetFalsingCheck();
int[] rowLocation = new int[2];
@@ -6645,13 +6416,6 @@ public class StatusBar extends SystemUI implements DemoMode,
updateHideIconsForBouncer(true /* animate */);
}
- protected void sendCloseSystemWindows(String reason) {
- try {
- ActivityManager.getService().closeSystemDialogs(reason);
- } catch (RemoteException e) {
- }
- }
-
protected void toggleKeyboardShortcuts(int deviceId) {
KeyboardShortcuts.toggle(mContext, deviceId);
}
@@ -6753,18 +6517,6 @@ public class StatusBar extends SystemUI implements DemoMode,
return isLockscreenPublicMode(userId);
}
- public void onNotificationClear(StatusBarNotification notification) {
- try {
- mBarService.onNotificationClear(
- notification.getPackageName(),
- notification.getTag(),
- notification.getId(),
- notification.getUserId());
- } catch (android.os.RemoteException ex) {
- // oh well
- }
- }
-
/**
* Called when the notification panel layouts
*/
@@ -6922,49 +6674,42 @@ public class StatusBar extends SystemUI implements DemoMode,
public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
if (!isDeviceProvisioned()) return;
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
final boolean afterKeyguardGone = intent.isActivity()
&& PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- new Thread() {
- @Override
- public void run() {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- try {
- intent.send(null, 0, null, null, null, null, getActivityOptions());
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here.
- // Just log the exception message.
- Log.w(TAG, "Sending intent failed: " + e);
+ dismissKeyguardThenExecute(() -> {
+ new Thread(() -> {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ try {
+ intent.send(null, 0, null, null, null, null, getActivityOptions());
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here.
+ // Just log the exception message.
+ Log.w(TAG, "Sending intent failed: " + e);
- // TODO: Dismiss Keyguard.
- }
- if (intent.isActivity()) {
- mAssistManager.hideAssist();
- }
- }
- }.start();
+ // TODO: Dismiss Keyguard.
+ }
+ if (intent.isActivity()) {
+ mAssistManager.hideAssist();
+ }
+ }).start();
- if (!mNotificationPanel.isFullyCollapsed()) {
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
+ if (!mNotificationPanel.isFullyCollapsed()) {
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
+ true /* delayed */);
+ visibilityChanged(false);
- return true;
- } else {
- return false;
- }
+ return true;
+ } else {
+ return false;
}
}, afterKeyguardGone);
}
@@ -7002,130 +6747,110 @@ public class StatusBar extends SystemUI implements DemoMode,
// Mark notification for one frame.
row.setJustClicked(true);
- DejankUtils.postAfterTraversal(new Runnable() {
- @Override
- public void run() {
- row.setJustClicked(false);
- }
- });
+ DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
final boolean afterKeyguardGone = intent.isActivity()
&& PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
- // Release the HUN notification to the shade.
+ dismissKeyguardThenExecute(() -> {
+ if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
+ // Release the HUN notification to the shade.
- if (isPanelFullyCollapsed()) {
- HeadsUpManager.setIsClickedNotification(row, true);
- }
- //
- // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
- // become canceled shortly by NoMan, but we can't assume that.
- mHeadsUpManager.releaseImmediately(notificationKey);
+ if (isPanelFullyCollapsed()) {
+ HeadsUpManager.setIsClickedNotification(row, true);
}
- StatusBarNotification parentToCancel = null;
- if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
- StatusBarNotification summarySbn = mGroupManager.getLogicalGroupSummary(sbn)
- .getStatusBarNotification();
- if (shouldAutoCancel(summarySbn)) {
- parentToCancel = summarySbn;
- }
+ //
+ // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
+ // become canceled shortly by NoMan, but we can't assume that.
+ mHeadsUpManager.releaseImmediately(notificationKey);
+ }
+ StatusBarNotification parentToCancel = null;
+ if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
+ StatusBarNotification summarySbn =
+ mGroupManager.getLogicalGroupSummary(sbn).getStatusBarNotification();
+ if (shouldAutoCancel(summarySbn)) {
+ parentToCancel = summarySbn;
}
- final StatusBarNotification parentToCancelFinal = parentToCancel;
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- if (intent != null) {
- // If we are launching a work activity and require to launch
- // separate work challenge, we defer the activity action and cancel
- // notification until work challenge is unlocked.
- if (intent.isActivity()) {
- final int userId = intent.getCreatorUserHandle()
- .getIdentifier();
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
- && mKeyguardManager.isDeviceLocked(userId)) {
- // TODO(b/28935539): should allow certain activities to
- // bypass work challenge
- if (startWorkChallengeIfNecessary(userId,
- intent.getIntentSender(), notificationKey)) {
- // Show work challenge, do not run PendingIntent and
- // remove notification
- return;
- }
- }
- }
- try {
- intent.send(null, 0, null, null, null, null,
- getActivityOptions());
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here.
- // Just log the exception message.
- Log.w(TAG, "Sending contentIntent failed: " + e);
-
- // TODO: Dismiss Keyguard.
- }
- if (intent.isActivity()) {
- mAssistManager.hideAssist();
+ }
+ final StatusBarNotification parentToCancelFinal = parentToCancel;
+ final Runnable runnable = () -> {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ if (intent != null) {
+ // If we are launching a work activity and require to launch
+ // separate work challenge, we defer the activity action and cancel
+ // notification until work challenge is unlocked.
+ if (intent.isActivity()) {
+ final int userId = intent.getCreatorUserHandle().getIdentifier();
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+ && mKeyguardManager.isDeviceLocked(userId)) {
+ // TODO(b/28935539): should allow certain activities to
+ // bypass work challenge
+ if (startWorkChallengeIfNecessary(userId, intent.getIntentSender(),
+ notificationKey)) {
+ // Show work challenge, do not run PendingIntent and
+ // remove notification
+ return;
}
}
+ }
+ try {
+ intent.send(null, 0, null, null, null, null, getActivityOptions());
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here.
+ // Just log the exception message.
+ Log.w(TAG, "Sending contentIntent failed: " + e);
- try {
- mBarService.onNotificationClick(notificationKey);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- if (parentToCancelFinal != null) {
- // We have to post it to the UI thread for synchronization
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Runnable removeRunnable = new Runnable() {
- @Override
- public void run() {
- performRemoveNotification(parentToCancelFinal);
- }
- };
- if (isCollapsing()) {
- // To avoid lags we're only performing the remove
- // after the shade was collapsed
- addPostCollapseAction(removeRunnable);
- } else {
- removeRunnable.run();
- }
- }
- });
- }
+ // TODO: Dismiss Keyguard.
+ }
+ if (intent.isActivity()) {
+ mAssistManager.hideAssist();
}
- };
+ }
- if (mStatusBarKeyguardViewManager.isShowing()
- && mStatusBarKeyguardViewManager.isOccluded()) {
- mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
- } else {
- new Thread(runnable).start();
+ try {
+ mBarService.onNotificationClick(notificationKey);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
}
+ if (parentToCancelFinal != null) {
+ // We have to post it to the UI thread for synchronization
+ mHandler.post(() -> {
+ Runnable removeRunnable =
+ () -> performRemoveNotification(parentToCancelFinal);
+ if (isCollapsing()) {
+ // To avoid lags we're only performing the remove
+ // after the shade was collapsed
+ addPostCollapseAction(removeRunnable);
+ } else {
+ removeRunnable.run();
+ }
+ });
+ }
+ };
- if (!mNotificationPanel.isFullyCollapsed()) {
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
+ if (mStatusBarKeyguardViewManager.isShowing()
+ && mStatusBarKeyguardViewManager.isOccluded()) {
+ mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+ } else {
+ new Thread(runnable).start();
+ }
- return true;
- } else {
- return false;
- }
+ if (!mNotificationPanel.isFullyCollapsed()) {
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
+ true /* delayed */);
+ visibilityChanged(false);
+
+ return true;
+ } else {
+ return false;
}
}, afterKeyguardGone);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index bbce751dcdfd..09828dcd9dc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -225,7 +225,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
if (mShowing) {
if (mOccluded && !mDozing) {
mStatusBar.hideKeyguard();
- mStatusBar.stopWaitingForKeyguardExit();
if (hideBouncerWhenShowing || mBouncer.needsFullscreenBouncer()) {
hideBouncer(false /* destroyView */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index c217bda935c4..9d6fc5e9094e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -804,6 +804,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
} else {
mWifiSignalController.setActivity(WifiManager.DATA_ACTIVITY_NONE);
}
+ String ssid = args.getString("ssid");
+ if (ssid != null) {
+ mDemoWifiState.ssid = ssid;
+ }
mDemoWifiState.enabled = show;
mWifiSignalController.notifyListeners();
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 57bcda7a5646..7295bcb9bc91 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1711,6 +1711,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
+ static final int TOP_APP_KILLED_BY_LMK_MSG = 73;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1938,6 +1939,17 @@ public class ActivityManagerService extends IActivityManager.Stub
dispatchProcessDied(pid, uid);
break;
}
+ case TOP_APP_KILLED_BY_LMK_MSG: {
+ final String appName = (String) msg.obj;
+ final AlertDialog d = new BaseErrorDialog(mUiContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setTitle(mUiContext.getText(R.string.top_app_killed_title));
+ d.setMessage(mUiContext.getString(R.string.top_app_killed_message, appName));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.close),
+ obtainMessage(DISMISS_DIALOG_UI_MSG, d));
+ d.show();
+ break;
+ }
case DISPATCH_UIDS_CHANGED_UI_MSG: {
dispatchUidsChanged();
} break;
@@ -5396,6 +5408,7 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean doLowMem = app.instr == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
+ maybeNotifyTopAppKilled(app);
Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
+ ProcessList.makeOomAdjString(app.setAdj)
+ ProcessList.makeProcStateString(app.setProcState));
@@ -5429,6 +5442,23 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ /** Show system error dialog when a top app is killed by LMK */
+ void maybeNotifyTopAppKilled(ProcessRecord app) {
+ if (!shouldNotifyTopAppKilled(app)) {
+ return;
+ }
+
+ Message msg = mHandler.obtainMessage(TOP_APP_KILLED_BY_LMK_MSG);
+ msg.obj = mContext.getPackageManager().getApplicationLabel(app.info);
+ mUiHandler.sendMessage(msg);
+ }
+
+ /** Only show notification when the top app is killed on low ram devices */
+ private boolean shouldNotifyTopAppKilled(ProcessRecord app) {
+ return app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
+ ActivityManager.isLowRamDeviceStatic();
+ }
+
/**
* If a stack trace dump file is configured, dump process stack traces.
* @param clearTraces causes the dump file to be erased prior to the new
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index bbb58ac7886c..3f31b0814e20 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3315,6 +3315,24 @@ public class PackageManagerService extends IPackageManager.Stub
removeCodePathLI(dstCodePath);
return null;
}
+
+ // If we have a profile for a compressed APK, copy it to the reference location.
+ // Since the package is the stub one, remove the stub suffix to get the normal package and
+ // APK name.
+ File profileFile = new File(getPrebuildProfilePath(pkg).replace(STUB_SUFFIX, ""));
+ if (profileFile.exists()) {
+ try {
+ // We could also do this lazily before calling dexopt in
+ // PackageDexOptimizer to prevent this happening on first boot. The issue
+ // is that we don't have a good way to say "do this only once".
+ if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
+ pkg.applicationInfo.uid, pkg.packageName)) {
+ Log.e(TAG, "decompressPackage failed to copy system profile!");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ", e);
+ }
+ }
return dstCodePath;
}
@@ -9739,7 +9757,7 @@ public class PackageManagerService extends IPackageManager.Stub
* and {@code numberOfPackagesFailed}.
*/
private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
- String compilerFilter, boolean bootComplete) {
+ final String compilerFilter, boolean bootComplete) {
int numberOfPackagesVisited = 0;
int numberOfPackagesOptimized = 0;
@@ -9750,6 +9768,8 @@ public class PackageManagerService extends IPackageManager.Stub
for (PackageParser.Package pkg : pkgs) {
numberOfPackagesVisited++;
+ boolean useProfileForDexopt = false;
+
if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
// Copy over initial preopt profiles since we won't get any JIT samples for methods
// that are already compiled.
@@ -9763,11 +9783,30 @@ public class PackageManagerService extends IPackageManager.Stub
if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
pkg.applicationInfo.uid, pkg.packageName)) {
Log.e(TAG, "Installer failed to copy system profile!");
+ } else {
+ // Disabled as this causes speed-profile compilation during first boot
+ // even if things are already compiled.
+ // useProfileForDexopt = true;
}
} catch (Exception e) {
Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
e);
}
+ } else {
+ PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ // Handle compressed APKs in this path. Only do this for stubs with profiles to
+ // minimize the number off apps being speed-profile compiled during first boot.
+ // The other paths will not change the filter.
+ if (disabledPs != null && disabledPs.pkg.isStub) {
+ // The package is the stub one, remove the stub suffix to get the normal
+ // package and APK names.
+ String systemProfilePath =
+ getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
+ File systemProfile = new File(systemProfilePath);
+ // Use the profile for compilation if there exists one for the same package
+ // in the system partition.
+ useProfileForDexopt = systemProfile.exists();
+ }
}
}
@@ -9796,6 +9835,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ String pkgCompilerFilter = compilerFilter;
+ if (useProfileForDexopt) {
+ // Use background dexopt mode to try and use the profile. Note that this does not
+ // guarantee usage of the profile.
+ pkgCompilerFilter =
+ PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+ PackageManagerService.REASON_BACKGROUND_DEXOPT);
+ }
+
// checkProfiles is false to avoid merging profiles during boot which
// might interfere with background compilation (b/28612421).
// Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
@@ -9804,7 +9852,7 @@ public class PackageManagerService extends IPackageManager.Stub
int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
pkg.packageName,
- compilerFilter,
+ pkgCompilerFilter,
dexoptFlags));
switch (primaryDexOptStaus) {
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 43918da75ad4..f0ebf10ec527 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -139,6 +139,7 @@ cc_library_host_static {
"xml/XmlDom.cpp",
"xml/XmlPullParser.cpp",
"xml/XmlUtil.cpp",
+ "Configuration.proto",
"Resources.proto",
"ResourcesInternal.proto",
],
diff --git a/tools/aapt2/ConfigDescription.cpp b/tools/aapt2/ConfigDescription.cpp
index a9278c136cff..59a6e1281783 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/tools/aapt2/ConfigDescription.cpp
@@ -876,6 +876,12 @@ ConfigDescription ConfigDescription::CopyWithoutSdkVersion() const {
return copy;
}
+std::string ConfigDescription::GetBcp47LanguageTag(bool canonicalize) const {
+ char locale[RESTABLE_MAX_LOCALE_LEN];
+ getBcp47Locale(locale, canonicalize);
+ return std::string(locale);
+}
+
bool ConfigDescription::Dominates(const ConfigDescription& o) const {
if (*this == o) {
return true;
diff --git a/tools/aapt2/ConfigDescription.h b/tools/aapt2/ConfigDescription.h
index 65c96175091c..c1d0e1084186 100644
--- a/tools/aapt2/ConfigDescription.h
+++ b/tools/aapt2/ConfigDescription.h
@@ -61,6 +61,9 @@ struct ConfigDescription : public android::ResTable_config {
ConfigDescription CopyWithoutSdkVersion() const;
+ // Returns the BCP-47 language tag of this configuration's locale.
+ std::string GetBcp47LanguageTag(bool canonicalize = false) const;
+
/**
* A configuration X dominates another configuration Y, if X has at least the
* precedence of Y and X is strictly more general than Y: for any type defined
diff --git a/tools/aapt2/Configuration.proto b/tools/aapt2/Configuration.proto
new file mode 100644
index 000000000000..fc636a43ec40
--- /dev/null
+++ b/tools/aapt2/Configuration.proto
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto3";
+
+package aapt.pb;
+
+option java_package = "com.android.aapt";
+option optimize_for = LITE_RUNTIME;
+
+// A description of the requirements a device must have in order for a
+// resource to be matched and selected.
+message Configuration {
+ enum LayoutDirection {
+ LAYOUT_DIRECTION_UNSET = 0;
+ LAYOUT_DIRECTION_LTR = 1;
+ LAYOUT_DIRECTION_RTL = 2;
+ }
+
+ enum ScreenLayoutSize {
+ SCREEN_LAYOUT_SIZE_UNSET = 0;
+ SCREEN_LAYOUT_SIZE_SMALL = 1;
+ SCREEN_LAYOUT_SIZE_NORMAL = 2;
+ SCREEN_LAYOUT_SIZE_LARGE = 3;
+ SCREEN_LAYOUT_SIZE_XLARGE = 4;
+ }
+
+ enum ScreenLayoutLong {
+ SCREEN_LAYOUT_LONG_UNSET = 0;
+ SCREEN_LAYOUT_LONG_LONG = 1;
+ SCREEN_LAYOUT_LONG_NOTLONG = 2;
+ }
+
+ enum ScreenRound {
+ SCREEN_ROUND_UNSET = 0;
+ SCREEN_ROUND_ROUND = 1;
+ SCREEN_ROUND_NOTROUND = 2;
+ }
+
+ enum WideColorGamut {
+ WIDE_COLOR_GAMUT_UNSET = 0;
+ WIDE_COLOR_GAMUT_WIDECG = 1;
+ WIDE_COLOR_GAMUT_NOWIDECG = 2;
+ }
+
+ enum Hdr {
+ HDR_UNSET = 0;
+ HDR_HIGHDR = 1;
+ HDR_LOWDR = 2;
+ }
+
+ enum Orientation {
+ ORIENTATION_UNSET = 0;
+ ORIENTATION_PORT = 1;
+ ORIENTATION_LAND = 2;
+ ORIENTATION_SQUARE = 3;
+ }
+
+ enum UiModeType {
+ UI_MODE_TYPE_UNSET = 0;
+ UI_MODE_TYPE_NORMAL = 1;
+ UI_MODE_TYPE_DESK = 2;
+ UI_MODE_TYPE_CAR = 3;
+ UI_MODE_TYPE_TELEVISION = 4;
+ UI_MODE_TYPE_APPLIANCE = 5;
+ UI_MODE_TYPE_WATCH = 6;
+ UI_MODE_TYPE_VRHEADSET = 7;
+ }
+
+ enum UiModeNight {
+ UI_MODE_NIGHT_UNSET = 0;
+ UI_MODE_NIGHT_NIGHT = 1;
+ UI_MODE_NIGHT_NOTNIGHT = 2;
+ }
+
+ enum Touchscreen {
+ TOUCHSCREEN_UNSET = 0;
+ TOUCHSCREEN_NOTOUCH = 1;
+ TOUCHSCREEN_STYLUS = 2;
+ TOUCHSCREEN_FINGER = 3;
+ }
+
+ enum KeysHidden {
+ KEYS_HIDDEN_UNSET = 0;
+ KEYS_HIDDEN_KEYSEXPOSED = 1;
+ KEYS_HIDDEN_KEYSHIDDEN = 2;
+ KEYS_HIDDEN_KEYSSOFT = 3;
+ }
+
+ enum Keyboard {
+ KEYBOARD_UNSET = 0;
+ KEYBOARD_NOKEYS = 1;
+ KEYBOARD_QWERTY = 2;
+ KEYBOARD_TWELVEKEY = 3;
+ }
+
+ enum NavHidden {
+ NAV_HIDDEN_UNSET = 0;
+ NAV_HIDDEN_NAVEXPOSED = 1;
+ NAV_HIDDEN_NAVHIDDEN = 2;
+ }
+
+ enum Navigation {
+ NAVIGATION_UNSET = 0;
+ NAVIGATION_NONAV = 1;
+ NAVIGATION_DPAD = 2;
+ NAVIGATION_TRACKBALL = 3;
+ NAVIGATION_WHEEL = 4;
+ }
+
+ //
+ // Axis/dimensions that are understood by the runtime.
+ //
+
+ // Mobile country code.
+ uint32 mcc = 1;
+
+ // Mobile network code.
+ uint32 mnc = 2;
+
+ // BCP-47 locale tag.
+ string locale = 3;
+
+ // Left-to-right, right-to-left...
+ LayoutDirection layout_direction = 4;
+
+ // Screen width in pixels. Prefer screen_width_dp.
+ uint32 screen_width = 5;
+
+ // Screen height in pixels. Prefer screen_height_dp.
+ uint32 screen_height = 6;
+
+ // Screen width in density independent pixels (dp).
+ uint32 screen_width_dp = 7;
+
+ // Screen height in density independent pixels (dp).
+ uint32 screen_height_dp = 8;
+
+ // The smallest screen dimension, regardless of orientation, in dp.
+ uint32 smallest_screen_width_dp = 9;
+
+ // Whether the device screen is classified as small, normal, large, xlarge.
+ ScreenLayoutSize screen_layout_size = 10;
+
+ // Whether the device screen is long.
+ ScreenLayoutLong screen_layout_long = 11;
+
+ // Whether the screen is round (Android Wear).
+ ScreenRound screen_round = 12;
+
+ // Whether the screen supports wide color gamut.
+ WideColorGamut wide_color_gamut = 13;
+
+ // Whether the screen has high dynamic range.
+ Hdr hdr = 14;
+
+ // Which orientation the device is in (portrait, landscape).
+ Orientation orientation = 15;
+
+ // Which type of UI mode the device is in (television, car, etc.).
+ UiModeType ui_mode_type = 16;
+
+ // Whether the device is in night mode.
+ UiModeNight ui_mode_night = 17;
+
+ // The device's screen density in dots-per-inch (dpi).
+ uint32 density = 18;
+
+ // Whether a touchscreen exists, supports a stylus, or finger.
+ Touchscreen touchscreen = 19;
+
+ // Whether the keyboard hardware keys are currently hidden, exposed, or
+ // if the keyboard is a software keyboard.
+ KeysHidden keys_hidden = 20;
+
+ // The type of keyboard present (none, QWERTY, 12-key).
+ Keyboard keyboard = 21;
+
+ // Whether the navigation is exposed or hidden.
+ NavHidden nav_hidden = 22;
+
+ // The type of navigation present on the device
+ // (trackball, wheel, dpad, etc.).
+ Navigation navigation = 23;
+
+ // The minimum SDK version of the device.
+ uint32 sdk_version = 24;
+
+ //
+ // Build-time only dimensions.
+ //
+
+ string product = 25;
+}
diff --git a/tools/aapt2/Locale.cpp b/tools/aapt2/Locale.cpp
index 7664fac44be1..d81921f23904 100644
--- a/tools/aapt2/Locale.cpp
+++ b/tools/aapt2/Locale.cpp
@@ -24,9 +24,10 @@
#include "util/Util.h"
-namespace aapt {
+using ::android::ResTable_config;
+using ::android::StringPiece;
-using android::ResTable_config;
+namespace aapt {
void LocaleValue::set_language(const char* language_chars) {
size_t i = 0;
@@ -72,7 +73,7 @@ static inline bool is_number(const std::string& str) {
return std::all_of(std::begin(str), std::end(str), ::isdigit);
}
-bool LocaleValue::InitFromFilterString(const android::StringPiece& str) {
+bool LocaleValue::InitFromFilterString(const StringPiece& str) {
// A locale (as specified in the filter) is an underscore separated name such
// as "en_US", "en_Latn_US", or "en_US_POSIX".
std::vector<std::string> parts = util::SplitAndLowercase(str, '_');
@@ -138,6 +139,71 @@ bool LocaleValue::InitFromFilterString(const android::StringPiece& str) {
return true;
}
+bool LocaleValue::InitFromBcp47Tag(const StringPiece& bcp47tag) {
+ return InitFromBcp47TagImpl(bcp47tag, '-');
+}
+
+bool LocaleValue::InitFromBcp47TagImpl(const StringPiece& bcp47tag, const char separator) {
+ std::vector<std::string> subtags = util::SplitAndLowercase(bcp47tag, separator);
+ if (subtags.size() == 1) {
+ set_language(subtags[0].c_str());
+ } else if (subtags.size() == 2) {
+ set_language(subtags[0].c_str());
+
+ // The second tag can either be a region, a variant or a script.
+ switch (subtags[1].size()) {
+ case 2:
+ case 3:
+ set_region(subtags[1].c_str());
+ break;
+ case 4:
+ if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
+ // This is a variant: fall through
+ } else {
+ set_script(subtags[1].c_str());
+ break;
+ }
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ set_variant(subtags[1].c_str());
+ break;
+ default:
+ return false;
+ }
+ } else if (subtags.size() == 3) {
+ // The language is always the first subtag.
+ set_language(subtags[0].c_str());
+
+ // The second subtag can either be a script or a region code.
+ // If its size is 4, it's a script code, else it's a region code.
+ if (subtags[1].size() == 4) {
+ set_script(subtags[1].c_str());
+ } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
+ set_region(subtags[1].c_str());
+ } else {
+ return false;
+ }
+
+ // The third tag can either be a region code (if the second tag was
+ // a script), else a variant code.
+ if (subtags[2].size() >= 4) {
+ set_variant(subtags[2].c_str());
+ } else {
+ set_region(subtags[2].c_str());
+ }
+ } else if (subtags.size() == 4) {
+ set_language(subtags[0].c_str());
+ set_script(subtags[1].c_str());
+ set_region(subtags[2].c_str());
+ set_variant(subtags[3].c_str());
+ } else {
+ return false;
+ }
+ return true;
+}
+
ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
std::vector<std::string>::iterator end) {
const std::vector<std::string>::iterator start_iter = iter;
@@ -145,71 +211,13 @@ ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
std::string& part = *iter;
if (part[0] == 'b' && part[1] == '+') {
// This is a "modified" BCP 47 language tag. Same semantics as BCP 47 tags,
- // except that the separator is "+" and not "-".
- std::vector<std::string> subtags = util::SplitAndLowercase(part, '+');
- subtags.erase(subtags.begin());
- if (subtags.size() == 1) {
- set_language(subtags[0].c_str());
- } else if (subtags.size() == 2) {
- set_language(subtags[0].c_str());
-
- // The second tag can either be a region, a variant or a script.
- switch (subtags[1].size()) {
- case 2:
- case 3:
- set_region(subtags[1].c_str());
- break;
- case 4:
- if ('0' <= subtags[1][0] && subtags[1][0] <= '9') {
- // This is a variant: fall through
- } else {
- set_script(subtags[1].c_str());
- break;
- }
- case 5:
- case 6:
- case 7:
- case 8:
- set_variant(subtags[1].c_str());
- break;
- default:
- return -1;
- }
- } else if (subtags.size() == 3) {
- // The language is always the first subtag.
- set_language(subtags[0].c_str());
-
- // The second subtag can either be a script or a region code.
- // If its size is 4, it's a script code, else it's a region code.
- if (subtags[1].size() == 4) {
- set_script(subtags[1].c_str());
- } else if (subtags[1].size() == 2 || subtags[1].size() == 3) {
- set_region(subtags[1].c_str());
- } else {
- return -1;
- }
-
- // The third tag can either be a region code (if the second tag was
- // a script), else a variant code.
- if (subtags[2].size() >= 4) {
- set_variant(subtags[2].c_str());
- } else {
- set_region(subtags[2].c_str());
- }
- } else if (subtags.size() == 4) {
- set_language(subtags[0].c_str());
- set_script(subtags[1].c_str());
- set_region(subtags[2].c_str());
- set_variant(subtags[3].c_str());
- } else {
+ // except that the separator is "+" and not "-". Skip the prefix 'b+'.
+ if (!InitFromBcp47TagImpl(StringPiece(part).substr(2), '+')) {
return -1;
}
-
++iter;
-
} else {
- if ((part.length() == 2 || part.length() == 3) && is_alpha(part) &&
- part != "car") {
+ if ((part.length() == 2 || part.length() == 3) && is_alpha(part) && part != "car") {
set_language(part.c_str());
++iter;
@@ -222,7 +230,6 @@ ssize_t LocaleValue::InitFromParts(std::vector<std::string>::iterator iter,
}
}
}
-
return static_cast<ssize_t>(iter - start_iter);
}
diff --git a/tools/aapt2/Locale.h b/tools/aapt2/Locale.h
index 3d73b2eb17bf..6d8b598415cc 100644
--- a/tools/aapt2/Locale.h
+++ b/tools/aapt2/Locale.h
@@ -41,6 +41,9 @@ struct LocaleValue {
*/
bool InitFromFilterString(const android::StringPiece& config);
+ // Initializes this LocaleValue from a BCP-47 locale tag.
+ bool InitFromBcp47Tag(const android::StringPiece& bcp47tag);
+
/**
* Initialize this LocaleValue from parts of a vector.
*/
@@ -67,6 +70,8 @@ struct LocaleValue {
inline bool operator>(const LocaleValue& o) const;
private:
+ bool InitFromBcp47TagImpl(const android::StringPiece& bcp47tag, const char separator);
+
void set_language(const char* language);
void set_region(const char* language);
void set_script(const char* script);
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index c1af88a1a74e..174b7f6b7c8c 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -16,19 +16,13 @@
syntax = "proto3";
+import "frameworks/base/tools/aapt2/Configuration.proto";
+
package aapt.pb;
option java_package = "com.android.aapt";
option optimize_for = LITE_RUNTIME;
-// A configuration description that wraps the binary form of the C++ class
-// aapt::ConfigDescription, with an added product definition.
-// TODO(adamlesinski): Flesh this out to be represented in proto.
-message ConfigDescription {
- bytes data = 1;
- string product = 2;
-}
-
// A string pool that wraps the binary form of the C++ class android::ResStringPool.
message StringPool {
bytes data = 1;
@@ -163,7 +157,7 @@ message Entry {
// A Configuration/Value pair.
message ConfigValue {
- ConfigDescription config = 1;
+ Configuration config = 1;
Value value = 2;
}
diff --git a/tools/aapt2/ResourcesInternal.proto b/tools/aapt2/ResourcesInternal.proto
index 17604e4c6fe8..0b0a252a3452 100644
--- a/tools/aapt2/ResourcesInternal.proto
+++ b/tools/aapt2/ResourcesInternal.proto
@@ -16,6 +16,7 @@
syntax = "proto3";
+import "frameworks/base/tools/aapt2/Configuration.proto";
import "frameworks/base/tools/aapt2/Resources.proto";
package aapt.pb.internal;
@@ -38,7 +39,7 @@ message CompiledFile {
string resource_name = 1;
// The configuration for which the resource is defined.
- aapt.pb.ConfigDescription config = 2;
+ aapt.pb.Configuration config = 2;
// The filesystem path to where the source file originated.
// Mainly used to display helpful error messages.
diff --git a/tools/aapt2/proto/ProtoHelpers.cpp b/tools/aapt2/proto/ProtoHelpers.cpp
index 59ca8e484fbe..18f7e1d2ff7d 100644
--- a/tools/aapt2/proto/ProtoHelpers.cpp
+++ b/tools/aapt2/proto/ProtoHelpers.cpp
@@ -16,6 +16,8 @@
#include "proto/ProtoHelpers.h"
+#include "Locale.h"
+
namespace aapt {
void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool) {
@@ -70,27 +72,507 @@ SymbolState DeserializeVisibilityFromPb(pb::SymbolStatus_Visibility pb_visibilit
return SymbolState::kUndefined;
}
-void SerializeConfig(const ConfigDescription& config, pb::ConfigDescription* out_pb_config) {
- android::ResTable_config flat_config = config;
- flat_config.size = sizeof(flat_config);
- flat_config.swapHtoD();
- out_pb_config->set_data(&flat_config, sizeof(flat_config));
+void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_config) {
+ out_pb_config->set_mcc(config.mcc);
+ out_pb_config->set_mnc(config.mnc);
+ out_pb_config->set_locale(config.GetBcp47LanguageTag());
+
+ switch (config.screenLayout & ConfigDescription::MASK_LAYOUTDIR) {
+ case ConfigDescription::LAYOUTDIR_LTR:
+ out_pb_config->set_layout_direction(pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_LTR);
+ break;
+
+ case ConfigDescription::LAYOUTDIR_RTL:
+ out_pb_config->set_layout_direction(pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_RTL);
+ break;
+ }
+
+ out_pb_config->set_screen_width(config.screenWidth);
+ out_pb_config->set_screen_height(config.screenHeight);
+ out_pb_config->set_screen_width_dp(config.screenWidthDp);
+ out_pb_config->set_screen_height_dp(config.screenHeightDp);
+ out_pb_config->set_smallest_screen_width_dp(config.smallestScreenWidthDp);
+
+ switch (config.screenLayout & ConfigDescription::MASK_SCREENSIZE) {
+ case ConfigDescription::SCREENSIZE_SMALL:
+ out_pb_config->set_screen_layout_size(
+ pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_SMALL);
+ break;
+
+ case ConfigDescription::SCREENSIZE_NORMAL:
+ out_pb_config->set_screen_layout_size(
+ pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_NORMAL);
+ break;
+
+ case ConfigDescription::SCREENSIZE_LARGE:
+ out_pb_config->set_screen_layout_size(
+ pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_LARGE);
+ break;
+
+ case ConfigDescription::SCREENSIZE_XLARGE:
+ out_pb_config->set_screen_layout_size(
+ pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_XLARGE);
+ break;
+ }
+
+ switch (config.screenLayout & ConfigDescription::MASK_SCREENLONG) {
+ case ConfigDescription::SCREENLONG_YES:
+ out_pb_config->set_screen_layout_long(
+ pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_LONG);
+ break;
+
+ case ConfigDescription::SCREENLONG_NO:
+ out_pb_config->set_screen_layout_long(
+ pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_NOTLONG);
+ break;
+ }
+
+ switch (config.screenLayout2 & ConfigDescription::MASK_SCREENROUND) {
+ case ConfigDescription::SCREENROUND_YES:
+ out_pb_config->set_screen_round(pb::Configuration_ScreenRound_SCREEN_ROUND_ROUND);
+ break;
+
+ case ConfigDescription::SCREENROUND_NO:
+ out_pb_config->set_screen_round(pb::Configuration_ScreenRound_SCREEN_ROUND_NOTROUND);
+ break;
+ }
+
+ switch (config.colorMode & ConfigDescription::MASK_WIDE_COLOR_GAMUT) {
+ case ConfigDescription::WIDE_COLOR_GAMUT_YES:
+ out_pb_config->set_wide_color_gamut(pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_WIDECG);
+ break;
+
+ case ConfigDescription::WIDE_COLOR_GAMUT_NO:
+ out_pb_config->set_wide_color_gamut(
+ pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_NOWIDECG);
+ break;
+ }
+
+ switch (config.colorMode & ConfigDescription::MASK_HDR) {
+ case ConfigDescription::HDR_YES:
+ out_pb_config->set_hdr(pb::Configuration_Hdr_HDR_HIGHDR);
+ break;
+
+ case ConfigDescription::HDR_NO:
+ out_pb_config->set_hdr(pb::Configuration_Hdr_HDR_LOWDR);
+ break;
+ }
+
+ switch (config.orientation) {
+ case ConfigDescription::ORIENTATION_PORT:
+ out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_PORT);
+ break;
+
+ case ConfigDescription::ORIENTATION_LAND:
+ out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_LAND);
+ break;
+
+ case ConfigDescription::ORIENTATION_SQUARE:
+ out_pb_config->set_orientation(pb::Configuration_Orientation_ORIENTATION_SQUARE);
+ break;
+ }
+
+ switch (config.uiMode & ConfigDescription::MASK_UI_MODE_TYPE) {
+ case ConfigDescription::UI_MODE_TYPE_NORMAL:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_NORMAL);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_DESK:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_DESK);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_CAR:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_CAR);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_TELEVISION:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_TELEVISION);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_APPLIANCE:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_APPLIANCE);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_WATCH:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_WATCH);
+ break;
+
+ case ConfigDescription::UI_MODE_TYPE_VR_HEADSET:
+ out_pb_config->set_ui_mode_type(pb::Configuration_UiModeType_UI_MODE_TYPE_VRHEADSET);
+ break;
+ }
+
+ switch (config.uiMode & ConfigDescription::MASK_UI_MODE_NIGHT) {
+ case ConfigDescription::UI_MODE_NIGHT_YES:
+ out_pb_config->set_ui_mode_night(pb::Configuration_UiModeNight_UI_MODE_NIGHT_NIGHT);
+ break;
+
+ case ConfigDescription::UI_MODE_NIGHT_NO:
+ out_pb_config->set_ui_mode_night(pb::Configuration_UiModeNight_UI_MODE_NIGHT_NOTNIGHT);
+ break;
+ }
+
+ out_pb_config->set_density(config.density);
+
+ switch (config.touchscreen) {
+ case ConfigDescription::TOUCHSCREEN_NOTOUCH:
+ out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_NOTOUCH);
+ break;
+
+ case ConfigDescription::TOUCHSCREEN_STYLUS:
+ out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_STYLUS);
+ break;
+
+ case ConfigDescription::TOUCHSCREEN_FINGER:
+ out_pb_config->set_touchscreen(pb::Configuration_Touchscreen_TOUCHSCREEN_FINGER);
+ break;
+ }
+
+ switch (config.inputFlags & ConfigDescription::MASK_KEYSHIDDEN) {
+ case ConfigDescription::KEYSHIDDEN_NO:
+ out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSEXPOSED);
+ break;
+
+ case ConfigDescription::KEYSHIDDEN_YES:
+ out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSHIDDEN);
+ break;
+
+ case ConfigDescription::KEYSHIDDEN_SOFT:
+ out_pb_config->set_keys_hidden(pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSSOFT);
+ break;
+ }
+
+ switch (config.keyboard) {
+ case ConfigDescription::KEYBOARD_NOKEYS:
+ out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_NOKEYS);
+ break;
+
+ case ConfigDescription::KEYBOARD_QWERTY:
+ out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_QWERTY);
+ break;
+
+ case ConfigDescription::KEYBOARD_12KEY:
+ out_pb_config->set_keyboard(pb::Configuration_Keyboard_KEYBOARD_TWELVEKEY);
+ break;
+ }
+
+ switch (config.inputFlags & ConfigDescription::MASK_NAVHIDDEN) {
+ case ConfigDescription::NAVHIDDEN_NO:
+ out_pb_config->set_nav_hidden(pb::Configuration_NavHidden_NAV_HIDDEN_NAVEXPOSED);
+ break;
+
+ case ConfigDescription::NAVHIDDEN_YES:
+ out_pb_config->set_nav_hidden(pb::Configuration_NavHidden_NAV_HIDDEN_NAVHIDDEN);
+ break;
+ }
+
+ switch (config.navigation) {
+ case ConfigDescription::NAVIGATION_NONAV:
+ out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_NONAV);
+ break;
+
+ case ConfigDescription::NAVIGATION_DPAD:
+ out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_DPAD);
+ break;
+
+ case ConfigDescription::NAVIGATION_TRACKBALL:
+ out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_TRACKBALL);
+ break;
+
+ case ConfigDescription::NAVIGATION_WHEEL:
+ out_pb_config->set_navigation(pb::Configuration_Navigation_NAVIGATION_WHEEL);
+ break;
+ }
+
+ out_pb_config->set_sdk_version(config.sdkVersion);
}
-bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config,
+bool DeserializeConfigDescriptionFromPb(const pb::Configuration& pb_config,
ConfigDescription* out_config) {
- // a ConfigDescription must be at least 4 bytes to store the size.
- if (pb_config.data().size() < 4) {
- return false;
+ out_config->mcc = static_cast<uint16_t>(pb_config.mcc());
+ out_config->mnc = static_cast<uint16_t>(pb_config.mnc());
+
+ if (!pb_config.locale().empty()) {
+ LocaleValue lv;
+ if (!lv.InitFromBcp47Tag(pb_config.locale())) {
+ return false;
+ }
+ lv.WriteTo(out_config);
+ }
+
+ switch (pb_config.layout_direction()) {
+ case pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_LTR:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_LAYOUTDIR) |
+ ConfigDescription::LAYOUTDIR_LTR;
+ break;
+
+ case pb::Configuration_LayoutDirection_LAYOUT_DIRECTION_RTL:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_LAYOUTDIR) |
+ ConfigDescription::LAYOUTDIR_RTL;
+ break;
+
+ default:
+ break;
}
- const android::ResTable_config* config;
- if (pb_config.data().size() > sizeof(*config)) {
- return false;
+ out_config->smallestScreenWidthDp = static_cast<uint16_t>(pb_config.smallest_screen_width_dp());
+ out_config->screenWidthDp = static_cast<uint16_t>(pb_config.screen_width_dp());
+ out_config->screenHeightDp = static_cast<uint16_t>(pb_config.screen_height_dp());
+
+ switch (pb_config.screen_layout_size()) {
+ case pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_SMALL:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENSIZE) |
+ ConfigDescription::SCREENSIZE_SMALL;
+ break;
+
+ case pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_NORMAL:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENSIZE) |
+ ConfigDescription::SCREENSIZE_NORMAL;
+ break;
+
+ case pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_LARGE:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENSIZE) |
+ ConfigDescription::SCREENSIZE_LARGE;
+ break;
+
+ case pb::Configuration_ScreenLayoutSize_SCREEN_LAYOUT_SIZE_XLARGE:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENSIZE) |
+ ConfigDescription::SCREENSIZE_XLARGE;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.screen_layout_long()) {
+ case pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_LONG:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENLONG) |
+ ConfigDescription::SCREENLONG_YES;
+ break;
+
+ case pb::Configuration_ScreenLayoutLong_SCREEN_LAYOUT_LONG_NOTLONG:
+ out_config->screenLayout = (out_config->screenLayout & ~ConfigDescription::MASK_SCREENLONG) |
+ ConfigDescription::SCREENLONG_NO;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.screen_round()) {
+ case pb::Configuration_ScreenRound_SCREEN_ROUND_ROUND:
+ out_config->screenLayout2 =
+ (out_config->screenLayout2 & ~ConfigDescription::MASK_SCREENROUND) |
+ ConfigDescription::SCREENROUND_YES;
+ break;
+
+ case pb::Configuration_ScreenRound_SCREEN_ROUND_NOTROUND:
+ out_config->screenLayout2 =
+ (out_config->screenLayout2 & ~ConfigDescription::MASK_SCREENROUND) |
+ ConfigDescription::SCREENROUND_NO;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.wide_color_gamut()) {
+ case pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_WIDECG:
+ out_config->colorMode = (out_config->colorMode & ~ConfigDescription::MASK_WIDE_COLOR_GAMUT) |
+ ConfigDescription::WIDE_COLOR_GAMUT_YES;
+ break;
+
+ case pb::Configuration_WideColorGamut_WIDE_COLOR_GAMUT_NOWIDECG:
+ out_config->colorMode = (out_config->colorMode & ~ConfigDescription::MASK_WIDE_COLOR_GAMUT) |
+ ConfigDescription::WIDE_COLOR_GAMUT_NO;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.hdr()) {
+ case pb::Configuration_Hdr_HDR_HIGHDR:
+ out_config->colorMode =
+ (out_config->colorMode & ~ConfigDescription::MASK_HDR) | ConfigDescription::HDR_YES;
+ break;
+
+ case pb::Configuration_Hdr_HDR_LOWDR:
+ out_config->colorMode =
+ (out_config->colorMode & ~ConfigDescription::MASK_HDR) | ConfigDescription::HDR_NO;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.orientation()) {
+ case pb::Configuration_Orientation_ORIENTATION_PORT:
+ out_config->orientation = ConfigDescription::ORIENTATION_PORT;
+ break;
+
+ case pb::Configuration_Orientation_ORIENTATION_LAND:
+ out_config->orientation = ConfigDescription::ORIENTATION_LAND;
+ break;
+
+ case pb::Configuration_Orientation_ORIENTATION_SQUARE:
+ out_config->orientation = ConfigDescription::ORIENTATION_SQUARE;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.ui_mode_type()) {
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_NORMAL:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_NORMAL;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_DESK:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_DESK;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_CAR:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_CAR;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_TELEVISION:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_TELEVISION;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_APPLIANCE:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_APPLIANCE;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_WATCH:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_WATCH;
+ break;
+
+ case pb::Configuration_UiModeType_UI_MODE_TYPE_VRHEADSET:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_TYPE) |
+ ConfigDescription::UI_MODE_TYPE_VR_HEADSET;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.ui_mode_night()) {
+ case pb::Configuration_UiModeNight_UI_MODE_NIGHT_NIGHT:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_NIGHT) |
+ ConfigDescription::UI_MODE_NIGHT_YES;
+ break;
+
+ case pb::Configuration_UiModeNight_UI_MODE_NIGHT_NOTNIGHT:
+ out_config->uiMode = (out_config->uiMode & ~ConfigDescription::MASK_UI_MODE_NIGHT) |
+ ConfigDescription::UI_MODE_NIGHT_NO;
+ break;
+
+ default:
+ break;
+ }
+
+ out_config->density = static_cast<uint16_t>(pb_config.density());
+
+ switch (pb_config.touchscreen()) {
+ case pb::Configuration_Touchscreen_TOUCHSCREEN_NOTOUCH:
+ out_config->touchscreen = ConfigDescription::TOUCHSCREEN_NOTOUCH;
+ break;
+
+ case pb::Configuration_Touchscreen_TOUCHSCREEN_STYLUS:
+ out_config->touchscreen = ConfigDescription::TOUCHSCREEN_STYLUS;
+ break;
+
+ case pb::Configuration_Touchscreen_TOUCHSCREEN_FINGER:
+ out_config->touchscreen = ConfigDescription::TOUCHSCREEN_FINGER;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.keys_hidden()) {
+ case pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSEXPOSED:
+ out_config->inputFlags = (out_config->inputFlags & ~ConfigDescription::MASK_KEYSHIDDEN) |
+ ConfigDescription::KEYSHIDDEN_NO;
+ break;
+
+ case pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSHIDDEN:
+ out_config->inputFlags = (out_config->inputFlags & ~ConfigDescription::MASK_KEYSHIDDEN) |
+ ConfigDescription::KEYSHIDDEN_YES;
+ break;
+
+ case pb::Configuration_KeysHidden_KEYS_HIDDEN_KEYSSOFT:
+ out_config->inputFlags = (out_config->inputFlags & ~ConfigDescription::MASK_KEYSHIDDEN) |
+ ConfigDescription::KEYSHIDDEN_SOFT;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.keyboard()) {
+ case pb::Configuration_Keyboard_KEYBOARD_NOKEYS:
+ out_config->keyboard = ConfigDescription::KEYBOARD_NOKEYS;
+ break;
+
+ case pb::Configuration_Keyboard_KEYBOARD_QWERTY:
+ out_config->keyboard = ConfigDescription::KEYBOARD_QWERTY;
+ break;
+
+ case pb::Configuration_Keyboard_KEYBOARD_TWELVEKEY:
+ out_config->keyboard = ConfigDescription::KEYBOARD_12KEY;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.nav_hidden()) {
+ case pb::Configuration_NavHidden_NAV_HIDDEN_NAVEXPOSED:
+ out_config->inputFlags = (out_config->inputFlags & ~ConfigDescription::MASK_NAVHIDDEN) |
+ ConfigDescription::NAVHIDDEN_NO;
+ break;
+
+ case pb::Configuration_NavHidden_NAV_HIDDEN_NAVHIDDEN:
+ out_config->inputFlags = (out_config->inputFlags & ~ConfigDescription::MASK_NAVHIDDEN) |
+ ConfigDescription::NAVHIDDEN_YES;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (pb_config.navigation()) {
+ case pb::Configuration_Navigation_NAVIGATION_NONAV:
+ out_config->navigation = ConfigDescription::NAVIGATION_NONAV;
+ break;
+
+ case pb::Configuration_Navigation_NAVIGATION_DPAD:
+ out_config->navigation = ConfigDescription::NAVIGATION_DPAD;
+ break;
+
+ case pb::Configuration_Navigation_NAVIGATION_TRACKBALL:
+ out_config->navigation = ConfigDescription::NAVIGATION_TRACKBALL;
+ break;
+
+ case pb::Configuration_Navigation_NAVIGATION_WHEEL:
+ out_config->navigation = ConfigDescription::NAVIGATION_WHEEL;
+ break;
+
+ default:
+ break;
}
- config = reinterpret_cast<const android::ResTable_config*>(pb_config.data().data());
- out_config->copyFromDtoH(*config);
+ out_config->screenWidth = static_cast<uint16_t>(pb_config.screen_width());
+ out_config->screenHeight = static_cast<uint16_t>(pb_config.screen_height());
+ out_config->sdkVersion = static_cast<uint16_t>(pb_config.sdk_version());
return true;
}
diff --git a/tools/aapt2/proto/ProtoHelpers.h b/tools/aapt2/proto/ProtoHelpers.h
index 2f268f44752c..714a2b27bf7f 100644
--- a/tools/aapt2/proto/ProtoHelpers.h
+++ b/tools/aapt2/proto/ProtoHelpers.h
@@ -20,11 +20,12 @@
#include "androidfw/ResourceTypes.h"
#include "ConfigDescription.h"
+#include "Configuration.pb.h"
#include "ResourceTable.h"
-#include "Source.h"
-#include "StringPool.h"
#include "Resources.pb.h"
#include "ResourcesInternal.pb.h"
+#include "Source.h"
+#include "StringPool.h"
namespace aapt {
@@ -39,9 +40,9 @@ pb::SymbolStatus_Visibility SerializeVisibilityToPb(SymbolState state);
SymbolState DeserializeVisibilityFromPb(pb::SymbolStatus_Visibility pb_visibility);
-void SerializeConfig(const ConfigDescription& config, pb::ConfigDescription* out_pb_config);
+void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_config);
-bool DeserializeConfigDescriptionFromPb(const pb::ConfigDescription& pb_config,
+bool DeserializeConfigDescriptionFromPb(const pb::Configuration& pb_config,
ConfigDescription* out_config);
pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type);
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
index f4a2b1e19331..4a88d61ef84c 100644
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ b/tools/aapt2/proto/TableProtoDeserializer.cpp
@@ -123,7 +123,7 @@ class PackagePbDeserializer {
}
for (const pb::ConfigValue& pb_config_value : pb_entry.config_value()) {
- const pb::ConfigDescription& pb_config = pb_config_value.config();
+ const pb::Configuration& pb_config = pb_config_value.config();
ConfigDescription config;
if (!DeserializeConfigDescriptionFromPb(pb_config, &config)) {
@@ -395,14 +395,16 @@ std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb(
}
file->name = name_ref.ToResourceName();
file->source.path = pb_file.source_path();
- DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config);
+ if (!DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config)) {
+ diag->Error(DiagMessage(source) << "invalid resource configuration in compiled file header");
+ return {};
+ }
for (const pb::internal::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbol()) {
// Need to create an lvalue here so that nameRef can point to something real.
if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(), &name_ref)) {
diag->Error(DiagMessage(source)
- << "invalid resource name for exported symbol in "
- "compiled file header: "
+ << "invalid resource name for exported symbol in compiled file header: "
<< pb_file.resource_name());
return {};
}
diff --git a/tools/aapt2/proto/TableProtoSerializer.cpp b/tools/aapt2/proto/TableProtoSerializer.cpp
index 981b72ab7221..3d5407c137b1 100644
--- a/tools/aapt2/proto/TableProtoSerializer.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer.cpp
@@ -282,10 +282,10 @@ CompiledFileOutputStream::CompiledFileOutputStream(ZeroCopyOutputStream* out) :
}
void CompiledFileOutputStream::EnsureAlignedWrite() {
- const int padding = out_.ByteCount() % 4;
- if (padding > 0) {
+ const int overflow = out_.ByteCount() % 4;
+ if (overflow > 0) {
uint32_t zero = 0u;
- out_.WriteRaw(&zero, padding);
+ out_.WriteRaw(&zero, 4 - overflow);
}
}
@@ -322,10 +322,10 @@ CompiledFileInputStream::CompiledFileInputStream(const void* data, size_t size)
: in_(static_cast<const uint8_t*>(data), size) {}
void CompiledFileInputStream::EnsureAlignedRead() {
- const int padding = in_.CurrentPosition() % 4;
- if (padding > 0) {
+ const int overflow = in_.CurrentPosition() % 4;
+ if (overflow > 0) {
// Reads are always 4 byte aligned.
- in_.Skip(padding);
+ in_.Skip(4 - overflow);
}
}
diff --git a/tools/aapt2/proto/TableProtoSerializer_test.cpp b/tools/aapt2/proto/TableProtoSerializer_test.cpp
index 80608b3d9c05..8f6414c68a43 100644
--- a/tools/aapt2/proto/TableProtoSerializer_test.cpp
+++ b/tools/aapt2/proto/TableProtoSerializer_test.cpp
@@ -19,6 +19,7 @@
#include "ResourceTable.h"
#include "test/Test.h"
+using ::android::StringPiece;
using ::google::protobuf::io::StringOutputStream;
using ::testing::Eq;
using ::testing::NotNull;
@@ -239,4 +240,97 @@ TEST(TableProtoSerializer, DeserializeCorruptHeaderSafely) {
EXPECT_FALSE(in_file_stream.ReadDataMetaData(&offset, &len));
}
+static void ExpectConfigSerializes(const StringPiece& config_str) {
+ const ConfigDescription expected_config = test::ParseConfigOrDie(config_str);
+ pb::Configuration pb_config;
+ SerializeConfig(expected_config, &pb_config);
+
+ ConfigDescription actual_config;
+ ASSERT_TRUE(DeserializeConfigDescriptionFromPb(pb_config, &actual_config));
+ EXPECT_EQ(expected_config, actual_config);
+}
+
+TEST(TableProtoSerializer, SerializeDeserializeConfiguration) {
+ ExpectConfigSerializes("");
+
+ ExpectConfigSerializes("mcc123");
+
+ ExpectConfigSerializes("mnc123");
+
+ ExpectConfigSerializes("en");
+ ExpectConfigSerializes("en-rGB");
+ ExpectConfigSerializes("b+en+GB");
+
+ ExpectConfigSerializes("ldltr");
+ ExpectConfigSerializes("ldrtl");
+
+ ExpectConfigSerializes("sw3600dp");
+
+ ExpectConfigSerializes("w300dp");
+
+ ExpectConfigSerializes("h400dp");
+
+ ExpectConfigSerializes("small");
+ ExpectConfigSerializes("normal");
+ ExpectConfigSerializes("large");
+ ExpectConfigSerializes("xlarge");
+
+ ExpectConfigSerializes("long");
+ ExpectConfigSerializes("notlong");
+
+ ExpectConfigSerializes("round");
+ ExpectConfigSerializes("notround");
+
+ ExpectConfigSerializes("widecg");
+ ExpectConfigSerializes("nowidecg");
+
+ ExpectConfigSerializes("highdr");
+ ExpectConfigSerializes("lowdr");
+
+ ExpectConfigSerializes("port");
+ ExpectConfigSerializes("land");
+ ExpectConfigSerializes("square");
+
+ ExpectConfigSerializes("desk");
+ ExpectConfigSerializes("car");
+ ExpectConfigSerializes("television");
+ ExpectConfigSerializes("appliance");
+ ExpectConfigSerializes("watch");
+ ExpectConfigSerializes("vrheadset");
+
+ ExpectConfigSerializes("night");
+ ExpectConfigSerializes("notnight");
+
+ ExpectConfigSerializes("300dpi");
+ ExpectConfigSerializes("hdpi");
+
+ ExpectConfigSerializes("notouch");
+ ExpectConfigSerializes("stylus");
+ ExpectConfigSerializes("finger");
+
+ ExpectConfigSerializes("keysexposed");
+ ExpectConfigSerializes("keyshidden");
+ ExpectConfigSerializes("keyssoft");
+
+ ExpectConfigSerializes("nokeys");
+ ExpectConfigSerializes("qwerty");
+ ExpectConfigSerializes("12key");
+
+ ExpectConfigSerializes("navhidden");
+ ExpectConfigSerializes("navexposed");
+
+ ExpectConfigSerializes("nonav");
+ ExpectConfigSerializes("dpad");
+ ExpectConfigSerializes("trackball");
+ ExpectConfigSerializes("wheel");
+
+ ExpectConfigSerializes("300x200");
+
+ ExpectConfigSerializes("v8");
+
+ ExpectConfigSerializes(
+ "mcc123-mnc456-b+en+GB-ldltr-sw300dp-w300dp-h400dp-large-long-round-widecg-highdr-land-car-"
+ "night-xhdpi-stylus-keysexposed-qwerty-navhidden-dpad-300x200-v23");
+}
+
} // namespace aapt