summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp17
-rwxr-xr-xapi/current.txt1
-rw-r--r--api/system-current.txt1
-rw-r--r--cmds/statsd/src/atoms.proto14
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.cpp5
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp10
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.h5
-rw-r--r--cmds/statsd/src/stats_log.proto4
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp5
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp8
-rw-r--r--core/java/android/content/pm/PackageInfo.java2
-rw-r--r--core/java/android/hardware/camera2/params/OutputConfiguration.java2
-rw-r--r--core/java/android/hardware/display/BrightnessConfiguration.java28
-rw-r--r--core/java/android/inputmethodservice/IInputMethodWrapper.java4
-rw-r--r--core/java/android/net/Uri.java2
-rw-r--r--core/java/android/util/FeatureFlagUtils.java1
-rw-r--r--core/java/android/view/inputmethod/InputMethodSubtype.java4
-rw-r--r--core/java/android/view/textservice/SpellCheckerSubtype.java4
-rw-r--r--core/java/android/webkit/WebViewFactory.java3
-rw-r--r--core/java/android/webkit/WebViewLibraryLoader.java218
-rw-r--r--core/java/android/widget/TextView.java3
-rw-r--r--core/java/com/android/internal/colorextraction/types/Tonal.java8
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodUtils.java153
-rw-r--r--core/java/com/android/internal/inputmethod/LocaleUtils.java151
-rw-r--r--core/java/com/android/internal/util/ContrastColorUtil.java2
-rw-r--r--core/java/com/android/internal/util/OWNERS28
-rw-r--r--core/java/com/android/internal/view/InputBindResult.java19
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/values-fr/strings.xml4
-rw-r--r--core/res/res/values-hi/strings.xml6
-rw-r--r--core/res/res/values-hy/strings.xml2
-rw-r--r--core/res/res/values-ja/strings.xml2
-rw-r--r--core/res/res/values-kn/strings.xml2
-rw-r--r--core/res/res/values-night/colors.xml2
-rw-r--r--core/res/res/values-night/themes_device_defaults.xml3
-rw-r--r--core/res/res/values-night/values.xml2
-rw-r--r--core/res/res/values-ru/strings.xml4
-rw-r--r--core/res/res/values-si/strings.xml6
-rw-r--r--core/res/res/values-ta/strings.xml2
-rw-r--r--core/res/res/values-television/themes.xml2
-rw-r--r--core/res/res/values-watch/themes.xml2
-rw-r--r--core/res/res/values-zh-rCN/strings.xml4
-rw-r--r--core/res/res/values-zh-rTW/strings.xml2
-rw-r--r--core/res/res/values/symbols.xml2
-rw-r--r--core/res/res/values/themes.xml7
-rw-r--r--core/res/res/values/themes_device_defaults.xml7
-rw-r--r--core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java49
-rw-r--r--core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java9
-rw-r--r--core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java120
-rw-r--r--core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java129
-rw-r--r--core/tests/webkit/Android.mk45
-rw-r--r--core/tests/webkit/AndroidManifest.xml30
-rw-r--r--core/tests/webkit/AndroidTest.xml30
-rw-r--r--core/tests/webkit/OWNERS3
-rw-r--r--core/tests/webkit/apk_with_native_libs/Android.mk71
-rw-r--r--core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml29
-rw-r--r--core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml28
-rw-r--r--core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java24
-rw-r--r--core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java329
-rw-r--r--media/jni/Android.bp11
-rw-r--r--media/jni/android_media_MediaMetricsJNI.cpp90
-rw-r--r--media/jni/android_media_MediaMetricsJNI.h (renamed from core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp)23
-rw-r--r--media/jni/android_media_MediaPlayer2.cpp74
-rw-r--r--native/webview/loader/loader.cpp20
-rw-r--r--packages/CarSystemUI/Android.bp1
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java45
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java13
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java39
-rw-r--r--packages/SettingsLib/tests/robotests/config/robolectric.properties5
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java91
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java91
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java43
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java10
-rw-r--r--packages/SystemUI/Android.bp3
-rw-r--r--packages/SystemUI/res/values-night/colors.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java5
-rw-r--r--packages/SystemUI/tests/Android.mk3
-rw-r--r--packages/VpnDialogs/res/values-es-rUS/strings.xml2
-rw-r--r--proto/src/metrics_constants/OWNERS1
-rw-r--r--services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java89
-rw-r--r--services/core/java/com/android/server/AlarmManagerService.java3
-rw-r--r--services/core/java/com/android/server/HardwarePropertiesManagerService.java11
-rw-r--r--services/core/java/com/android/server/IpSecService.java34
-rw-r--r--services/core/java/com/android/server/TextServicesManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/core/java/com/android/server/am/BaseErrorDialog.java2
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java6
-rw-r--r--services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java (renamed from services/core/java/com/android/server/InputContentUriTokenHandler.java)4
-rw-r--r--services/core/java/com/android/server/inputmethod/InputMethodManagerService.java (renamed from services/core/java/com/android/server/InputMethodManagerService.java)8
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyLogger.java4
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java2
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java3
-rw-r--r--services/core/java/com/android/server/notification/PreferencesHelper.java286
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java8
-rw-r--r--services/java/com/android/server/SystemServer.java1
-rw-r--r--services/net/java/android/net/ip/IpClient.java27
-rw-r--r--services/robotests/Android.mk1
-rw-r--r--services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java101
-rw-r--r--services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java6
-rw-r--r--startop/OWNERS5
-rwxr-xr-xstartop/scripts/app_startup/analyze_metrics.py457
-rwxr-xr-xstartop/scripts/app_startup/app_startup_runner.py322
-rwxr-xr-xstartop/scripts/app_startup/app_startup_runner_test.py210
-rwxr-xr-xstartop/scripts/app_startup/launch_application41
-rwxr-xr-xstartop/scripts/app_startup/lib/common14
-rwxr-xr-xstartop/scripts/app_startup/run_app_with_prefetch344
-rwxr-xr-x[-rw-r--r--]startop/scripts/app_startup/unlock_screen (renamed from core/tests/webkit/apk_with_native_libs/jni/Android.mk)28
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java12
-rw-r--r--tests/net/java/com/android/server/IpSecServiceParameterizedTest.java43
-rwxr-xr-xtools/aosp/aosp_sha.sh20
112 files changed, 2729 insertions, 1626 deletions
diff --git a/Android.bp b/Android.bp
index aeb3cebe8a13..cb7f7a2317d3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1221,7 +1221,7 @@ metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.x
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
"--hide SdkConstant --hide HiddenTypeParameter --hide Todo --hide Typo"
-doc_defaults {
+stubs_defaults {
name: "metalava-api-stubs-default",
srcs: [
":opt-telephony-srcs",
@@ -1246,10 +1246,9 @@ doc_defaults {
],
local_sourcepaths: frameworks_base_subdirs,
installable: false,
- metalava_enabled: true,
- metalava_annotations_enabled: true,
- metalava_previous_api: ":last-released-public-api",
- metalava_merge_annotations_dirs: [
+ annotations_enabled: true,
+ previous_api: ":last-released-public-api",
+ merge_annotations_dirs: [
"metalava-manual",
"ojluni-annotated-stubs",
],
@@ -1481,7 +1480,7 @@ java_library_static {
],
}
-droiddoc {
+droidstubs {
name: "hiddenapi-lists-docs",
defaults: ["metalava-api-stubs-default"],
arg_files: [
@@ -1540,7 +1539,7 @@ filegroup {
],
}
-droiddoc {
+droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
api_filename: "public_api.txt",
@@ -1562,7 +1561,7 @@ droiddoc {
},
}
-droiddoc {
+droidstubs {
name: "system-api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
api_tag_name: "SYSTEM",
@@ -1586,7 +1585,7 @@ droiddoc {
},
}
-droiddoc {
+droidstubs {
name: "test-api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
api_tag_name: "TEST",
diff --git a/api/current.txt b/api/current.txt
index e31f8a05611d..b9e00f6fc0be 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -42654,6 +42654,7 @@ package android.telephony {
method public static int[] getSubscriptionIds(int);
method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
method public boolean isNetworkRoaming(int);
+ method public static boolean isValidSubscriptionId(int);
method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
method public void setSubscriptionOverrideCongested(int, boolean, long);
diff --git a/api/system-current.txt b/api/system-current.txt
index 1e1c621a561d..e2c59cb10dd4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6785,7 +6785,6 @@ package android.webkit {
method public static android.content.pm.PackageInfo getLoadedPackageInfo();
method public static int loadWebViewNativeLibraryFromPackage(java.lang.String, java.lang.ClassLoader);
method public static void prepareWebViewInZygote();
- field public static final java.lang.String CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY = "persist.sys.webview.vmsize";
field public static final int LIBLOAD_ADDRESS_SPACE_NOT_RESERVED = 2; // 0x2
field public static final int LIBLOAD_FAILED_JNI_CALL = 7; // 0x7
field public static final int LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES = 4; // 0x4
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d117f390705d..2c07431ee38a 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -91,7 +91,7 @@ message Atom {
ActivityForegroundStateChanged activity_foreground_state_changed = 42;
IsolatedUidChanged isolated_uid_changed = 43;
PacketWakeupOccurred packet_wakeup_occurred = 44;
- // 45 is available
+ WallClockTimeShifted wall_clock_time_shifted = 45;
AnomalyDetected anomaly_detected = 46;
AppBreadcrumbReported app_breadcrumb_reported = 47;
AppStartOccurred app_start_occurred = 48;
@@ -1479,6 +1479,18 @@ message AppBreadcrumbReported {
}
/**
+ * Logs the wall-clock time when a significant wall-clock time shift occurs.
+ * For example, this could be due to the user manually changing the time.
+ *
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/AlarmManagerService.java
+ */
+message WallClockTimeShifted {
+ // New wall-clock time in milliseconds, according to System.currentTimeMillis().
+ optional int64 wall_clock_timestamp_millis = 1;
+}
+
+/**
* Logs when statsd detects an anomaly.
*
* Logged from:
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index eec90fc8d053..afd8ec2212fe 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -49,7 +49,6 @@ const int FIELD_ID_DATA = 1;
// for EventMetricData
const int FIELD_ID_ELAPSED_TIMESTAMP_NANOS = 1;
const int FIELD_ID_ATOMS = 2;
-const int FIELD_ID_WALL_CLOCK_TIMESTAMP_NANOS = 3;
EventMetricProducer::EventMetricProducer(const ConfigKey& key, const EventMetric& metric,
const int conditionIndex,
@@ -146,13 +145,9 @@ void EventMetricProducer::onMatchedLogEventInternalLocked(
if (truncateTimestamp) {
mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
(long long)truncateTimestampNsToFiveMinutes(event.GetElapsedTimestampNs()));
- mProto->write(FIELD_TYPE_INT64 | FIELD_ID_WALL_CLOCK_TIMESTAMP_NANOS,
- (long long)truncateTimestampNsToFiveMinutes(getWallClockNs()));
} else {
mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
(long long)event.GetElapsedTimestampNs());
- mProto->write(FIELD_TYPE_INT64 | FIELD_ID_WALL_CLOCK_TIMESTAMP_NANOS,
- (long long)getWallClockNs());
}
uint64_t eventToken = mProto->start(FIELD_TYPE_MESSAGE | FIELD_ID_ATOMS);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index bcfcd7a4f06e..02b97734d3ff 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -63,7 +63,6 @@ const int FIELD_ID_DIMENSION_LEAF_IN_CONDITION = 5;
// for GaugeBucketInfo
const int FIELD_ID_ATOM = 3;
const int FIELD_ID_ELAPSED_ATOM_TIMESTAMP = 4;
-const int FIELD_ID_WALL_CLOCK_ATOM_TIMESTAMP = 5;
const int FIELD_ID_BUCKET_NUM = 6;
const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 7;
const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 8;
@@ -286,16 +285,9 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const int64_t elapsedTimestampNs = truncateTimestamp ?
truncateTimestampNsToFiveMinutes(atom.mElapsedTimestamps) :
atom.mElapsedTimestamps;
- const int64_t wallClockNs = truncateTimestamp ?
- truncateTimestampNsToFiveMinutes(atom.mWallClockTimestampNs) :
- atom.mWallClockTimestampNs;
protoOutput->write(
FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED | FIELD_ID_ELAPSED_ATOM_TIMESTAMP,
(long long)elapsedTimestampNs);
- protoOutput->write(
- FIELD_TYPE_INT64 | FIELD_COUNT_REPEATED |
- FIELD_ID_WALL_CLOCK_ATOM_TIMESTAMP,
- (long long)wallClockNs);
}
}
protoOutput->end(bucketInfoToken);
@@ -450,7 +442,7 @@ void GaugeMetricProducer::onMatchedLogEventInternalLocked(
if ((*mCurrentSlicedBucket)[eventKey].size() >= mGaugeAtomsPerDimensionLimit) {
return;
}
- GaugeAtom gaugeAtom(getGaugeFields(event), eventTimeNs, getWallClockNs());
+ GaugeAtom gaugeAtom(getGaugeFields(event), eventTimeNs);
(*mCurrentSlicedBucket)[eventKey].push_back(gaugeAtom);
// Anomaly detection on gauge metric only works when there is one numeric
// field specified.
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index e3da5db4b90e..6379389218fd 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -33,12 +33,11 @@ namespace os {
namespace statsd {
struct GaugeAtom {
- GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs, int64_t wallClockNs)
- : mFields(fields), mElapsedTimestamps(elapsedTimeNs), mWallClockTimestampNs(wallClockNs) {
+ GaugeAtom(std::shared_ptr<vector<FieldValue>> fields, int64_t elapsedTimeNs)
+ : mFields(fields), mElapsedTimestamps(elapsedTimeNs) {
}
std::shared_ptr<vector<FieldValue>> mFields;
int64_t mElapsedTimestamps;
- int64_t mWallClockTimestampNs;
};
struct GaugeBucket {
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index db7e680f1d37..ab0b23cc009d 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -46,7 +46,7 @@ message EventMetricData {
optional Atom atom = 2;
- optional int64 wall_clock_timestamp_nanos = 3;
+ optional int64 wall_clock_timestamp_nanos = 3 [deprecated = true];
}
message CountBucketInfo {
@@ -142,7 +142,7 @@ message GaugeBucketInfo {
repeated int64 elapsed_timestamp_nanos = 4;
- repeated int64 wall_clock_timestamp_nanos = 5;
+ repeated int64 wall_clock_timestamp_nanos = 5 [deprecated = true];
optional int64 bucket_num = 6;
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index ea6eb3f3d712..5b6f167984dc 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -148,7 +148,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+ EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
@@ -271,7 +271,7 @@ TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents) {
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+ EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
@@ -375,7 +375,6 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
EXPECT_EQ(configAddedTimeNs + 55, data.bucket_info(0).elapsed_timestamp_nanos(0));
- EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 3de8d0da2c3b..5c1ef01dd576 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -173,7 +173,7 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
if (sampling_type == GaugeMetric::ALL_CONDITION_CHANGES) {
EXPECT_EQ(2, data.bucket_info(0).atom_size());
EXPECT_EQ(2, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(2, data.bucket_info(0).wall_clock_timestamp_nanos_size());
+ EXPECT_EQ(0, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -192,7 +192,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(1, data.bucket_info(1).atom_size());
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(1, data.bucket_info(1).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
data.bucket_info(1).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -206,7 +205,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(2, data.bucket_info(2).atom_size());
EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(2, data.bucket_info(2).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
data.bucket_info(2).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
@@ -226,7 +224,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
} else {
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -239,7 +236,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(1, data.bucket_info(1).atom_size());
EXPECT_EQ(1, data.bucket_info(1).elapsed_timestamp_nanos_size());
- EXPECT_EQ(1, data.bucket_info(1).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
data.bucket_info(1).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
@@ -253,7 +249,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(1, data.bucket_info(2).atom_size());
EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
- EXPECT_EQ(1, data.bucket_info(2).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
data.bucket_info(2).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
@@ -276,7 +271,6 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
EXPECT_EQ(1, data.bucket_info_size());
EXPECT_EQ(1, data.bucket_info(0).atom_size());
EXPECT_EQ(1, data.bucket_info(0).elapsed_timestamp_nanos_size());
- EXPECT_EQ(1, data.bucket_info(0).wall_clock_timestamp_nanos_size());
EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index d9d177760243..9e2050327ece 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -234,7 +234,7 @@ public class PackageInfo implements Parcelable {
/**
* Array of all signatures read from the package file. This is only filled
* in if the flag {@link PackageManager#GET_SIGNATURES} was set. A package
- * must be singed with at least one certificate which is at position zero.
+ * must be signed with at least one certificate which is at position zero.
* The package can be signed with additional certificates which appear as
* subsequent entries.
*
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 1ee3c933b326..cb336597cb8f 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -58,7 +58,7 @@ import java.util.List;
* execute in parallel with any {@link Surface} initialization, such as waiting for a
* {@link android.view.SurfaceView} to be ready as part of the UI initialization.</li>
*
- * <li>The third and most complex usage pattern inlvolves surface sharing. Once instantiated an
+ * <li>The third and most complex usage pattern involves surface sharing. Once instantiated an
* OutputConfiguration can be enabled for surface sharing via {@link #enableSurfaceSharing}. This
* must be done before creating a new capture session and enables calls to
* {@link CameraCaptureSession#updateOutputConfiguration}. An OutputConfiguration with enabled
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 6d9ba778d09a..7e52ca331f9f 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -141,13 +141,6 @@ public final class BrightnessConfiguration implements Parcelable {
private String mDescription;
/**
- * STOPSHIP remove when app has stopped using this.
- * @hide
- */
- public Builder() {
- }
-
- /**
* Constructs the builder with the control points for the brightness curve.
*
* Brightness curves must have strictly increasing ambient brightness values in lux and
@@ -159,24 +152,6 @@ public final class BrightnessConfiguration implements Parcelable {
* @throws IllegalArgumentException if the nit levels are not monotonically increasing.
*/
public Builder(float[] lux, float[] nits) {
- setCurve(lux, nits);
- }
-
- /**
- * Sets the control points for the brightness curve.
- *
- * Brightness curves must have strictly increasing ambient brightness values in lux and
- * monotonically increasing display brightness values in nits. In addition, the initial
- * control point must be 0 lux.
- *
- * @throws IllegalArgumentException if the initial control point is not at 0 lux.
- * @throws IllegalArgumentException if the lux levels are not strictly increasing.
- * @throws IllegalArgumentException if the nit levels are not monotonically increasing.
- *
- * STOPSHIP remove when app has stopped using this.
- * @hide
- */
- public Builder setCurve(float[] lux, float[] nits) {
Preconditions.checkNotNull(lux);
Preconditions.checkNotNull(nits);
if (lux.length == 0 || nits.length == 0) {
@@ -190,11 +165,10 @@ public final class BrightnessConfiguration implements Parcelable {
}
Preconditions.checkArrayElementsInRange(lux, 0, Float.MAX_VALUE, "lux");
Preconditions.checkArrayElementsInRange(nits, 0, Float.MAX_VALUE, "nits");
- checkMonotonic(lux, true/*strictly increasing*/, "lux");
+ checkMonotonic(lux, true /*strictly increasing*/, "lux");
checkMonotonic(nits, false /*strictly increasing*/, "nits");
mCurveLux = lux;
mCurveNits = nits;
- return this;
}
/**
diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java
index 00a1f6feecc5..4080ee625a0f 100644
--- a/core/java/android/inputmethodservice/IInputMethodWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java
@@ -87,8 +87,8 @@ class IInputMethodWrapper extends IInputMethod.Stub
* guarantees that {@link #bindInput(InputBinding)},
* {@link #startInput(IBinder, IInputContext, int, EditorInfo, boolean)}, and
* {@link #unbindInput()} are called with the same order as the original calls
- * in {@link com.android.server.InputMethodManagerService}. See {@link IBinder#FLAG_ONEWAY}
- * for detailed semantics.</p>
+ * in {@link com.android.server.inputmethod.InputMethodManagerService}.
+ * See {@link IBinder#FLAG_ONEWAY} for detailed semantics.</p>
*/
AtomicBoolean mIsUnbindIssued = null;
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 9bcc6001615f..40465ceafcb8 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -197,7 +197,7 @@ public abstract class Uri implements Parcelable, Comparable<Uri> {
*
* <p>Example: "//www.google.com/search?q=android"
*
- * @return the decoded scheme-specific-part
+ * @return the encoded scheme-specific-part
*/
public abstract String getEncodedSchemeSpecificPart();
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index b5ade2a3b654..0476cf8961a5 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -39,7 +39,6 @@ public class FeatureFlagUtils {
private static final Map<String, String> DEFAULT_FLAGS;
static {
DEFAULT_FLAGS = new HashMap<>();
- DEFAULT_FLAGS.put("settings_battery_display_app_list", "false");
DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false");
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 61a697282dcb..a7d7a8d67f64 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -28,7 +28,7 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Slog;
-import com.android.internal.inputmethod.LocaleUtils;
+import com.android.internal.inputmethod.InputMethodUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -384,7 +384,7 @@ public final class InputMethodSubtype implements Parcelable {
if (!TextUtils.isEmpty(mSubtypeLanguageTag)) {
mCachedLocaleObj = Locale.forLanguageTag(mSubtypeLanguageTag);
} else {
- mCachedLocaleObj = LocaleUtils.constructLocaleFromString(mSubtypeLocale);
+ mCachedLocaleObj = InputMethodUtils.constructLocaleFromString(mSubtypeLocale);
}
return mCachedLocaleObj;
}
diff --git a/core/java/android/view/textservice/SpellCheckerSubtype.java b/core/java/android/view/textservice/SpellCheckerSubtype.java
index 41b70b61fd4a..026610ecb6f9 100644
--- a/core/java/android/view/textservice/SpellCheckerSubtype.java
+++ b/core/java/android/view/textservice/SpellCheckerSubtype.java
@@ -25,7 +25,7 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Slog;
-import com.android.internal.inputmethod.LocaleUtils;
+import com.android.internal.inputmethod.InputMethodUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -228,7 +228,7 @@ public final class SpellCheckerSubtype implements Parcelable {
if (!TextUtils.isEmpty(mSubtypeLanguageTag)) {
return Locale.forLanguageTag(mSubtypeLanguageTag);
}
- return LocaleUtils.constructLocaleFromString(mSubtypeLocale);
+ return InputMethodUtils.constructLocaleFromString(mSubtypeLocale);
}
/**
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index e9a9e8f80662..46b1f6e6189e 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -51,9 +51,6 @@ public final class WebViewFactory {
private static final String CHROMIUM_WEBVIEW_FACTORY_METHOD = "create";
- public static final String CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY =
- "persist.sys.webview.vmsize";
-
private static final String LOGTAG = "WebViewFactory";
private static final boolean DEBUG = false;
diff --git a/core/java/android/webkit/WebViewLibraryLoader.java b/core/java/android/webkit/WebViewLibraryLoader.java
index cabba06bdff5..5a6aebaaad51 100644
--- a/core/java/android/webkit/WebViewLibraryLoader.java
+++ b/core/java/android/webkit/WebViewLibraryLoader.java
@@ -17,15 +17,14 @@
package android.webkit;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
-import android.content.pm.ApplicationInfo;
+import android.app.ActivityThread;
+import android.app.LoadedApk;
+import android.content.Context;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Process;
import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -33,11 +32,7 @@ import com.android.server.LocalServices;
import dalvik.system.VMRuntime;
-import java.io.File;
-import java.io.IOException;
import java.util.Arrays;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
/**
* @hide
@@ -50,7 +45,6 @@ public class WebViewLibraryLoader {
"/data/misc/shared_relro/libwebviewchromium32.relro";
private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_64 =
"/data/misc/shared_relro/libwebviewchromium64.relro";
- private static final long CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES = 100 * 1024 * 1024;
private static final boolean DEBUG = false;
@@ -69,18 +63,26 @@ public class WebViewLibraryLoader {
boolean result = false;
boolean is64Bit = VMRuntime.getRuntime().is64Bit();
try {
- if (args.length != 1 || args[0] == null) {
+ if (args.length != 2 || args[0] == null || args[1] == null) {
Log.e(LOGTAG, "Invalid RelroFileCreator args: " + Arrays.toString(args));
return;
}
- Log.v(LOGTAG, "RelroFileCreator (64bit = " + is64Bit + "), lib: " + args[0]);
+ String packageName = args[0];
+ String libraryFileName = args[1];
+ Log.v(LOGTAG, "RelroFileCreator (64bit = " + is64Bit + "), package: "
+ + packageName + " library: " + libraryFileName);
if (!sAddressSpaceReserved) {
Log.e(LOGTAG, "can't create relro file; address space not reserved");
return;
}
- result = nativeCreateRelroFile(args[0] /* path */,
+ LoadedApk apk = ActivityThread.currentActivityThread().getPackageInfo(
+ packageName,
+ null,
+ Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
+ result = nativeCreateRelroFile(libraryFileName,
is64Bit ? CHROMIUM_WEBVIEW_NATIVE_RELRO_64 :
- CHROMIUM_WEBVIEW_NATIVE_RELRO_32);
+ CHROMIUM_WEBVIEW_NATIVE_RELRO_32,
+ apk.getClassLoader());
if (result && DEBUG) Log.v(LOGTAG, "created relro file");
} finally {
// We must do our best to always notify the update service, even if something fails.
@@ -101,7 +103,8 @@ public class WebViewLibraryLoader {
/**
* Create a single relro file by invoking an isolated process that to do the actual work.
*/
- static void createRelroFile(final boolean is64Bit, @NonNull WebViewNativeLibrary nativeLib) {
+ static void createRelroFile(final boolean is64Bit, @NonNull String packageName,
+ @NonNull String libraryFileName) {
final String abi =
is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
@@ -119,13 +122,10 @@ public class WebViewLibraryLoader {
};
try {
- if (nativeLib == null || nativeLib.path == null) {
- throw new IllegalArgumentException(
- "Native library paths to the WebView RelRo process must not be null!");
- }
boolean success = LocalServices.getService(ActivityManagerInternal.class)
.startIsolatedProcess(
- RelroFileCreator.class.getName(), new String[] { nativeLib.path },
+ RelroFileCreator.class.getName(),
+ new String[] { packageName, libraryFileName },
"WebViewLoader-" + abi, abi, Process.SHARED_RELRO_UID, crashHandler);
if (!success) throw new Exception("Failed to start the relro file creator process");
} catch (Throwable t) {
@@ -140,83 +140,50 @@ public class WebViewLibraryLoader {
* be called whenever we change WebView provider.
* @return the number of relro processes started.
*/
- static int prepareNativeLibraries(PackageInfo webviewPackageInfo)
- throws WebViewFactory.MissingWebViewPackageException {
- WebViewNativeLibrary nativeLib32bit =
- getWebViewNativeLibrary(webviewPackageInfo, false /* is64bit */);
- WebViewNativeLibrary nativeLib64bit =
- getWebViewNativeLibrary(webviewPackageInfo, true /* is64bit */);
- updateWebViewZygoteVmSize(nativeLib32bit, nativeLib64bit);
-
- return createRelros(nativeLib32bit, nativeLib64bit);
+ static int prepareNativeLibraries(@NonNull PackageInfo webViewPackageInfo) {
+ // TODO(torne): new way of calculating VM size
+ // updateWebViewZygoteVmSize(nativeLib32bit, nativeLib64bit);
+ String libraryFileName = WebViewFactory.getWebViewLibrary(
+ webViewPackageInfo.applicationInfo);
+ if (libraryFileName == null) {
+ // Can't do anything with no filename, don't spawn any processes.
+ return 0;
+ }
+ return createRelros(webViewPackageInfo.packageName, libraryFileName);
}
/**
* @return the number of relro processes started.
*/
- private static int createRelros(@Nullable WebViewNativeLibrary nativeLib32bit,
- @Nullable WebViewNativeLibrary nativeLib64bit) {
+ private static int createRelros(@NonNull String packageName, @NonNull String libraryFileName) {
if (DEBUG) Log.v(LOGTAG, "creating relro files");
int numRelros = 0;
if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
- if (nativeLib32bit == null) {
- Log.e(LOGTAG, "No 32-bit WebView library path, skipping relro creation.");
- } else {
- if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro");
- createRelroFile(false /* is64Bit */, nativeLib32bit);
- numRelros++;
- }
+ if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro");
+ createRelroFile(false /* is64Bit */, packageName, libraryFileName);
+ numRelros++;
}
if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
- if (nativeLib64bit == null) {
- Log.e(LOGTAG, "No 64-bit WebView library path, skipping relro creation.");
- } else {
- if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro");
- createRelroFile(true /* is64Bit */, nativeLib64bit);
- numRelros++;
- }
+ if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro");
+ createRelroFile(true /* is64Bit */, packageName, libraryFileName);
+ numRelros++;
}
return numRelros;
}
/**
- *
- * @return the native WebView libraries in the new WebView APK.
- */
- private static void updateWebViewZygoteVmSize(
- @Nullable WebViewNativeLibrary nativeLib32bit,
- @Nullable WebViewNativeLibrary nativeLib64bit)
- throws WebViewFactory.MissingWebViewPackageException {
- // Find the native libraries of the new WebView package, to change the size of the
- // memory region in the Zygote reserved for the library.
- long newVmSize = 0L;
-
- if (nativeLib32bit != null) newVmSize = Math.max(newVmSize, nativeLib32bit.size);
- if (nativeLib64bit != null) newVmSize = Math.max(newVmSize, nativeLib64bit.size);
-
- if (DEBUG) {
- Log.v(LOGTAG, "Based on library size, need " + newVmSize
- + " bytes of address space.");
- }
- // The required memory can be larger than the file on disk (due to .bss), and an
- // upgraded version of the library will likely be larger, so always attempt to
- // reserve twice as much as we think to allow for the library to grow during this
- // boot cycle.
- newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
- Log.d(LOGTAG, "Setting new address space to " + newVmSize);
- setWebViewZygoteVmSize(newVmSize);
- }
-
- /**
* Reserve space for the native library to be loaded into.
*/
static void reserveAddressSpaceInZygote() {
System.loadLibrary("webviewchromium_loader");
- long addressSpaceToReserve =
- SystemProperties.getLong(WebViewFactory.CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
- CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES);
+ boolean is64Bit = VMRuntime.getRuntime().is64Bit();
+ // On 64-bit address space is really cheap and we can reserve 1GB which is plenty.
+ // On 32-bit it's fairly scarce and we should keep it to a realistic number that
+ // permits some future growth but doesn't hog space: we use 100MB which is more than 2x
+ // the current requirement.
+ long addressSpaceToReserve = is64Bit ? 1 * 1024 * 1024 * 1024 : 100 * 1024 * 1024;
sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve);
if (sAddressSpaceReserved) {
@@ -253,106 +220,7 @@ public class WebViewLibraryLoader {
return result;
}
- /**
- * Fetch WebView's native library paths from {@param packageInfo}.
- * @hide
- */
- @Nullable
- @VisibleForTesting
- public static WebViewNativeLibrary getWebViewNativeLibrary(PackageInfo packageInfo,
- boolean is64bit) throws WebViewFactory.MissingWebViewPackageException {
- ApplicationInfo ai = packageInfo.applicationInfo;
- final String nativeLibFileName = WebViewFactory.getWebViewLibrary(ai);
-
- String dir = getWebViewNativeLibraryDirectory(ai, is64bit /* 64bit */);
-
- WebViewNativeLibrary lib = findNativeLibrary(ai, nativeLibFileName,
- is64bit ? Build.SUPPORTED_64_BIT_ABIS : Build.SUPPORTED_32_BIT_ABIS, dir);
-
- if (DEBUG) {
- Log.v(LOGTAG, String.format("Native %d-bit lib: %s", is64bit ? 64 : 32, lib.path));
- }
- return lib;
- }
-
- /**
- * @return the directory of the native WebView library with bitness {@param is64bit}.
- * @hide
- */
- @VisibleForTesting
- public static String getWebViewNativeLibraryDirectory(ApplicationInfo ai, boolean is64bit) {
- // Primary arch has the same bitness as the library we are looking for.
- if (is64bit == VMRuntime.is64BitAbi(ai.primaryCpuAbi)) return ai.nativeLibraryDir;
-
- // Secondary arch has the same bitness as the library we are looking for.
- if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) {
- return ai.secondaryNativeLibraryDir;
- }
-
- return "";
- }
-
- /**
- * @return an object describing a native WebView library given the directory path of that
- * library, or null if the library couldn't be found.
- */
- @Nullable
- private static WebViewNativeLibrary findNativeLibrary(ApplicationInfo ai,
- String nativeLibFileName, String[] abiList, String libDirectory)
- throws WebViewFactory.MissingWebViewPackageException {
- if (TextUtils.isEmpty(libDirectory)) return null;
- String libPath = libDirectory + "/" + nativeLibFileName;
- File f = new File(libPath);
- if (f.exists()) {
- return new WebViewNativeLibrary(libPath, f.length());
- } else {
- return getLoadFromApkPath(ai.sourceDir, abiList, nativeLibFileName);
- }
- }
-
- /**
- * @hide
- */
- @VisibleForTesting
- public static class WebViewNativeLibrary {
- public final String path;
- public final long size;
-
- WebViewNativeLibrary(String path, long size) {
- this.path = path;
- this.size = size;
- }
- }
-
- private static WebViewNativeLibrary getLoadFromApkPath(String apkPath,
- String[] abiList,
- String nativeLibFileName)
- throws WebViewFactory.MissingWebViewPackageException {
- // Search the APK for a native library conforming to a listed ABI.
- try (ZipFile z = new ZipFile(apkPath)) {
- for (String abi : abiList) {
- final String entry = "lib/" + abi + "/" + nativeLibFileName;
- ZipEntry e = z.getEntry(entry);
- if (e != null && e.getMethod() == ZipEntry.STORED) {
- // Return a path formatted for dlopen() load from APK.
- return new WebViewNativeLibrary(apkPath + "!/" + entry, e.getSize());
- }
- }
- } catch (IOException e) {
- throw new WebViewFactory.MissingWebViewPackageException(e);
- }
- return null;
- }
-
- /**
- * Sets the size of the memory area in which to store the relro section.
- */
- private static void setWebViewZygoteVmSize(long vmSize) {
- SystemProperties.set(WebViewFactory.CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY,
- Long.toString(vmSize));
- }
-
static native boolean nativeReserveAddressSpace(long addressSpaceToReserve);
- static native boolean nativeCreateRelroFile(String lib, String relro);
+ static native boolean nativeCreateRelroFile(String lib, String relro, ClassLoader clazzLoader);
static native int nativeLoadWithRelroFile(String lib, String relro, ClassLoader clazzLoader);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 0645a162f377..d9132736232a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -313,6 +313,7 @@ import java.util.function.Supplier;
* @attr ref android.R.styleable#TextView_fallbackLineSpacing
* @attr ref android.R.styleable#TextView_letterSpacing
* @attr ref android.R.styleable#TextView_fontFeatureSettings
+ * @attr ref android.R.styleable#TextView_fontVariationSettings
* @attr ref android.R.styleable#TextView_breakStrategy
* @attr ref android.R.styleable#TextView_hyphenationFrequency
* @attr ref android.R.styleable#TextView_autoSizeTextType
@@ -4382,6 +4383,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*
* @see #getFontVariationSettings()
* @see FontVariationAxis
+ *
+ * @attr ref android.R.styleable#TextView_fontVariationSettings
*/
public boolean setFontVariationSettings(@Nullable String fontVariationSettings) {
final String existingSettings = mTextPaint.getFontVariationSettings();
diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
index 7b25a0691c40..3fd88dbb8704 100644
--- a/core/java/com/android/internal/colorextraction/types/Tonal.java
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -51,10 +51,8 @@ public class Tonal implements ExtractionType {
private static final boolean DEBUG = true;
- public static final int THRESHOLD_COLOR_LIGHT = 0xffe0e0e0;
public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0;
- public static final int THRESHOLD_COLOR_DARK = 0xff212121;
- public static final int MAIN_COLOR_DARK = 0xff000000;
+ public static final int MAIN_COLOR_DARK = 0xff212121;
private final TonalPalette mGreyPalette;
private final ArrayList<TonalPalette> mTonalPalettes;
@@ -197,12 +195,12 @@ public class Tonal implements ExtractionType {
// light fallback or darker than our dark fallback.
ColorUtils.colorToHSL(mainColor, mTmpHSL);
final float mainLuminosity = mTmpHSL[2];
- ColorUtils.colorToHSL(THRESHOLD_COLOR_LIGHT, mTmpHSL);
+ ColorUtils.colorToHSL(MAIN_COLOR_LIGHT, mTmpHSL);
final float lightLuminosity = mTmpHSL[2];
if (mainLuminosity > lightLuminosity) {
return false;
}
- ColorUtils.colorToHSL(THRESHOLD_COLOR_DARK, mTmpHSL);
+ ColorUtils.colorToHSL(MAIN_COLOR_DARK, mTmpHSL);
final float darkLuminosity = mTmpHSL[2];
if (mainLuminosity < darkLuminosity) {
return false;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 1410ff9a0813..1e5b5c80f31b 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -334,6 +334,32 @@ public class InputMethodUtils {
return getDefaultEnabledImes(context, imis, false /* onlyMinimum */);
}
+ public static Locale constructLocaleFromString(String localeStr) {
+ if (TextUtils.isEmpty(localeStr)) {
+ return null;
+ }
+ // TODO: Use {@link Locale#toLanguageTag()} and {@link Locale#forLanguageTag(languageTag)}.
+ String[] localeParams = localeStr.split("_", 3);
+ if (localeParams.length >= 1 && "tl".equals(localeParams[0])) {
+ // Convert a locale whose language is "tl" to one whose language is "fil".
+ // For example, "tl_PH" will get converted to "fil_PH".
+ // Versions of Android earlier than Lollipop did not support three letter language
+ // codes, and used "tl" (Tagalog) as the language string for "fil" (Filipino).
+ // On Lollipop and above, the current three letter version must be used.
+ localeParams[0] = "fil";
+ }
+ // The length of localeStr is guaranteed to always return a 1 <= value <= 3
+ // because localeStr is not empty.
+ if (localeParams.length == 1) {
+ return new Locale(localeParams[0]);
+ } else if (localeParams.length == 2) {
+ return new Locale(localeParams[0], localeParams[1]);
+ } else if (localeParams.length == 3) {
+ return new Locale(localeParams[0], localeParams[1], localeParams[2]);
+ }
+ return null;
+ }
+
public static boolean containsSubtypeOf(final InputMethodInfo imi,
@Nullable final Locale locale, final boolean checkCountry, final String mode) {
if (locale == null) {
@@ -1294,7 +1320,133 @@ public class InputMethodUtils {
}
}
+ // For spell checker service manager.
+ // TODO: Should we have TextServicesUtils.java?
+ private static final Locale LOCALE_EN_US = new Locale("en", "US");
+ private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
+
+ /**
+ * Returns a list of {@link Locale} in the order of appropriateness for the default spell
+ * checker service.
+ *
+ * <p>If the system language is English, and the region is also explicitly specified in the
+ * system locale, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * <p>If the system language is English, but no region is specified in the system locale,
+ * the following fallback order will be applied.</p>
+ * <ul>
+ * <li>("en")</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * </ul>
+ *
+ * <p>If the system language is not English, the following fallback order will be applied.</p>
+ * <ul>
+ * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
+ * <li>(system-locale-language, system-locale-region) (if exists)</li>
+ * <li>(system-locale-language) (if exists)</li>
+ * <li>("en", "US")</li>
+ * <li>("en", "GB")</li>
+ * <li>("en")</li>
+ * </ul>
+ *
+ * @param systemLocale the current system locale to be taken into consideration.
+ * @return a list of {@link Locale}. The first one is considered to be most appropriate.
+ */
@VisibleForTesting
+ public static ArrayList<Locale> getSuitableLocalesForSpellChecker(
+ @Nullable final Locale systemLocale) {
+ final Locale systemLocaleLanguageCountryVariant;
+ final Locale systemLocaleLanguageCountry;
+ final Locale systemLocaleLanguage;
+ if (systemLocale != null) {
+ final String language = systemLocale.getLanguage();
+ final boolean hasLanguage = !TextUtils.isEmpty(language);
+ final String country = systemLocale.getCountry();
+ final boolean hasCountry = !TextUtils.isEmpty(country);
+ final String variant = systemLocale.getVariant();
+ final boolean hasVariant = !TextUtils.isEmpty(variant);
+ if (hasLanguage && hasCountry && hasVariant) {
+ systemLocaleLanguageCountryVariant = new Locale(language, country, variant);
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ }
+ if (hasLanguage && hasCountry) {
+ systemLocaleLanguageCountry = new Locale(language, country);
+ } else {
+ systemLocaleLanguageCountry = null;
+ }
+ if (hasLanguage) {
+ systemLocaleLanguage = new Locale(language);
+ } else {
+ systemLocaleLanguage = null;
+ }
+ } else {
+ systemLocaleLanguageCountryVariant = null;
+ systemLocaleLanguageCountry = null;
+ systemLocaleLanguage = null;
+ }
+
+ final ArrayList<Locale> locales = new ArrayList<>();
+ if (systemLocaleLanguageCountryVariant != null) {
+ locales.add(systemLocaleLanguageCountryVariant);
+ }
+
+ if (Locale.ENGLISH.equals(systemLocaleLanguage)) {
+ if (systemLocaleLanguageCountry != null) {
+ // If the system language is English, and the region is also explicitly specified,
+ // following fallback order will be applied.
+ // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null]
+ // - en_US [if systemLocaleLanguageCountry is non-null and not en_US]
+ // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB]
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (!LOCALE_EN_US.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_US);
+ }
+ if (!LOCALE_EN_GB.equals(systemLocaleLanguageCountry)) {
+ locales.add(LOCALE_EN_GB);
+ }
+ locales.add(Locale.ENGLISH);
+ } else {
+ // If the system language is English, but no region is specified, following
+ // fallback order will be applied.
+ // - en
+ // - en_US
+ // - en_GB
+ locales.add(Locale.ENGLISH);
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ }
+ } else {
+ // If the system language is not English, the fallback order will be
+ // - systemLocaleLanguageCountry [if non-null]
+ // - systemLocaleLanguage [if non-null]
+ // - en_US
+ // - en_GB
+ // - en
+ if (systemLocaleLanguageCountry != null) {
+ locales.add(systemLocaleLanguageCountry);
+ }
+ if (systemLocaleLanguage != null) {
+ locales.add(systemLocaleLanguage);
+ }
+ locales.add(LOCALE_EN_US);
+ locales.add(LOCALE_EN_GB);
+ locales.add(Locale.ENGLISH);
+ }
+ return locales;
+ }
+
public static boolean isSoftInputModeStateVisibleAllowed(
int targetSdkVersion, int controlFlags) {
if (targetSdkVersion < Build.VERSION_CODES.P) {
@@ -1309,4 +1461,5 @@ public class InputMethodUtils {
}
return true;
}
+
}
diff --git a/core/java/com/android/internal/inputmethod/LocaleUtils.java b/core/java/com/android/internal/inputmethod/LocaleUtils.java
index f7360eb0fe13..eeb3854bcc55 100644
--- a/core/java/com/android/internal/inputmethod/LocaleUtils.java
+++ b/core/java/com/android/internal/inputmethod/LocaleUtils.java
@@ -16,6 +16,8 @@
package com.android.internal.inputmethod;
+import com.android.internal.annotations.VisibleForTesting;
+
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -23,8 +25,6 @@ import android.icu.util.ULocale;
import android.os.LocaleList;
import android.text.TextUtils;
-import com.android.internal.annotations.VisibleForTesting;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -208,151 +208,4 @@ public final class LocaleUtils {
dest.add(sources.get(entry.mIndex));
}
}
-
- public static Locale constructLocaleFromString(String localeStr) {
- if (TextUtils.isEmpty(localeStr)) {
- return null;
- }
- // TODO: Use {@link Locale#toLanguageTag()} and {@link Locale#forLanguageTag(languageTag)}.
- String[] localeParams = localeStr.split("_", 3);
- if (localeParams.length >= 1 && "tl".equals(localeParams[0])) {
- // Convert a locale whose language is "tl" to one whose language is "fil".
- // For example, "tl_PH" will get converted to "fil_PH".
- // Versions of Android earlier than Lollipop did not support three letter language
- // codes, and used "tl" (Tagalog) as the language string for "fil" (Filipino).
- // On Lollipop and above, the current three letter version must be used.
- localeParams[0] = "fil";
- }
- // The length of localeStr is guaranteed to always return a 1 <= value <= 3
- // because localeStr is not empty.
- if (localeParams.length == 1) {
- return new Locale(localeParams[0]);
- } else if (localeParams.length == 2) {
- return new Locale(localeParams[0], localeParams[1]);
- } else if (localeParams.length == 3) {
- return new Locale(localeParams[0], localeParams[1], localeParams[2]);
- }
- return null;
- }
-
- /**
- * Returns a list of {@link Locale} in the order of appropriateness for the default spell
- * checker service.
- *
- * <p>If the system language is English, and the region is also explicitly specified in the
- * system locale, the following fallback order will be applied.</p>
- * <ul>
- * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
- * <li>(system-locale-language, system-locale-region)</li>
- * <li>("en", "US")</li>
- * <li>("en", "GB")</li>
- * <li>("en")</li>
- * </ul>
- *
- * <p>If the system language is English, but no region is specified in the system locale,
- * the following fallback order will be applied.</p>
- * <ul>
- * <li>("en")</li>
- * <li>("en", "US")</li>
- * <li>("en", "GB")</li>
- * </ul>
- *
- * <p>If the system language is not English, the following fallback order will be applied.</p>
- * <ul>
- * <li>(system-locale-language, system-locale-region, system-locale-variant) (if exists)</li>
- * <li>(system-locale-language, system-locale-region) (if exists)</li>
- * <li>(system-locale-language) (if exists)</li>
- * <li>("en", "US")</li>
- * <li>("en", "GB")</li>
- * <li>("en")</li>
- * </ul>
- *
- * @param systemLocale the current system locale to be taken into consideration.
- * @return a list of {@link Locale}. The first one is considered to be most appropriate.
- */
- public static ArrayList<Locale> getSuitableLocalesForSpellChecker(
- @Nullable final Locale systemLocale) {
- final Locale systemLocaleLanguageCountryVariant;
- final Locale systemLocaleLanguageCountry;
- final Locale systemLocaleLanguage;
- if (systemLocale != null) {
- final String language = systemLocale.getLanguage();
- final boolean hasLanguage = !TextUtils.isEmpty(language);
- final String country = systemLocale.getCountry();
- final boolean hasCountry = !TextUtils.isEmpty(country);
- final String variant = systemLocale.getVariant();
- final boolean hasVariant = !TextUtils.isEmpty(variant);
- if (hasLanguage && hasCountry && hasVariant) {
- systemLocaleLanguageCountryVariant = new Locale(language, country, variant);
- } else {
- systemLocaleLanguageCountryVariant = null;
- }
- if (hasLanguage && hasCountry) {
- systemLocaleLanguageCountry = new Locale(language, country);
- } else {
- systemLocaleLanguageCountry = null;
- }
- if (hasLanguage) {
- systemLocaleLanguage = new Locale(language);
- } else {
- systemLocaleLanguage = null;
- }
- } else {
- systemLocaleLanguageCountryVariant = null;
- systemLocaleLanguageCountry = null;
- systemLocaleLanguage = null;
- }
-
- final ArrayList<Locale> locales = new ArrayList<>();
- if (systemLocaleLanguageCountryVariant != null) {
- locales.add(systemLocaleLanguageCountryVariant);
- }
-
- if (Locale.ENGLISH.equals(systemLocaleLanguage)) {
- if (systemLocaleLanguageCountry != null) {
- // If the system language is English, and the region is also explicitly specified,
- // following fallback order will be applied.
- // - systemLocaleLanguageCountry [if systemLocaleLanguageCountry is non-null]
- // - en_US [if systemLocaleLanguageCountry is non-null and not en_US]
- // - en_GB [if systemLocaleLanguageCountry is non-null and not en_GB]
- // - en
- if (systemLocaleLanguageCountry != null) {
- locales.add(systemLocaleLanguageCountry);
- }
- if (!Locale.US.equals(systemLocaleLanguageCountry)) {
- locales.add(Locale.US);
- }
- if (!Locale.UK.equals(systemLocaleLanguageCountry)) {
- locales.add(Locale.UK);
- }
- locales.add(Locale.ENGLISH);
- } else {
- // If the system language is English, but no region is specified, following
- // fallback order will be applied.
- // - en
- // - en_US
- // - en_GB
- locales.add(Locale.ENGLISH);
- locales.add(Locale.US);
- locales.add(Locale.UK);
- }
- } else {
- // If the system language is not English, the fallback order will be
- // - systemLocaleLanguageCountry [if non-null]
- // - systemLocaleLanguage [if non-null]
- // - en_US
- // - en_GB
- // - en
- if (systemLocaleLanguageCountry != null) {
- locales.add(systemLocaleLanguageCountry);
- }
- if (systemLocaleLanguage != null) {
- locales.add(systemLocaleLanguage);
- }
- locales.add(Locale.US);
- locales.add(Locale.UK);
- locales.add(Locale.ENGLISH);
- }
- return locales;
- }
}
diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java
index 16ca4fcdbe34..1038199cf109 100644
--- a/core/java/com/android/internal/util/ContrastColorUtil.java
+++ b/core/java/com/android/internal/util/ContrastColorUtil.java
@@ -455,7 +455,7 @@ public class ContrastColorUtil {
* Resolves {@param color} to an actual color if it is {@link Notification#COLOR_DEFAULT}
*/
public static int resolveColor(Context context, int color, boolean defaultBackgroundIsDark) {
- if (color == Notification.COLOR_DEFAULT) {
+ if (color == Notification.COLOR_DEFAULT || defaultBackgroundIsDark) {
int res = defaultBackgroundIsDark
? com.android.internal.R.color.notification_default_color_dark
: com.android.internal.R.color.notification_default_color_light;
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 21d750c59a4e..e65d11404a4e 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -1,24 +1,4 @@
-per-file AsyncChannel*=lorenzo@google.com
-per-file AsyncChannel*=satk@google.com
-per-file AsyncChannel*=silberst@google.com
-per-file BitUtils*=ek@google.com
-per-file BitUtils*=lorenzo@google.com
-per-file BitUtils*=satk@google.com
-per-file MessageUtils*=ek@google.com
-per-file MessageUtils*=lorenzo@google.com
-per-file MessageUtils*=satk@google.com
-per-file Protocol*=ek@google.com
-per-file Protocol*=lorenzo@google.com
-per-file Protocol*=quiche@google.com
-per-file Protocol*=satk@google.com
-per-file Protocol*=silberst@google.com
-per-file RingBuffer*=ek@google.com
-per-file RingBuffer*=lorenzo@google.com
-per-file RingBuffer*=satk@google.com
-per-file State*=ek@google.com
-per-file State*=lorenzo@google.com
-per-file State*=quiche@google.com
-per-file State*=silberst@google.com
-per-file TokenBucket*=ek@google.com
-per-file TokenBucket*=lorenzo@google.com
-per-file TokenBucket*=satk@google.com
+per-file AsyncChannel* = lorenzo@google.com, satk@google.com, etancohen@google.com
+per-file BitUtils*, MessageUtils*, Protocol*, RingBuffer*, TokenBucket* = jchalard@google.com, lorenzo@google.com, satk@google.com
+per-file Protocol* = etancohen@google.com, lorenzo@google.com
+per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index e03c1f8621be..7548c2257c06 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -60,7 +60,7 @@ public final class InputBindResult implements Parcelable {
/**
* Indicates that this is a temporary binding until the
* {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session
- * to {@link com.android.server.InputMethodManagerService} (IMMS).
+ * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS).
*
* <p>Note that in this state the IMS is already bound to IMMS but the logical session
* is not yet established on top of the IPC channel.</p>
@@ -73,7 +73,7 @@ public final class InputBindResult implements Parcelable {
/**
* Indicates that this is a temporary binding until the
* {@link android.inputmethodservice.InputMethodService} (IMS) establishes a valid session
- * to {@link com.android.server.InputMethodManagerService} (IMMS).
+ * to {@link com.android.server.inputmethod.InputMethodManagerService} (IMMS).
*
* <p>Note that in this state the IMMS has already initiated a connection to the IMS but
* the binding process is not completed yet.</p>
@@ -91,12 +91,14 @@ public final class InputBindResult implements Parcelable {
int SUCCESS_REPORT_WINDOW_FOCUS_ONLY = 3;
/**
* Indicates somehow
- * {@link com.android.server.InputMethodManagerService#startInputOrWindowGainedFocus} is
- * trying to return null {@link InputBindResult}, which must never happen.
+ * {@link
+ * com.android.server.inputmethod.InputMethodManagerService#startInputOrWindowGainedFocus}
+ * is trying to return null {@link InputBindResult}, which must never happen.
*/
int ERROR_NULL = 4;
/**
- * Indicates that {@link com.android.server.InputMethodManagerService} recognizes no IME.
+ * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService}
+ * recognizes no IME.
*/
int ERROR_NO_IME = 5;
/**
@@ -114,8 +116,8 @@ public final class InputBindResult implements Parcelable {
*/
int ERROR_SYSTEM_NOT_READY = 7;
/**
- * Indicates that {@link com.android.server.InputMethodManagerService} tried to connect to
- * an {@link android.inputmethodservice.InputMethodService} but failed.
+ * Indicates that {@link com.android.server.inputmethod.InputMethodManagerService} tried to
+ * connect to an {@link android.inputmethodservice.InputMethodService} but failed.
*
* @see android.content.Context#bindServiceAsUser(Intent, ServiceConnection, int, UserHandle)
*/
@@ -137,7 +139,8 @@ public final class InputBindResult implements Parcelable {
* The client should try to restart input when its {@link android.view.Window} is focused
* again.</p>
*
- * @see com.android.server.wm.WindowManagerService#inputMethodClientHasFocus(IInputMethodClient)
+ * @see com.android.server.wm.WindowManagerInternal#inputMethodClientHasFocus(
+ * IInputMethodClient)
*/
int ERROR_NOT_IME_TARGET_WINDOW = 11;
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f845bd0e3964..9ab55d62839b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -584,7 +584,7 @@
<protected-broadcast android:name="android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED" />
<protected-broadcast android:name="android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED" />
<protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
- <protected-broadcast android:name="com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
+ <protected-broadcast android:name="com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
<!-- Time zone rules update intents fired by the system server -->
<protected-broadcast android:name="com.android.intent.action.timezone.RULES_UPDATE_OPERATION" />
@@ -3352,7 +3352,7 @@
@hide
@removed -->
<permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|privileged" />
<!-- @SystemApi Allows an application to know what content is playing and control its playback.
<p>Not for use by third-party applications due to privacy of media consumption</p> -->
@@ -4120,11 +4120,6 @@
<permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
android:protectionLevel="signature" />
- <!-- Allows an application to read emergency info name.
- @hide <p>Not for use by third-party applications. -->
- <permission android:name="com.android.emergency.permission.READ_EMERGENCY_INFO_NAME"
- android:protectionLevel="signature" />
-
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 6932be373c0b..e153082045ec 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -284,7 +284,7 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'envoyer et d\'afficher des SMS ?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Stockage"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"accéder à des photos, à des contenus multimédias et à des fichiers sur votre appareil"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'accéder aux photos, contenus multimédias et fichiers sur votre appareil ?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à accéder aux photos, contenus multimédias et fichiers sur votre appareil ?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
<string name="permgrouprequest_microphone" msgid="9167492350681916038">"Permettre à &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; d\'enregistrer des contenus audio ?"</string>
@@ -1340,7 +1340,7 @@
<string name="ext_media_unmountable_notification_message" msgid="4193858924381066522">"Appuyez sur la notification pour résoudre le problème"</string>
<string name="ext_media_unmountable_notification_message" product="tv" msgid="3941179940297874950">"La <xliff:g id="NAME">%s</xliff:g> est corrompue. Sélectionnez cette option pour résoudre le problème."</string>
<string name="ext_media_unsupported_notification_title" msgid="3797642322958803257">"<xliff:g id="NAME">%s</xliff:g> non compatible"</string>
- <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Cet appareil n\'est pas compatible avec la mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\". Appuyez ici pour le configurer dans un format accepté."</string>
+ <string name="ext_media_unsupported_notification_message" msgid="6121601473787888589">"Cet appareil n\'est pas compatible avec le support \"<xliff:g id="NAME">%s</xliff:g>\". Appuyez ici pour le configurer dans un format accepté."</string>
<string name="ext_media_unsupported_notification_message" product="tv" msgid="3725436899820390906">"Cet appareil n\'est pas compatible avec cette <xliff:g id="NAME">%s</xliff:g>. Sélectionnez cette option pour la configurer dans un format accepté."</string>
<string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Retrait inattendu de mémoire \"<xliff:g id="NAME">%s</xliff:g>\""</string>
<string name="ext_media_badremoval_notification_message" msgid="8556885808951260574">"Éjectez le périphérique externe avant de le retirer pour éviter toute perte de contenu"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index d4b800ad2e04..6afe603993ab 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1895,10 +1895,10 @@
<string name="autofill_save_title_with_type" msgid="8637809388029313305">"<xliff:g id="TYPE">%1$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
<string name="autofill_save_title_with_2types" msgid="5214035651838265325">"<xliff:g id="TYPE_0">%1$s</xliff:g> और <xliff:g id="TYPE_1">%2$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
<string name="autofill_save_title_with_3types" msgid="6943161834231458441">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> और <xliff:g id="TYPE_2">%3$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; में सेव करें?"</string>
- <string name="autofill_update_title" msgid="4879673117448810818">"&lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt;? में अपडेट करें?"</string>
- <string name="autofill_update_title_with_type" msgid="339733442087186755">"<xliff:g id="TYPE">%1$s</xliff:g> को to &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; में अपडेट करें?"</string>
+ <string name="autofill_update_title" msgid="4879673117448810818">"&lt;b&gt;<xliff:g id="LABEL">%1$s</xliff:g>&lt;/b&gt; में अपडेट करें?"</string>
+ <string name="autofill_update_title_with_type" msgid="339733442087186755">"<xliff:g id="TYPE">%1$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%2$s</xliff:g>&lt;/b&gt; में अपडेट करें?"</string>
<string name="autofill_update_title_with_2types" msgid="6321714204167424745">"<xliff:g id="TYPE_0">%1$s</xliff:g> और <xliff:g id="TYPE_1">%2$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%3$s</xliff:g>&lt;/b&gt; में अपडेट करें?"</string>
- <string name="autofill_update_title_with_3types" msgid="5866735124066629287">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> और <xliff:g id="TYPE_2">%3$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; में अपडेट करें."</string>
+ <string name="autofill_update_title_with_3types" msgid="5866735124066629287">"<xliff:g id="TYPE_0">%1$s</xliff:g>, <xliff:g id="TYPE_1">%2$s</xliff:g> और <xliff:g id="TYPE_2">%3$s</xliff:g> को &lt;b&gt;<xliff:g id="LABEL">%4$s</xliff:g>&lt;/b&gt; में अपडेट करें?"</string>
<string name="autofill_save_yes" msgid="6398026094049005921">"सेव करें"</string>
<string name="autofill_save_no" msgid="2625132258725581787">"नहीं, धन्यवाद"</string>
<string name="autofill_update_yes" msgid="310358413273276958">"अपडेट करें"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 8b3f287d08aa..6a5f287d6f68 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -514,7 +514,7 @@
<string name="permdesc_imagesWrite" msgid="7073662756617474375">"Թույլ է տալիս հավելվածին փոփոխել ձեր լուսանկարների հավաքածուն:"</string>
<string name="permlab_mediaLocation" msgid="8675148183726247864">"ճանաչել տեղադրության մասին տվյալները մեդիա բովանդակության հավաքածուից"</string>
<string name="permdesc_mediaLocation" msgid="2237023389178865130">"Թույլ է տալիս հավելվածին ճանաչել տեղադրության մասին տվյալները ձեր մեդիա բովանդակության հավաքածուից:"</string>
- <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Կենսաչափական սարք չի գտնվել"</string>
+ <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Կենսաչափական սարքը հասանելի չէ"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Մատնահետքը հայտնաբերվել է մասամբ: Փորձեք նորից:"</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Չհաջողվեց մշակել մատնահետքը: Նորից փորձեք:"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Մատնահետքերի սենսորն աղտոտված է: Մաքրեք այն և փորձեք նորից:"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4cada6068fe7..4915111c9e07 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -284,7 +284,7 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"SMS メッセージの送信と表示を &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ストレージ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"端末内の写真、メディア、ファイルへのアクセス"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"端末内の写真、メディア、ファイルへのアクセスを &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"端末内の写真、メディア、ファイルへのアクセスを「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」に許可しますか?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"マイク"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"音声の録音"</string>
<string name="permgrouprequest_microphone" msgid="9167492350681916038">"音声の録音を &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に許可しますか?"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index dca94ff526e1..e228d35d7067 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -284,7 +284,7 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"ಎಸ್‌ಎಂಎಸ್‌ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಮತ್ತು ವೀಕ್ಷಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"ಸಂಗ್ರಹಣೆ"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ ಮತ್ತು ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"ಸಾಧನದಲ್ಲಿ ಫೋಟೋಗಳು, ಮಾಧ್ಯಮ, ಫೈಲ್‌ಗಳನ್ನು ಪ್ರವೇಶಿಸಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ಮೈಕ್ರೋಫೋನ್‌"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouprequest_microphone" msgid="9167492350681916038">"ಆಡಿಯೋ ರೆಕಾರ್ಡ್‌ ಮಾಡಲು &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
diff --git a/core/res/res/values-night/colors.xml b/core/res/res/values-night/colors.xml
index 351f8ea8643e..6bbd2587d78d 100644
--- a/core/res/res/values-night/colors.xml
+++ b/core/res/res/values-night/colors.xml
@@ -27,5 +27,5 @@
<color name="notification_default_color_dark">#ddffffff</color>
<!-- The background color of a notification card. -->
- <color name="notification_material_background_color">@*android:color/material_grey_900</color>
+ <color name="notification_material_background_color">@color/black</color>
</resources> \ No newline at end of file
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 5e3675ac6c3e..c8d4d05a3507 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -51,4 +51,7 @@ easier.
-->
<!-- DeviceDefault theme for a window that should look like the Settings app. -->
<style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault"/>
+
+ <!-- Theme for the dialog shown when an app crashes or ANRs. -->
+ <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert" />
</resources>
diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml
index 4eb2ff3b5970..45cf0f0fedb3 100644
--- a/core/res/res/values-night/values.xml
+++ b/core/res/res/values-night/values.xml
@@ -26,7 +26,7 @@
<item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
<!-- QS panel background -->
- <item name="colorBackgroundFloating">@color/material_grey_900</item>
+ <item name="colorBackgroundFloating">@color/black</item>
<!-- volume background -->
<item name="panelColorBackground">@color/material_grey_800</item>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index e31f161b5dd4..c14bce471bda 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -290,7 +290,7 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; отправлять и просматривать SMS?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Хранилище"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"доступ к фото, мультимедиа и файлам на вашем устройстве"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"Разрешить приложению &lt;b&gt;\"<xliff:g id="APP_NAME">%1$s</xliff:g>\"&lt;/b&gt; доступ к фото, мультимедиа и файлам на устройстве?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к фото, мультимедиа и файлам на устройстве?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"записывать аудио"</string>
<string name="permgrouprequest_microphone" msgid="9167492350681916038">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; записывать аудио?"</string>
@@ -305,7 +305,7 @@
<string name="permgrouprequest_phone" msgid="9166979577750581037">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; совершать звонки и управлять ими?"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Нательные датчики"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"доступ к данным датчиков о состоянии организма"</string>
- <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Разрешить приложению &lt;b&gt;\"<xliff:g id="APP_NAME">%1$s</xliff:g>\"&lt;/b&gt; доступ к данным датчиков о состоянии организма?"</string>
+ <string name="permgrouprequest_sensors" msgid="6349806962814556786">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к данным датчиков о состоянии организма?"</string>
<string name="permgrouplab_aural" msgid="965607064083134896">"Музыка"</string>
<string name="permgroupdesc_aural" msgid="4870189506255958055">"доступ к музыке"</string>
<string name="permgrouprequest_aural" msgid="6787926123071735620">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; доступ к музыке?"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 8b89a977faac..0f353f28b2f8 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -514,8 +514,7 @@
<string name="permdesc_imagesWrite" msgid="7073662756617474375">"ඔබගේ ඡායාරූප එකතුව වෙනස් කිරීමට යෙදුමට ඉඩ දෙයි."</string>
<string name="permlab_mediaLocation" msgid="8675148183726247864">"ඔබගේ මාධ්‍ය එකතුවෙන් ස්ථාන කියවන්න"</string>
<string name="permdesc_mediaLocation" msgid="2237023389178865130">"ඔබගේ මාධ්‍ය එකතුවෙන් ස්ථාන කියවීමට යෙදුමට ඉඩ දෙයි."</string>
- <!-- no translation found for biometric_error_hw_unavailable (645781226537551036) -->
- <skip />
+ <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"ජීවමිතික දෘඪාංග ලබා ගත නොහැකිය"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"ඇඟිලි සලකුණ අඩ වශයෙන් අනාවරණය කර ගැනිණි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"ඇඟිලි සලකුණ පිරිසැකසීමට නොහැකි විය. කරුණාකර නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"ඇඟිලි සලකුණු සංවේදකය අපිරිසිදුයි. කරුණාකර පිරිසිදු කර නැවත උත්සාහ කරන්න."</string>
@@ -523,8 +522,7 @@
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"ඇඟිල්ල වඩා සෙමෙන් ගෙන යන ලදි. කරුණාකර නැවත උත්සාහ කරන්න."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
- <!-- no translation found for biometric_not_recognized (5770511773560736082) -->
- <skip />
+ <string name="biometric_not_recognized" msgid="5770511773560736082">"හඳුනා නොගන්නා ලදී"</string>
<string name="fingerprint_authenticated" msgid="5309333983002526448">"ඇඟිලි සලකුණ සත්‍යාපනය කරන ලදී"</string>
<string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"ඇඟිලි සලකුණු දෘඪාංගය ලද නොහැකිය."</string>
<string name="fingerprint_error_no_space" msgid="1055819001126053318">"ඇඟිලි සලකුණ ගබඩා කළ නොහැක. දැනට පවතින ඇඟිලි සලකුණක් ඉවත් කරන්න."</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index b175f75acea9..35592a696d68 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -284,7 +284,7 @@
<string name="permgrouprequest_sms" msgid="7168124215838204719">"மெசேஜ்களை அனுப்பவும், பார்க்கவும் &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"சேமிப்பிடம்"</string>
<string name="permgroupdesc_storage" msgid="637758554581589203">"உங்கள் சாதனத்தில் உள்ள படங்கள், மீடியா மற்றும் கோப்புகளை அணுக வேண்டும்"</string>
- <string name="permgrouprequest_storage" msgid="7885942926944299560">"உங்கள் சாதனத்திலுள்ள படங்கள், மீடியா, ஃபைல்கள் ஆகியவற்றை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; பயன்பாட்டை அனுமதிக்கவா?"</string>
+ <string name="permgrouprequest_storage" msgid="7885942926944299560">"உங்கள் சாதனத்திலுள்ள படங்கள், மீடியா, ஃபைல்கள் ஆகியவற்றை அணுகுவதற்கு &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"மைக்ரோஃபோன்"</string>
<string name="permgroupdesc_microphone" msgid="4988812113943554584">"ஒலிப் பதிவு செய்யலாம்"</string>
<string name="permgrouprequest_microphone" msgid="9167492350681916038">"ஆடியோவைப் பதிவு செய்ய &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; பயன்பாட்டை அனுமதிக்கவா?"</string>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 377982a409c9..0712cbcfc024 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -15,7 +15,7 @@
-->
<resources>
<style name="Theme.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
- <style name="Theme.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
+ <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.Leanback.Dialog.AppError" />
<style name="Theme.Holo.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
<style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
<style name="Theme.Material.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
diff --git a/core/res/res/values-watch/themes.xml b/core/res/res/values-watch/themes.xml
index 04df1809878a..1be47baf4e7f 100644
--- a/core/res/res/values-watch/themes.xml
+++ b/core/res/res/values-watch/themes.xml
@@ -15,7 +15,7 @@
-->
<resources>
<!-- Theme for the dialog shown when an app crashes or ANRs. Override to make it dark. -->
- <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
+ <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert">
<item name="windowContentTransitions">false</item>
<item name="windowActivityTransitions">false</item>
<item name="windowCloseOnTouchOutside">false</item>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 0b04e0875718..966a5a53ffd8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -272,9 +272,9 @@
<string name="permgrouprequest_contacts" msgid="6032805601881764300">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;访问您的通讯录吗?"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"获取此设备的位置信息"</string>
- <string name="permgrouprequest_location" msgid="3788275734953323491">"允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;获取此设备的位置信息吗?"</string>
+ <string name="permgrouprequest_location" msgid="3788275734953323491">"要允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
<string name="permgrouprequestdetail_location" msgid="1113400215566814664">"只有当您使用该应用时,该应用才有权获取位置信息。"</string>
- <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"一律允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;获取此设备的位置信息吗?"</string>
+ <string name="permgroupbackgroundrequest_location" msgid="8461841153030844390">"一律允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”获取此设备的位置信息吗?"</string>
<string name="permgroupbackgroundrequestdetail_location" msgid="1715668276378108654">"即使您并未使用该应用,该应用也将始终有权获取位置信息。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index bd4ea2a6610e..bd36ed654915 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -514,7 +514,7 @@
<string name="permdesc_imagesWrite" msgid="7073662756617474375">"允許應用程式修改你的相片收藏。"</string>
<string name="permlab_mediaLocation" msgid="8675148183726247864">"讀取你的媒體收藏的位置資訊"</string>
<string name="permdesc_mediaLocation" msgid="2237023389178865130">"允許應用程式讀取你的媒體收藏的位置資訊。"</string>
- <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"找不到生物特徵辨識硬體"</string>
+ <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"無法使用生物特徵辨識硬體"</string>
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"僅偵測到部分指紋,請再試一次。"</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"無法處理指紋,請再試一次。"</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"指紋感應器有髒汙。請清潔感應器,然後再試一次。"</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92cca72e055a..389278f87fa1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2099,7 +2099,7 @@
<java-symbol type="string" name="vpn_lockdown_error" />
<java-symbol type="string" name="vpn_lockdown_config" />
<java-symbol type="string" name="wallpaper_binding_label" />
- <java-symbol type="style" name="Theme.Dialog.AppError" />
+ <java-symbol type="style" name="Theme.DeviceDefault.Dialog.AppError" />
<java-symbol type="style" name="Theme.Leanback.Dialog.Alert" />
<java-symbol type="style" name="Theme.Toast" />
<java-symbol type="xml" name="storage_list" />
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 3937af5c933f..a7530cea5d73 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -869,13 +869,6 @@ please see themes_device_defaults.xml.
<!-- System themes -->
<eat-comment />
- <!-- Theme for the dialog shown when an app crashes or ANRs. -->
- <style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
- <item name="windowContentTransitions">false</item>
- <item name="windowActivityTransitions">false</item>
- <item name="windowCloseOnTouchOutside">false</item>
- </style>
-
<!-- Special theme for the recent apps dialog, to allow customization
with overlays. -->
<style name="Theme.Dialog.RecentApplications" parent="Theme.DeviceDefault.Light.Dialog">
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 14e5082bdebb..92096abfcfab 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -719,6 +719,13 @@ easier.
<item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
+ <!-- Theme for the dialog shown when an app crashes or ANRs. -->
+ <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
+ <item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
+ <item name="windowCloseOnTouchOutside">false</item>
+ </style>
+
<style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
<!-- Color palette -->
<item name="colorPrimary">@color/primary_device_default_dark</item>
diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
index 5ef30a828cf7..dcc51e121b32 100644
--- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
+++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
@@ -48,8 +48,8 @@ public class BrightnessConfigurationTest {
@Test
public void testSetCurveIsUnmodified() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+ BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
+ LUX_LEVELS, NITS_LEVELS);
BrightnessConfiguration config = builder.build();
Pair<float[], float[]> curve = config.getCurve();
assertArrayEquals(LUX_LEVELS, curve.first, "lux");
@@ -58,45 +58,33 @@ public class BrightnessConfigurationTest {
@Test(expected = IllegalArgumentException.class)
public void testCurveMustHaveZeroLuxPoint() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
lux[0] = 1f;
- builder.setCurve(lux, NITS_LEVELS);
- }
-
- @Test(expected = IllegalStateException.class)
- public void testCurveMustBeSet() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.build();
+ new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
}
@Test(expected = NullPointerException.class)
public void testCurveMustNotHaveNullArrays() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(null, null);
+ new BrightnessConfiguration.Builder(null, null);
}
@Test(expected = IllegalArgumentException.class)
public void testCurveMustNotHaveEmptyArrays() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(new float[0], new float[0]);
+ new BrightnessConfiguration.Builder(new float[0], new float[0]);
}
@Test
public void testCurveMustNotHaveArraysOfDifferentLengths() {
assertThrows(IllegalArgumentException.class, () -> {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length + 1);
lux[lux.length - 1] = lux[lux.length - 2] + 1;
- boolean exceptionThrown = false;
- builder.setCurve(lux, NITS_LEVELS);
+ new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
});
assertThrows(IllegalArgumentException.class, () -> {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length + 1);
nits[nits.length - 1] = nits[nits.length - 2] + 1;
- builder.setCurve(LUX_LEVELS, nits);
+ new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
});
}
@@ -105,23 +93,21 @@ public class BrightnessConfigurationTest {
assertThrows(IllegalArgumentException.class, () -> {
float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
lux[lux.length - 1] = Float.NaN;
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(lux, NITS_LEVELS);
+ new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
});
assertThrows(IllegalArgumentException.class, () -> {
float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
nits[nits.length - 1] = Float.NaN;
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, nits);
+ new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
});
}
@Test
public void testParceledConfigIsEquivalent() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+ BrightnessConfiguration.Builder builder =
+ new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
BrightnessConfiguration config = builder.build();
Parcel p = Parcel.obtain();
p.writeParcelable(config, 0 /*flags*/);
@@ -133,12 +119,11 @@ public class BrightnessConfigurationTest {
@Test
public void testEquals() {
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+ BrightnessConfiguration.Builder builder =
+ new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
BrightnessConfiguration baseConfig = builder.build();
- builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, NITS_LEVELS);
+ builder = new BrightnessConfiguration.Builder(LUX_LEVELS, NITS_LEVELS);
BrightnessConfiguration identicalConfig = builder.build();
assertEquals(baseConfig, identicalConfig);
assertEquals("hashCodes must be equal for identical configs",
@@ -146,15 +131,13 @@ public class BrightnessConfigurationTest {
float[] lux = Arrays.copyOf(LUX_LEVELS, LUX_LEVELS.length);
lux[lux.length - 1] = lux[lux.length - 1] * 2;
- builder = new BrightnessConfiguration.Builder();
- builder.setCurve(lux, NITS_LEVELS);
+ builder = new BrightnessConfiguration.Builder(lux, NITS_LEVELS);
BrightnessConfiguration luxDifferConfig = builder.build();
assertNotEquals(baseConfig, luxDifferConfig);
float[] nits = Arrays.copyOf(NITS_LEVELS, NITS_LEVELS.length);
nits[nits.length - 1] = nits[nits.length - 1] * 2;
- builder = new BrightnessConfiguration.Builder();
- builder.setCurve(LUX_LEVELS, nits);
+ builder = new BrightnessConfiguration.Builder(LUX_LEVELS, nits);
BrightnessConfiguration nitsDifferConfig = builder.build();
assertNotEquals(baseConfig, nitsDifferConfig);
}
diff --git a/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java b/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
index 920988be2eb3..9e445541ad3a 100644
--- a/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
+++ b/core/tests/coretests/src/android/os/SetPersistentVrThreadTest.java
@@ -24,7 +24,6 @@ import android.os.Process;
import android.provider.Settings;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
/**
* Tests ActivityManager#setPersistentVrThread and ActivityManager#setVrThread's
@@ -76,9 +75,11 @@ public class SetPersistentVrThreadTest extends ActivityInstrumentationTestCase2<
}
private void setPersistentVrModeEnabled(boolean enable) throws Throwable {
- mVrManager.setPersistentVrModeEnabled(enable);
- // Allow the system time to send out callbacks for persistent VR mode.
- Thread.sleep(200);
+ if (mVrManager != null) {
+ mVrManager.setPersistentVrModeEnabled(enable);
+ // Allow the system time to send out callbacks for persistent VR mode.
+ Thread.sleep(200);
+ }
}
@SmallTest
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
index f731a4affb87..3064afaeaab1 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java
@@ -71,11 +71,15 @@ public class InputMethodUtilsTest {
private static final Locale LOCALE_FR = new Locale("fr");
private static final Locale LOCALE_FR_CA = new Locale("fr", "CA");
private static final Locale LOCALE_HI = new Locale("hi");
+ private static final Locale LOCALE_JA = new Locale("ja");
private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
private static final Locale LOCALE_ZH_CN = new Locale("zh", "CN");
private static final Locale LOCALE_ZH_TW = new Locale("zh", "TW");
private static final Locale LOCALE_IN = new Locale("in");
private static final Locale LOCALE_ID = new Locale("id");
+ private static final Locale LOCALE_TH = new Locale("ht");
+ private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
+ private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
private static final String SUBTYPE_MODE_HANDWRITING = "handwriting";
@@ -1083,6 +1087,122 @@ public class InputMethodUtilsTest {
}
@Test
+ public void testGetSuitableLocalesForSpellChecker() throws Exception {
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_US, locales.get(0));
+ assertEquals(LOCALE_EN_GB, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN_GB, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
+ assertEquals(3, locales.size());
+ assertEquals(LOCALE_EN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
+ assertEquals(4, locales.size());
+ assertEquals(LOCALE_EN_IN, locales.get(0));
+ assertEquals(LOCALE_EN_US, locales.get(1));
+ assertEquals(LOCALE_EN_GB, locales.get(2));
+ assertEquals(LOCALE_EN, locales.get(3));
+ }
+
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test 3-letter language code.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_FIL_PH, locales.get(0));
+ assertEquals(LOCALE_FIL, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+
+ // Test variant.
+ {
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
+ assertEquals(6, locales.size());
+ assertEquals(LOCALE_TH_TH_TH, locales.get(0));
+ assertEquals(LOCALE_TH_TH, locales.get(1));
+ assertEquals(LOCALE_TH, locales.get(2));
+ assertEquals(LOCALE_EN_US, locales.get(3));
+ assertEquals(LOCALE_EN_GB, locales.get(4));
+ assertEquals(Locale.ENGLISH, locales.get(5));
+ }
+
+ // Test Locale extension.
+ {
+ final Locale localeWithoutVariant = LOCALE_JA_JP;
+ final Locale localeWithVariant = new Locale.Builder()
+ .setLocale(LOCALE_JA_JP)
+ .setExtension('x', "android")
+ .build();
+ assertFalse(localeWithoutVariant.equals(localeWithVariant));
+
+ final ArrayList<Locale> locales =
+ InputMethodUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
+ assertEquals(5, locales.size());
+ assertEquals(LOCALE_JA_JP, locales.get(0));
+ assertEquals(LOCALE_JA, locales.get(1));
+ assertEquals(LOCALE_EN_US, locales.get(2));
+ assertEquals(LOCALE_EN_GB, locales.get(3));
+ assertEquals(Locale.ENGLISH, locales.get(4));
+ }
+ }
+
+ @Test
+ public void testConstructLocaleFromString() throws Exception {
+ assertEquals(new Locale("en"), InputMethodUtils.constructLocaleFromString("en"));
+ assertEquals(new Locale("en", "US"), InputMethodUtils.constructLocaleFromString("en_US"));
+ assertEquals(new Locale("en", "US", "POSIX"),
+ InputMethodUtils.constructLocaleFromString("en_US_POSIX"));
+
+ // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
+ // support three letter language codes, and used "tl" (Tagalog) as the language string for
+ // "fil" (Filipino).
+ assertEquals(new Locale("fil"), InputMethodUtils.constructLocaleFromString("tl"));
+ assertEquals(new Locale("fil", "PH"), InputMethodUtils.constructLocaleFromString("tl_PH"));
+ assertEquals(new Locale("fil", "PH", "POSIX"),
+ InputMethodUtils.constructLocaleFromString("tl_PH_POSIX"));
+
+ // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
+ assertEquals(new Locale("a"), InputMethodUtils.constructLocaleFromString("a"));
+ assertEquals(new Locale("a b c"), InputMethodUtils.constructLocaleFromString("a b c"));
+ assertEquals(new Locale("en-US"), InputMethodUtils.constructLocaleFromString("en-US"));
+ }
+
+ @Test
public void testIsSoftInputModeStateVisibleAllowed() {
// On pre-P devices, SOFT_INPUT_STATE_VISIBLE/SOFT_INPUT_STATE_ALWAYS_VISIBLE are always
// allowed, regardless of the focused view state.
diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
index 7d0e646181c0..549511a420eb 100644
--- a/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/inputmethod/LocaleUtilsTest.java
@@ -17,7 +17,6 @@
package com.android.internal.inputmethod;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import android.os.LocaleList;
import android.support.test.filters.SmallTest;
@@ -35,18 +34,6 @@ public class LocaleUtilsTest {
private static final LocaleUtils.LocaleExtractor<Locale> sIdentityMapper = source -> source;
- private static final Locale LOCALE_EN = new Locale("en");
- private static final Locale LOCALE_EN_US = new Locale("en", "US");
- private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
- private static final Locale LOCALE_EN_IN = new Locale("en", "IN");
- private static final Locale LOCALE_FIL = new Locale("fil");
- private static final Locale LOCALE_FIL_PH = new Locale("fil", "PH");
- private static final Locale LOCALE_JA = new Locale("ja");
- private static final Locale LOCALE_JA_JP = new Locale("ja", "JP");
- private static final Locale LOCALE_TH = new Locale("ht");
- private static final Locale LOCALE_TH_TH = new Locale("ht", "TH");
- private static final Locale LOCALE_TH_TH_TH = new Locale("ht", "TH", "TH");
-
@Test
public void testFilterByLanguageEmptyLanguageList() throws Exception {
final ArrayList<Locale> availableLocales = new ArrayList<>();
@@ -398,120 +385,4 @@ public class LocaleUtilsTest {
assertEquals(availableLocales.get(3), dest.get(0));
}
}
-
- @Test
- public void testGetSuitableLocalesForSpellChecker() throws Exception {
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_US);
- assertEquals(3, locales.size());
- assertEquals(LOCALE_EN_US, locales.get(0));
- assertEquals(LOCALE_EN_GB, locales.get(1));
- assertEquals(LOCALE_EN, locales.get(2));
- }
-
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_GB);
- assertEquals(3, locales.size());
- assertEquals(LOCALE_EN_GB, locales.get(0));
- assertEquals(LOCALE_EN_US, locales.get(1));
- assertEquals(LOCALE_EN, locales.get(2));
- }
-
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_EN);
- assertEquals(3, locales.size());
- assertEquals(LOCALE_EN, locales.get(0));
- assertEquals(LOCALE_EN_US, locales.get(1));
- assertEquals(LOCALE_EN_GB, locales.get(2));
- }
-
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_EN_IN);
- assertEquals(4, locales.size());
- assertEquals(LOCALE_EN_IN, locales.get(0));
- assertEquals(LOCALE_EN_US, locales.get(1));
- assertEquals(LOCALE_EN_GB, locales.get(2));
- assertEquals(LOCALE_EN, locales.get(3));
- }
-
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_JA_JP);
- assertEquals(5, locales.size());
- assertEquals(LOCALE_JA_JP, locales.get(0));
- assertEquals(LOCALE_JA, locales.get(1));
- assertEquals(LOCALE_EN_US, locales.get(2));
- assertEquals(LOCALE_EN_GB, locales.get(3));
- assertEquals(Locale.ENGLISH, locales.get(4));
- }
-
- // Test 3-letter language code.
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_FIL_PH);
- assertEquals(5, locales.size());
- assertEquals(LOCALE_FIL_PH, locales.get(0));
- assertEquals(LOCALE_FIL, locales.get(1));
- assertEquals(LOCALE_EN_US, locales.get(2));
- assertEquals(LOCALE_EN_GB, locales.get(3));
- assertEquals(Locale.ENGLISH, locales.get(4));
- }
-
- // Test variant.
- {
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(LOCALE_TH_TH_TH);
- assertEquals(6, locales.size());
- assertEquals(LOCALE_TH_TH_TH, locales.get(0));
- assertEquals(LOCALE_TH_TH, locales.get(1));
- assertEquals(LOCALE_TH, locales.get(2));
- assertEquals(LOCALE_EN_US, locales.get(3));
- assertEquals(LOCALE_EN_GB, locales.get(4));
- assertEquals(Locale.ENGLISH, locales.get(5));
- }
-
- // Test Locale extension.
- {
- final Locale localeWithoutVariant = LOCALE_JA_JP;
- final Locale localeWithVariant = new Locale.Builder()
- .setLocale(LOCALE_JA_JP)
- .setExtension('x', "android")
- .build();
- assertFalse(localeWithoutVariant.equals(localeWithVariant));
-
- final ArrayList<Locale> locales =
- LocaleUtils.getSuitableLocalesForSpellChecker(localeWithVariant);
- assertEquals(5, locales.size());
- assertEquals(LOCALE_JA_JP, locales.get(0));
- assertEquals(LOCALE_JA, locales.get(1));
- assertEquals(LOCALE_EN_US, locales.get(2));
- assertEquals(LOCALE_EN_GB, locales.get(3));
- assertEquals(Locale.ENGLISH, locales.get(4));
- }
- }
-
- @Test
- public void testConstructLocaleFromString() throws Exception {
- assertEquals(new Locale("en"), LocaleUtils.constructLocaleFromString("en"));
- assertEquals(new Locale("en", "US"), LocaleUtils.constructLocaleFromString("en_US"));
- assertEquals(new Locale("en", "US", "POSIX"),
- LocaleUtils.constructLocaleFromString("en_US_POSIX"));
-
- // Special rewrite rule for "tl" for versions of Android earlier than Lollipop that did not
- // support three letter language codes, and used "tl" (Tagalog) as the language string for
- // "fil" (Filipino).
- assertEquals(new Locale("fil"), LocaleUtils.constructLocaleFromString("tl"));
- assertEquals(new Locale("fil", "PH"), LocaleUtils.constructLocaleFromString("tl_PH"));
- assertEquals(new Locale("fil", "PH", "POSIX"),
- LocaleUtils.constructLocaleFromString("tl_PH_POSIX"));
-
- // So far rejecting an invalid/unexpected locale string is out of the scope of this method.
- assertEquals(new Locale("a"), LocaleUtils.constructLocaleFromString("a"));
- assertEquals(new Locale("a b c"), LocaleUtils.constructLocaleFromString("a b c"));
- assertEquals(new Locale("en-US"), LocaleUtils.constructLocaleFromString("en-US"));
- }
}
diff --git a/core/tests/webkit/Android.mk b/core/tests/webkit/Android.mk
deleted file mode 100644
index 45f6957c10e7..000000000000
--- a/core/tests/webkit/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-
-# Include all test java files.
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, unit_tests_src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- android-support-test
-
-LOCAL_PACKAGE_NAME := WebViewLoadingTests
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-LOCAL_REQUIRED_MODULES := \
- WebViewLoadingOnDiskTestApk \
- WebViewLoadingFromApkTestApk
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/core/tests/webkit/AndroidManifest.xml b/core/tests/webkit/AndroidManifest.xml
deleted file mode 100644
index 42accdf66891..000000000000
--- a/core/tests/webkit/AndroidManifest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.webkit.tests"
- android:sharedUserId="android.uid.system">
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.webkit.tests"
- android:label="Frameworks WebView Loader Tests" />
-
-</manifest>
diff --git a/core/tests/webkit/AndroidTest.xml b/core/tests/webkit/AndroidTest.xml
deleted file mode 100644
index 4c50b7df3368..000000000000
--- a/core/tests/webkit/AndroidTest.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs Frameworks WebView Loading Tests.">
- <option name="test-suite-tag" value="apct" />
- <option name="test-suite-tag" value="apct-instrumentation" />
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="WebViewLoadingTests.apk" />
- <option name="test-file-name" value="WebViewLoadingOnDiskTestApk.apk" />
- <option name="test-file-name" value="WebViewLoadingFromApkTestApk.apk" />
- <option name="cleanup-apks" value="true" />
- <option name="alt-dir" value="out" />
- </target_preparer>
-
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="package" value="com.android.webkit.tests" />
- </test>
-</configuration>
diff --git a/core/tests/webkit/OWNERS b/core/tests/webkit/OWNERS
deleted file mode 100644
index 00e540a46ab2..000000000000
--- a/core/tests/webkit/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-changwan@google.com
-tobiasjs@google.com
-torne@google.com
diff --git a/core/tests/webkit/apk_with_native_libs/Android.mk b/core/tests/webkit/apk_with_native_libs/Android.mk
deleted file mode 100644
index e18a7e0df175..000000000000
--- a/core/tests/webkit/apk_with_native_libs/Android.mk
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-MY_PATH := $(LOCAL_PATH)
-
-# Set shared variables
-MY_MODULE_TAGS := optional
-MY_JNI_SHARED_LIBRARIES := libwebviewtest_jni
-MY_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-MY_SRC_FILES := $(call all-java-files-under, src)
-MY_CFLAGS := -Wall -Werror
-MY_SDK_VERSION := system_current
-MY_PROGUARD_ENABLED := disabled
-MY_MULTILIB := both
-
-# Recurse down the file tree.
-include $(call all-subdir-makefiles)
-
-
-
-# Builds an apk containing native libraries that will be unzipped on the device.
-include $(CLEAR_VARS)
-
-LOCAL_PATH := $(MY_PATH)
-LOCAL_PACKAGE_NAME := WebViewLoadingOnDiskTestApk
-LOCAL_MANIFEST_FILE := ondisk/AndroidManifest.xml
-
-LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS)
-LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES)
-LOCAL_MODULE_PATH := $(MY_MODULE_PATH)
-LOCAL_SRC_FILES := $(MY_SRC_FILES)
-LOCAL_CFLAGS := $(MY_CFLAGS)
-LOCAL_SDK_VERSION := $(MY_SDK_VERSION)
-LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED)
-LOCAL_MULTILIB := $(MY_MULTILIB)
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
-
-
-# Builds an apk containing uncompressed native libraries that have to be
-# accessed through the APK itself on the device.
-include $(CLEAR_VARS)
-
-LOCAL_PATH := $(MY_PATH)
-LOCAL_PACKAGE_NAME := WebViewLoadingFromApkTestApk
-LOCAL_MANIFEST_FILE := inapk/AndroidManifest.xml
-
-LOCAL_MODULE_TAGS := $(MY_MODULE_TAGS)
-LOCAL_JNI_SHARED_LIBRARIES := $(MY_JNI_SHARED_LIBRARIES)
-LOCAL_MODULE_PATH := $(MY_MODULE_PATH)
-LOCAL_SRC_FILES := $(MY_SRC_FILES)
-LOCAL_CFLAGS := $(MY_CFLAGS)
-LOCAL_SDK_VERSION := $(MY_SDK_VERSION)
-LOCAL_PROGUARD_ENABLED := $(MY_PROGUARD_ENABLED)
-LOCAL_MULTILIB := $(MY_MULTILIB)
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml b/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml
deleted file mode 100644
index 868b2388d135..000000000000
--- a/core/tests/webkit/apk_with_native_libs/inapk/AndroidManifest.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.webviewloading_test_from_apk"
- android:versionCode="1"
- android:versionName="0.0.0.1">
-
- <application android:label="WebView Loading Test APK"
- android:multiArch="true"
- android:extractNativeLibs="false">
- <meta-data android:name="com.android.webview.WebViewLibrary"
- android:value="libwebviewtest_jni.so" />
- </application>
-</manifest>
diff --git a/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml b/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml
deleted file mode 100644
index ffffeb8e1630..000000000000
--- a/core/tests/webkit/apk_with_native_libs/ondisk/AndroidManifest.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.webviewloading_test_on_disk"
- android:versionCode="1"
- android:versionName="0.0.0.1">
-
- <application android:label="WebView Loading Test APK"
- android:multiArch="true">
- <meta-data android:name="com.android.webview.WebViewLibrary"
- android:value="libwebviewtest_jni.so" />
- </application>
-</manifest>
diff --git a/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java b/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java
deleted file mode 100644
index 0efa4b4ac694..000000000000
--- a/core/tests/webkit/apk_with_native_libs/src/com/google/android/xts/webview_list/WebViewLoadingTestClass.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.
- */
-
-
-package com.android.webview.chromium;
-
-/**
- * An empty class for testing purposes.
- */
-public class WebViewLoadingTestClass {
-}
diff --git a/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java b/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java
deleted file mode 100644
index e2f2d37a4d68..000000000000
--- a/core/tests/webkit/unit_tests_src/com/android/webkit/WebViewLibraryLoaderTest.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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.
- */
-
-package android.webkit;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Bundle;
-import android.util.Log;
-
-import android.support.test.filters.MediumTest;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.support.test.InstrumentationRegistry;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Unit tests for {@link WebViewLibraryLoader}.
- * Use the following command to run these tests:
- * make WebViewLoadingTests \
- * && adb install -r -d \
- * ${ANDROID_PRODUCT_OUT}/data/app/WebViewLoadingTests/WebViewLoadingTests.apk \
- * && adb shell am instrument -e class 'android.webkit.WebViewLibraryLoaderTest' -w \
- * 'com.android.webkit.tests/android.support.test.runner.AndroidJUnitRunner'
- */
-@RunWith(AndroidJUnit4.class)
-public final class WebViewLibraryLoaderTest {
- private static final String WEBVIEW_LIBS_ON_DISK_TEST_APK =
- "com.android.webviewloading_test_on_disk";
- private static final String WEBVIEW_LIBS_IN_APK_TEST_APK =
- "com.android.webviewloading_test_from_apk";
- private static final String WEBVIEW_LOADING_TEST_NATIVE_LIB = "libwebviewtest_jni.so";
-
- private PackageInfo webviewOnDiskPackageInfo;
- private PackageInfo webviewFromApkPackageInfo;
-
- @Before public void setUp() throws PackageManager.NameNotFoundException {
- PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
- webviewOnDiskPackageInfo =
- pm.getPackageInfo(WEBVIEW_LIBS_ON_DISK_TEST_APK, PackageManager.GET_META_DATA);
- webviewFromApkPackageInfo =
- pm.getPackageInfo(WEBVIEW_LIBS_IN_APK_TEST_APK, PackageManager.GET_META_DATA);
- }
-
- private static boolean is64BitDevice() {
- return Build.SUPPORTED_64_BIT_ABIS.length > 0;
- }
-
- // We test the getWebViewNativeLibraryDirectory method here because it handled several different
- // cases/combinations and it seems unnecessary to create one test-apk for each such combination
- // and arch.
-
- /**
- * Ensure we fetch the correct native library directories in the multi-arch case where
- * the primary ABI is 64-bit.
- */
- @SmallTest
- @Test public void testGetWebViewLibDirMultiArchPrimary64bit() {
- final String nativeLib = "nativeLib";
- final String secondaryNativeLib = "secondaryNativeLib";
- PackageInfo packageInfo = new PackageInfo();
- ApplicationInfo ai = new ApplicationInfoBuilder().
- // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP
- setPrimaryCpuAbi("arm64-v8a").
- setNativeLibraryDir(nativeLib).
- setSecondaryCpuAbi("armeabi").
- setSecondaryNativeLibraryDir(secondaryNativeLib).
- create();
- packageInfo.applicationInfo = ai;
- String actual32Lib =
- WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, false /* is64bit */);
- String actual64Lib =
- WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, true /* is64bit */);
- assertEquals(nativeLib, actual64Lib);
- assertEquals(secondaryNativeLib, actual32Lib);
- }
-
- /**
- * Ensure we fetch the correct native library directory in the 64-bit single-arch case.
- */
- @SmallTest
- @Test public void testGetWebViewLibDirSingleArch64bit() {
- final String nativeLib = "nativeLib";
- PackageInfo packageInfo = new PackageInfo();
- ApplicationInfo ai = new ApplicationInfoBuilder().
- // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP
- setPrimaryCpuAbi("arm64-v8a").
- setNativeLibraryDir(nativeLib).
- create();
- packageInfo.applicationInfo = ai;
- String actual64Lib =
- WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, true /* is64bit */);
- assertEquals(nativeLib, actual64Lib);
- }
-
- /**
- * Ensure we fetch the correct native library directory in the 32-bit single-arch case.
- */
- @SmallTest
- @Test public void testGetWebViewLibDirSingleArch32bit() {
- final String nativeLib = "nativeLib";
- PackageInfo packageInfo = new PackageInfo();
- ApplicationInfo ai = new ApplicationInfoBuilder().
- // See VMRuntime.ABI_TO_INSTRUCTION_SET_MAP
- setPrimaryCpuAbi("armeabi-v7a").
- setNativeLibraryDir(nativeLib).
- create();
- packageInfo.applicationInfo = ai;
- String actual32Lib =
- WebViewLibraryLoader.getWebViewNativeLibraryDirectory(ai, false /* is64bit */);
- assertEquals(nativeLib, actual32Lib);
- }
-
- /**
- * Ensure we fetch the correct 32-bit library path from an APK with 32-bit and 64-bit
- * libraries unzipped onto disk.
- */
- @MediumTest
- @Test public void testGetWebViewLibraryPathOnDisk32Bit()
- throws WebViewFactory.MissingWebViewPackageException {
- WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewOnDiskPackageInfo, false /* is64bit */);
- String expectedLibaryDirectory = is64BitDevice() ?
- webviewOnDiskPackageInfo.applicationInfo.secondaryNativeLibraryDir :
- webviewOnDiskPackageInfo.applicationInfo.nativeLibraryDir;
- String lib32Path = expectedLibaryDirectory + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB;
- assertEquals("Fetched incorrect 32-bit path from WebView library.",
- lib32Path, actualNativeLib.path);
- }
-
- /**
- * Ensure we fetch the correct 64-bit library path from an APK with 32-bit and 64-bit
- * libraries unzipped onto disk.
- */
- @MediumTest
- @Test public void testGetWebViewLibraryPathOnDisk64Bit()
- throws WebViewFactory.MissingWebViewPackageException {
- // A 32-bit device will not unpack 64-bit libraries.
- if (!is64BitDevice()) return;
-
- WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewOnDiskPackageInfo, true /* is64bit */);
- String lib64Path = webviewOnDiskPackageInfo.applicationInfo.nativeLibraryDir
- + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB;
- assertEquals("Fetched incorrect 64-bit path from WebView library.",
- lib64Path, actualNativeLib.path);
- }
-
- /**
- * Check the size of the 32-bit library fetched from an APK with both 32-bit and 64-bit
- * libraries unzipped onto disk.
- */
- @MediumTest
- @Test public void testGetWebView32BitLibrarySizeOnDiskIsNonZero()
- throws WebViewFactory.MissingWebViewPackageException {
- WebViewLibraryLoader.WebViewNativeLibrary actual32BitNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewOnDiskPackageInfo, false /* is64bit */);
- assertTrue(actual32BitNativeLib.size > 0);
- }
-
- /**
- * Check the size of the 64-bit library fetched from an APK with both 32-bit and 64-bit
- * libraries unzipped onto disk.
- */
- @MediumTest
- @Test public void testGetWebView64BitLibrarySizeOnDiskIsNonZero()
- throws WebViewFactory.MissingWebViewPackageException {
- // A 32-bit device will not unpack 64-bit libraries.
- if (!is64BitDevice()) return;
- WebViewLibraryLoader.WebViewNativeLibrary actual64BitNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewOnDiskPackageInfo, true /* is64bit */);
- assertTrue(actual64BitNativeLib.size > 0);
- }
-
- /**
- * Ensure we fetch the correct 32-bit library path from an APK with both 32-bit and 64-bit
- * libraries stored uncompressed in the APK.
- */
- @MediumTest
- @Test public void testGetWebView32BitLibraryPathFromApk()
- throws WebViewFactory.MissingWebViewPackageException, IOException {
- WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewFromApkPackageInfo, false /* is64bit */);
- // The device might have ignored the app's request to not extract native libs, so first
- // check whether the library paths match those of extracted libraries.
- String expectedLibaryDirectory = is64BitDevice() ?
- webviewFromApkPackageInfo.applicationInfo.secondaryNativeLibraryDir :
- webviewFromApkPackageInfo.applicationInfo.nativeLibraryDir;
- String lib32Path = expectedLibaryDirectory + "/" + WEBVIEW_LOADING_TEST_NATIVE_LIB;
- if (lib32Path.equals(actualNativeLib.path)) {
- // If the libraries were extracted to disk, ensure that they're actually there.
- assertTrue("The given WebView library doesn't exist.",
- new File(actualNativeLib.path).exists());
- } else { // The libraries were not extracted to disk.
- assertIsValidZipEntryPath(actualNativeLib.path,
- webviewFromApkPackageInfo.applicationInfo.sourceDir);
- }
- }
-
- /**
- * Ensure we fetch the correct 32-bit library path from an APK with both 32-bit and 64-bit
- * libraries stored uncompressed in the APK.
- */
- @MediumTest
- @Test public void testGetWebView64BitLibraryPathFromApk()
- throws WebViewFactory.MissingWebViewPackageException, IOException {
- // A 32-bit device will not unpack 64-bit libraries.
- if (!is64BitDevice()) return;
-
- WebViewLibraryLoader.WebViewNativeLibrary actualNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewFromApkPackageInfo, true /* is64bit */);
- assertIsValidZipEntryPath(actualNativeLib.path,
- webviewFromApkPackageInfo.applicationInfo.sourceDir);
- }
-
- private static void assertIsValidZipEntryPath(String path, String zipFilePath)
- throws IOException {
- assertTrue("The path to a zip entry must start with the path to the zip file itself."
- + "Expected zip path: " + zipFilePath + ", actual zip entry: " + path,
- path.startsWith(zipFilePath + "!/"));
- String[] pathSplit = path.split("!/");
- assertEquals("A zip file path should have two parts, the zip path, and the zip entry path.",
- 2, pathSplit.length);
- ZipFile zipFile = new ZipFile(pathSplit[0]);
- assertNotNull("Path doesn't point to a valid zip entry: " + path,
- zipFile.getEntry(pathSplit[1]));
- }
-
-
- /**
- * Check the size of the 32-bit library fetched from an APK with both 32-bit and 64-bit
- * libraries stored uncompressed in the APK.
- */
- @MediumTest
- @Test public void testGetWebView32BitLibrarySizeFromApkIsNonZero()
- throws WebViewFactory.MissingWebViewPackageException {
- WebViewLibraryLoader.WebViewNativeLibrary actual32BitNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewFromApkPackageInfo, false /* is64bit */);
- assertTrue(actual32BitNativeLib.size > 0);
- }
-
- /**
- * Check the size of the 64-bit library fetched from an APK with both 32-bit and 64-bit
- * libraries stored uncompressed in the APK.
- */
- @MediumTest
- @Test public void testGetWebView64BitLibrarySizeFromApkIsNonZero()
- throws WebViewFactory.MissingWebViewPackageException {
- // A 32-bit device will not unpack 64-bit libraries.
- if (!is64BitDevice()) return;
-
- WebViewLibraryLoader.WebViewNativeLibrary actual64BitNativeLib =
- WebViewLibraryLoader.getWebViewNativeLibrary(
- webviewFromApkPackageInfo, true /* is64bit */);
- assertTrue(actual64BitNativeLib.size > 0);
- }
-
- private static class ApplicationInfoBuilder {
- ApplicationInfo ai;
-
- public ApplicationInfoBuilder setPrimaryCpuAbi(String primaryCpuAbi) {
- ai.primaryCpuAbi = primaryCpuAbi;
- return this;
- }
-
- public ApplicationInfoBuilder setSecondaryCpuAbi(String secondaryCpuAbi) {
- ai.secondaryCpuAbi = secondaryCpuAbi;
- return this;
- }
-
- public ApplicationInfoBuilder setNativeLibraryDir(String nativeLibraryDir) {
- ai.nativeLibraryDir = nativeLibraryDir;
- return this;
- }
-
- public ApplicationInfoBuilder setSecondaryNativeLibraryDir(
- String secondaryNativeLibraryDir) {
- ai.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
- return this;
- }
-
- public ApplicationInfoBuilder setMetaData(Bundle metaData) {
- ai.metaData = metaData;
- return this;
- }
-
- public ApplicationInfoBuilder() {
- ai = new android.content.pm.ApplicationInfo();
- }
-
- public ApplicationInfo create() {
- return ai;
- }
- }
-}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 339a7eef637e..7681cc340069 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -91,6 +91,7 @@ cc_library_shared {
"android_media_Media2HTTPConnection.cpp",
"android_media_Media2HTTPService.cpp",
"android_media_Media2DataSource.cpp",
+ "android_media_MediaMetricsJNI.cpp",
"android_media_MediaPlayer2.cpp",
"android_media_SyncParams.cpp",
],
@@ -98,7 +99,6 @@ cc_library_shared {
shared_libs: [
"android.hardware.cas@1.0", // for CasManager. VNDK???
"android.hardware.cas.native@1.0", // CasManager. VNDK???
- "libandroid_runtime", // ???
"libaudioclient", // for use of AudioTrack, AudioSystem. to be removed
"libbinder",
"libgui", // for VideoFrameScheduler
@@ -120,13 +120,9 @@ cc_library_shared {
header_libs: ["libhardware_headers"],
static_libs: [
- "libbacktrace",
"libbase",
- "libc_malloc_debug_backtrace",
"libcrypto",
"libcutils",
- "libdexfile",
- "liblzma",
"libmedia_helper",
"libmedia_player2_util",
"libmediadrm",
@@ -135,7 +131,7 @@ cc_library_shared {
"libmediaplayer2",
"libmediaplayer2-protos",
"libmediautils",
- "libnetd_client",
+ "libnetd_client", // for setNetworkForUser
"libprotobuf-cpp-lite",
"libstagefright_esds",
"libstagefright_foundation",
@@ -146,9 +142,6 @@ cc_library_shared {
"libstagefright_player2",
"libstagefright_rtsp",
"libstagefright_timedtext2",
- "libunwindstack",
- "libutilscallstack",
- "libziparchive",
],
group_static_libs: true,
diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp
new file mode 100644
index 000000000000..3ded8c260512
--- /dev/null
+++ b/media/jni/android_media_MediaMetricsJNI.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 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 <jni.h>
+#include <nativehelper/JNIHelp.h>
+
+#include "android_media_MediaMetricsJNI.h"
+#include <media/MediaAnalyticsItem.h>
+
+
+// Copeid from core/jni/ (libandroid_runtime.so)
+namespace android {
+
+// place the attributes into a java PersistableBundle object
+jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle) {
+
+ jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
+ if (clazzBundle==NULL) {
+ ALOGD("can't find android/os/PersistableBundle");
+ return NULL;
+ }
+ // sometimes the caller provides one for us to fill
+ if (mybundle == NULL) {
+ // create the bundle
+ jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
+ mybundle = env->NewObject(clazzBundle, constructID);
+ if (mybundle == NULL) {
+ return NULL;
+ }
+ }
+
+ // grab methods that we can invoke
+ jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
+ jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
+ jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
+ jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");
+
+ // env, class, method, {parms}
+ //env->CallVoidMethod(env, mybundle, setIntID, jstr, jint);
+
+ // iterate through my attributes
+ // -- get name, get type, get value
+ // -- insert appropriately into the bundle
+ for (size_t i = 0 ; i < item->mPropCount; i++ ) {
+ MediaAnalyticsItem::Prop *prop = &item->mProps[i];
+ // build the key parameter from prop->mName
+ jstring keyName = env->NewStringUTF(prop->mName);
+ // invoke the appropriate method to insert
+ switch (prop->mType) {
+ case MediaAnalyticsItem::kTypeInt32:
+ env->CallVoidMethod(mybundle, setIntID,
+ keyName, (jint) prop->u.int32Value);
+ break;
+ case MediaAnalyticsItem::kTypeInt64:
+ env->CallVoidMethod(mybundle, setLongID,
+ keyName, (jlong) prop->u.int64Value);
+ break;
+ case MediaAnalyticsItem::kTypeDouble:
+ env->CallVoidMethod(mybundle, setDoubleID,
+ keyName, (jdouble) prop->u.doubleValue);
+ break;
+ case MediaAnalyticsItem::kTypeCString:
+ env->CallVoidMethod(mybundle, setStringID, keyName,
+ env->NewStringUTF(prop->u.CStringValue));
+ break;
+ default:
+ ALOGE("to_String bad item type: %d for %s",
+ prop->mType, prop->mName);
+ break;
+ }
+ }
+
+ return mybundle;
+}
+
+}; // namespace android
+
diff --git a/core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp b/media/jni/android_media_MediaMetricsJNI.h
index 0ced4ee12ac5..fd621ea7261d 100644
--- a/core/tests/webkit/apk_with_native_libs/jni/WebViewTestJniOnLoad.cpp
+++ b/media/jni/android_media_MediaMetricsJNI.h
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright 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
+ * 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,
@@ -14,8 +14,21 @@
* limitations under the License.
*/
+#ifndef _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
+#define _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
+
#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <media/MediaAnalyticsItem.h>
+
+// Copeid from core/jni/ (libandroid_runtime.so)
+namespace android {
+
+class MediaMetricsJNI {
+public:
+ static jobject writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle);
+};
+
+}; // namespace android
-jint JNI_OnLoad(JavaVM * /*vm*/, void * /*reserved*/) {
- return JNI_VERSION_1_4;
-}
+#endif // _ANDROID_MEDIA_MEDIAMETRICSJNI_H_
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 801dade63268..d4c84b5b6c77 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -909,7 +909,7 @@ android_media_MediaPlayer2_getAudioStreamType(JNIEnv *env, jobject thiz)
}
static jboolean
-android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject java_request)
+android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject)
{
ALOGV("setParameter: key %d", key);
sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
@@ -918,9 +918,11 @@ android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, job
return false;
}
- // TODO: parcelForJavaObject() shouldn't be used since it's dependent on
- // framework's Parcel implementation. This setParameter() is used
- // only with AudioAttribute. Can this be used as jobject with JAudioTrack?
+ return false;
+ // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency.
+ // Once JAudioTrack migration is done, the AudioAttribute jobject
+ // should be directly passed to AudioTrack without native parcel conversion.
+ /*
Parcel *request = parcelForJavaObject(env, java_request);
status_t err = mp->setParameter(key, *request);
if (err == OK) {
@@ -928,6 +930,7 @@ android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, job
} else {
return false;
}
+ */
}
static jobject
@@ -940,6 +943,11 @@ android_media_MediaPlayer2_getParameter(JNIEnv *env, jobject thiz, jint key)
return NULL;
}
+ return NULL;
+ // TODO: set/getParameter is temporarily disabled to remove android_runtime.so dependency.
+ // Once JAudioTrack migration is done, the AudioAttribute jobject
+ // should be directly passed to AudioTrack without native parcel conversion.
+ /*
jobject jParcel = createJavaParcelObject(env);
if (jParcel != NULL) {
Parcel* nativeParcel = parcelForJavaObject(env, jParcel);
@@ -950,6 +958,7 @@ android_media_MediaPlayer2_getParameter(JNIEnv *env, jobject thiz, jint key)
}
}
return jParcel;
+ */
}
static void
@@ -1005,7 +1014,11 @@ android_media_MediaPlayer2_invoke(JNIEnv *env, jobject thiz, jbyteArray requestD
PlayerMessage response;
request.ParseFromArray(pData, pDataLen);
- media_player->invoke(request, &response);
+ process_media_player_call( env, thiz, media_player->invoke(request, &response),
+ "java.lang.RuntimeException", NULL );
+ if (env->ExceptionCheck()) {
+ return NULL;
+ }
int size = response.ByteSize();
jbyte* temp = new jbyte[size];
@@ -1019,55 +1032,6 @@ android_media_MediaPlayer2_invoke(JNIEnv *env, jobject thiz, jbyteArray requestD
return out;
}
-// Sends the new filter to the client.
-static jint
-android_media_MediaPlayer2_setMetadataFilter(JNIEnv *env, jobject thiz, jobject request)
-{
- sp<MediaPlayer2> media_player = getMediaPlayer(env, thiz);
- if (media_player == NULL ) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
- return UNKNOWN_ERROR;
- }
-
- Parcel *filter = parcelForJavaObject(env, request);
-
- if (filter == NULL ) {
- jniThrowException(env, "java/lang/RuntimeException", "Filter is null");
- return UNKNOWN_ERROR;
- }
-
- return (jint) media_player->setMetadataFilter(*filter);
-}
-
-static jboolean
-android_media_MediaPlayer2_getMetadata(JNIEnv *env, jobject thiz, jboolean update_only,
- jboolean apply_filter, jobject reply)
-{
- sp<MediaPlayer2> media_player = getMediaPlayer(env, thiz);
- if (media_player == NULL ) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
- return JNI_FALSE;
- }
-
- Parcel *metadata = parcelForJavaObject(env, reply);
-
- if (metadata == NULL ) {
- jniThrowException(env, "java/lang/RuntimeException", "Reply parcel is null");
- return JNI_FALSE;
- }
-
- metadata->freeData();
- // On return metadata is positioned at the beginning of the
- // metadata. Note however that the parcel actually starts with the
- // return code so you should not rewind the parcel using
- // setDataPosition(0).
- if (media_player->getMetadata(update_only, apply_filter, metadata) == OK) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
-}
-
// This function gets some field IDs, which in turn causes class initialization.
// It is called from a static block in MediaPlayer2, which won't run until the
// first time an instance of this class is used.
@@ -1532,8 +1496,6 @@ static const JNINativeMethod gMethods[] = {
{"isLooping", "()Z", (void *)android_media_MediaPlayer2_isLooping},
{"_setVolume", "(FF)V", (void *)android_media_MediaPlayer2_setVolume},
{"_invoke", "([B)[B", (void *)android_media_MediaPlayer2_invoke},
- {"native_setMetadataFilter", "(Landroid/os/Parcel;)I", (void *)android_media_MediaPlayer2_setMetadataFilter},
- {"native_getMetadata", "(ZZLandroid/os/Parcel;)Z", (void *)android_media_MediaPlayer2_getMetadata},
{"native_init", "()V", (void *)android_media_MediaPlayer2_native_init},
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer2_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer2_native_finalize},
diff --git a/native/webview/loader/loader.cpp b/native/webview/loader/loader.cpp
index adb371dde0fc..fee2a259cb54 100644
--- a/native/webview/loader/loader.cpp
+++ b/native/webview/loader/loader.cpp
@@ -64,7 +64,8 @@ jboolean DoReserveAddressSpace(jlong size) {
return JNI_TRUE;
}
-jboolean DoCreateRelroFile(const char* lib, const char* relro) {
+jboolean DoCreateRelroFile(JNIEnv* env, const char* lib, const char* relro,
+ jobject clazzLoader) {
// Try to unlink the old file, since if this is being called, the old one is
// obsolete.
if (unlink(relro) != 0 && errno != ENOENT) {
@@ -82,11 +83,19 @@ jboolean DoCreateRelroFile(const char* lib, const char* relro) {
ALOGE("Failed to create temporary file %s: %s", relro_tmp, strerror(errno));
return JNI_FALSE;
}
+ android_namespace_t* ns =
+ android::FindNamespaceByClassLoader(env, clazzLoader);
+ if (ns == NULL) {
+ ALOGE("Failed to find classloader namespace");
+ return JNI_FALSE;
+ }
android_dlextinfo extinfo;
- extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO;
+ extinfo.flags = ANDROID_DLEXT_RESERVED_ADDRESS | ANDROID_DLEXT_WRITE_RELRO |
+ ANDROID_DLEXT_USE_NAMESPACE;
extinfo.reserved_addr = gReservedAddress;
extinfo.reserved_size = gReservedSize;
extinfo.relro_fd = tmp_fd;
+ extinfo.library_namespace = ns;
void* handle = android_dlopen_ext(lib, RTLD_NOW, &extinfo);
int close_result = close(tmp_fd);
if (handle == NULL) {
@@ -143,13 +152,14 @@ jboolean ReserveAddressSpace(JNIEnv*, jclass, jlong size) {
return DoReserveAddressSpace(size);
}
-jboolean CreateRelroFile(JNIEnv* env, jclass, jstring lib, jstring relro) {
+jboolean CreateRelroFile(JNIEnv* env, jclass, jstring lib, jstring relro,
+ jobject clazzLoader) {
jboolean ret = JNI_FALSE;
const char* lib_utf8 = env->GetStringUTFChars(lib, NULL);
if (lib_utf8 != NULL) {
const char* relro_utf8 = env->GetStringUTFChars(relro, NULL);
if (relro_utf8 != NULL) {
- ret = DoCreateRelroFile(lib_utf8, relro_utf8);
+ ret = DoCreateRelroFile(env, lib_utf8, relro_utf8, clazzLoader);
env->ReleaseStringUTFChars(relro, relro_utf8);
}
env->ReleaseStringUTFChars(lib, lib_utf8);
@@ -179,7 +189,7 @@ const JNINativeMethod kJniMethods[] = {
{ "nativeReserveAddressSpace", "(J)Z",
reinterpret_cast<void*>(ReserveAddressSpace) },
{ "nativeCreateRelroFile",
- "(Ljava/lang/String;Ljava/lang/String;)Z",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)Z",
reinterpret_cast<void*>(CreateRelroFile) },
{ "nativeLoadWithRelroFile",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)I",
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index f908595c7da1..86f90327ce4f 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -51,6 +51,7 @@ android_app {
libs: [
"telephony-common",
"android.car",
+ "android.car.user",
],
manifest: "AndroidManifest.xml",
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index 0c4e02b59bec..e13e566ec901 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -33,7 +33,6 @@ import java.util.List;
final class A2dpSinkProfile implements LocalBluetoothProfile {
private static final String TAG = "A2dpSinkProfile";
- private static boolean V = true;
private BluetoothA2dpSink mService;
private boolean mIsProfileReady;
@@ -56,7 +55,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
implements BluetoothProfile.ServiceListener {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (V) Log.d(TAG,"Bluetooth service connected");
+ Log.d(TAG, "Bluetooth service connected");
mService = (BluetoothA2dpSink) proxy;
// We just bound to the service, so refresh the UI for any connected A2DP devices.
List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -75,7 +74,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
public void onServiceDisconnected(int profile) {
- if (V) Log.d(TAG,"Bluetooth service disconnected");
+ Log.d(TAG, "Bluetooth service disconnected");
mIsProfileReady=false;
}
}
@@ -106,7 +105,9 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
public List<BluetoothDevice> getConnectedDevices() {
- if (mService == null) return new ArrayList<BluetoothDevice>(0);
+ if (mService == null) {
+ return new ArrayList<BluetoothDevice>(0);
+ }
return mService.getDevicesMatchingConnectionStates(
new int[] {BluetoothProfile.STATE_CONNECTED,
BluetoothProfile.STATE_CONNECTING,
@@ -114,24 +115,18 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
public boolean connect(BluetoothDevice device) {
- if (mService == null) return false;
- List<BluetoothDevice> srcs = getConnectedDevices();
- if (srcs != null) {
- for (BluetoothDevice src : srcs) {
- if (src.equals(device)) {
- // Connect to same device, Ignore it
- Log.d(TAG,"Ignoring Connect");
- return true;
- }
- }
+ if (mService == null) {
+ return false;
}
return mService.connect(device);
}
public boolean disconnect(BluetoothDevice device) {
- if (mService == null) return false;
+ if (mService == null) {
+ return false;
+ }
// Downgrade priority as user is disconnecting the headset.
- if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
+ if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
}
return mService.disconnect(device);
@@ -145,17 +140,23 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
public boolean isPreferred(BluetoothDevice device) {
- if (mService == null) return false;
+ if (mService == null) {
+ return false;
+ }
return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
}
public int getPreferred(BluetoothDevice device) {
- if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+ if (mService == null) {
+ return BluetoothProfile.PRIORITY_OFF;
+ }
return mService.getPriority(device);
}
public void setPreferred(BluetoothDevice device, boolean preferred) {
- if (mService == null) return;
+ if (mService == null) {
+ return;
+ }
if (preferred) {
if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -166,7 +167,9 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
boolean isA2dpPlaying() {
- if (mService == null) return false;
+ if (mService == null) {
+ return false;
+ }
List<BluetoothDevice> srcs = mService.getConnectedDevices();
if (!srcs.isEmpty()) {
if (mService.isA2dpPlaying(srcs.get(0))) {
@@ -208,7 +211,7 @@ final class A2dpSinkProfile implements LocalBluetoothProfile {
}
protected void finalize() {
- if (V) Log.d(TAG, "finalize()");
+ Log.d(TAG, "finalize()");
if (mService != null) {
try {
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.A2DP_SINK,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 649900bc97bd..b9f7323b1a9e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -78,12 +78,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
private final static String MESSAGE_REJECTION_COUNT_PREFS_NAME = "bluetooth_message_reject";
- /**
- * When we connect to multiple profiles, we only want to display a single
- * error even if they all fail. This tracks that state.
- */
- private boolean mIsConnectingErrorPossible;
-
public long getHiSyncId() {
return mHiSyncId;
}
@@ -230,9 +224,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
return;
}
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
-
int preferredProfiles = 0;
for (LocalBluetoothProfile profile : mProfiles) {
if (connectAllProfiles ? profile.isConnectable() : profile.isAutoConnectable()) {
@@ -253,8 +244,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
if (!ensurePaired()) {
return;
}
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
for (LocalBluetoothProfile profile : mProfiles) {
if (profile.isAutoConnectable()) {
@@ -271,8 +260,6 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
*/
public void connectProfile(LocalBluetoothProfile profile) {
mConnectAttempted = SystemClock.elapsedRealtime();
- // Reset the only-show-one-error-dialog tracking variable
- mIsConnectingErrorPossible = true;
connectInt(profile);
// Refresh the UI based on profile.connect() call
refresh();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index f9f623395801..4b6a22c9b2c8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -36,7 +36,6 @@ import java.util.List;
*/
final class HfpClientProfile implements LocalBluetoothProfile {
private static final String TAG = "HfpClientProfile";
- private static boolean V = false;
private BluetoothHeadsetClient mService;
private boolean mIsProfileReady;
@@ -60,7 +59,7 @@ final class HfpClientProfile implements LocalBluetoothProfile {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- if (V) Log.d(TAG,"Bluetooth service connected");
+ Log.d(TAG, "Bluetooth service connected");
mService = (BluetoothHeadsetClient) proxy;
// We just bound to the service, so refresh the UI for any connected HFP devices.
List<BluetoothDevice> deviceList = mService.getConnectedDevices();
@@ -81,7 +80,7 @@ final class HfpClientProfile implements LocalBluetoothProfile {
@Override
public void onServiceDisconnected(int profile) {
- if (V) Log.d(TAG,"Bluetooth service disconnected");
+ Log.d(TAG, "Bluetooth service disconnected");
mIsProfileReady=false;
}
}
@@ -115,7 +114,9 @@ final class HfpClientProfile implements LocalBluetoothProfile {
}
public List<BluetoothDevice> getConnectedDevices() {
- if (mService == null) return new ArrayList<BluetoothDevice>(0);
+ if (mService == null) {
+ return new ArrayList<BluetoothDevice>(0);
+ }
return mService.getDevicesMatchingConnectionStates(
new int[] {BluetoothProfile.STATE_CONNECTED,
BluetoothProfile.STATE_CONNECTING,
@@ -124,23 +125,17 @@ final class HfpClientProfile implements LocalBluetoothProfile {
@Override
public boolean connect(BluetoothDevice device) {
- if (mService == null) return false;
- List<BluetoothDevice> srcs = getConnectedDevices();
- if (srcs != null) {
- for (BluetoothDevice src : srcs) {
- if (src.equals(device)) {
- // Connect to same device, Ignore it
- Log.d(TAG,"Ignoring Connect");
- return true;
- }
- }
+ if (mService == null) {
+ return false;
}
return mService.connect(device);
}
@Override
public boolean disconnect(BluetoothDevice device) {
- if (mService == null) return false;
+ if (mService == null) {
+ return false;
+ }
// Downgrade priority as user is disconnecting the headset.
if (mService.getPriority(device) > BluetoothProfile.PRIORITY_ON){
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -158,19 +153,25 @@ final class HfpClientProfile implements LocalBluetoothProfile {
@Override
public boolean isPreferred(BluetoothDevice device) {
- if (mService == null) return false;
+ if (mService == null) {
+ return false;
+ }
return mService.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
}
@Override
public int getPreferred(BluetoothDevice device) {
- if (mService == null) return BluetoothProfile.PRIORITY_OFF;
+ if (mService == null) {
+ return BluetoothProfile.PRIORITY_OFF;
+ }
return mService.getPriority(device);
}
@Override
public void setPreferred(BluetoothDevice device, boolean preferred) {
- if (mService == null) return;
+ if (mService == null) {
+ return;
+ }
if (preferred) {
if (mService.getPriority(device) < BluetoothProfile.PRIORITY_ON) {
mService.setPriority(device, BluetoothProfile.PRIORITY_ON);
@@ -216,7 +217,7 @@ final class HfpClientProfile implements LocalBluetoothProfile {
}
protected void finalize() {
- if (V) Log.d(TAG, "finalize()");
+ Log.d(TAG, "finalize()");
if (mService != null) {
try {
BluetoothAdapter.getDefaultAdapter().closeProfileProxy(
diff --git a/packages/SettingsLib/tests/robotests/config/robolectric.properties b/packages/SettingsLib/tests/robotests/config/robolectric.properties
index 34a2a1a28ada..6b5b8e59472b 100644
--- a/packages/SettingsLib/tests/robotests/config/robolectric.properties
+++ b/packages/SettingsLib/tests/robotests/config/robolectric.properties
@@ -1,2 +1,5 @@
manifest=frameworks/base/packages/SettingsLib/tests/robotests/AndroidManifest.xml
-sdk=NEWEST_SDK \ No newline at end of file
+sdk=NEWEST_SDK
+
+shadows=\
+ com.android.settingslib.testutils.shadow.ShadowXmlUtils \ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java
new file mode 100644
index 000000000000..274fff83ea8a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/A2dpSinkProfileTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothA2dpSink;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class A2dpSinkProfileTest {
+
+ @Mock
+ private CachedBluetoothDeviceManager mDeviceManager;
+ @Mock
+ private LocalBluetoothProfileManager mProfileManager;
+ @Mock
+ private BluetoothA2dpSink mService;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private BluetoothDevice mBluetoothDevice;
+ private BluetoothProfile.ServiceListener mServiceListener;
+ private A2dpSinkProfile mProfile;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ mProfile = new A2dpSinkProfile(RuntimeEnvironment.application,
+ mDeviceManager, mProfileManager);
+ mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+ mServiceListener.onServiceConnected(BluetoothProfile.A2DP_SINK, mService);
+ }
+
+ @Test
+ public void connect_shouldConnectBluetoothA2dpSink() {
+ mProfile.connect(mBluetoothDevice);
+ verify(mService).connect(mBluetoothDevice);
+ }
+
+ @Test
+ public void disconnect_shouldDisconnectBluetoothA2dpSink() {
+ mProfile.disconnect(mBluetoothDevice);
+ verify(mService).disconnect(mBluetoothDevice);
+ }
+
+ @Test
+ public void getConnectionStatus_shouldReturnConnectionState() {
+ when(mService.getConnectionState(mBluetoothDevice)).
+ thenReturn(BluetoothProfile.STATE_CONNECTED);
+ assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+ isEqualTo(BluetoothProfile.STATE_CONNECTED);
+ }
+} \ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java
new file mode 100644
index 000000000000..187be0bf647b
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HfpClientProfileTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.bluetooth;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadsetClient;
+import android.bluetooth.BluetoothProfile;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowBluetoothAdapter.class})
+public class HfpClientProfileTest {
+
+ @Mock
+ private CachedBluetoothDeviceManager mDeviceManager;
+ @Mock
+ private LocalBluetoothProfileManager mProfileManager;
+ @Mock
+ private BluetoothHeadsetClient mService;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private BluetoothDevice mBluetoothDevice;
+ private BluetoothProfile.ServiceListener mServiceListener;
+ private HfpClientProfile mProfile;
+ private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ mProfile = new HfpClientProfile(RuntimeEnvironment.application,
+ mDeviceManager, mProfileManager);
+ mServiceListener = mShadowBluetoothAdapter.getServiceListener();
+ mServiceListener.onServiceConnected(BluetoothProfile.HEADSET_CLIENT, mService);
+ }
+
+ @Test
+ public void connect_shouldConnectBluetoothHeadsetClient() {
+ mProfile.connect(mBluetoothDevice);
+ verify(mService).connect(mBluetoothDevice);
+ }
+
+ @Test
+ public void disconnect_shouldDisconnectBluetoothHeadsetClient() {
+ mProfile.disconnect(mBluetoothDevice);
+ verify(mService).disconnect(mBluetoothDevice);
+ }
+
+ @Test
+ public void getConnectionStatus_shouldReturnConnectionState() {
+ when(mService.getConnectionState(mBluetoothDevice)).
+ thenReturn(BluetoothProfile.STATE_CONNECTED);
+ assertThat(mProfile.getConnectionStatus(mBluetoothDevice)).
+ isEqualTo(BluetoothProfile.STATE_CONNECTED);
+ }
+}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java
new file mode 100644
index 000000000000..3455765ce24c
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowXmlUtils.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.testutils.shadow;
+
+import static org.robolectric.shadow.api.Shadow.directlyOn;
+
+import com.android.internal.util.XmlUtils;
+
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.util.ReflectionHelpers;
+
+@Implements(XmlUtils.class)
+public class ShadowXmlUtils {
+
+ @Implementation
+ public static final int convertValueToInt(CharSequence charSeq, int defaultValue) {
+ final Class<?> xmlUtilsClass = ReflectionHelpers.loadClass(
+ Robolectric.class.getClassLoader(), "com.android.internal.util.XmlUtils");
+ try {
+ return directlyOn(xmlUtilsClass, "convertValueToInt",
+ ReflectionHelpers.ClassParameter.from(CharSequence.class, charSeq),
+ ReflectionHelpers.ClassParameter.from(int.class, new Integer(defaultValue)));
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 4fc190d43056..ec35b3df73c9 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -16,6 +16,8 @@
package com.android.shell;
+import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static com.android.shell.BugreportPrefs.STATE_HIDE;
@@ -235,6 +237,7 @@ public class BugreportProgressService extends Service {
private static final Bundle sNotificationBundle = new Bundle();
private boolean mIsWatch;
+ private boolean mIsTv;
private int mLastProgressPercent;
@@ -255,6 +258,9 @@ public class BugreportProgressService extends Service {
final Configuration conf = mContext.getResources().getConfiguration();
mIsWatch = (conf.uiMode & Configuration.UI_MODE_TYPE_MASK) ==
Configuration.UI_MODE_TYPE_WATCH;
+ PackageManager packageManager = getPackageManager();
+ mIsTv = packageManager.hasSystemFeature(FEATURE_LEANBACK)
+ || packageManager.hasSystemFeature(FEATURE_TELEVISION);
NotificationManager nm = NotificationManager.from(mContext);
nm.createNotificationChannel(
new NotificationChannel(NOTIFICATION_CHANNEL_ID,
@@ -500,8 +506,8 @@ public class BugreportProgressService extends Service {
.setProgress(info.max, info.progress, false)
.setOngoing(true);
- // Wear bugreport doesn't need the bug info dialog, screenshot and cancel action.
- if (!mIsWatch) {
+ // Wear and ATV bugreport doesn't need the bug info dialog, screenshot and cancel action.
+ if (!(mIsWatch || mIsTv)) {
final Action cancelAction = new Action.Builder(null, mContext.getString(
com.android.internal.R.string.cancel), newCancelIntent(mContext, info)).build();
final Intent infoIntent = new Intent(mContext, BugreportProgressService.class);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 091350334835..9c33116a149b 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -66,6 +66,7 @@ android_library {
libs: [
"telephony-common",
"android.car",
+ "android.car.user",
],
aaptflags: [
@@ -119,6 +120,7 @@ android_library {
"android.test.runner",
"telephony-common",
"android.car",
+ "android.car.user",
"android.test.base",
],
aaptflags: [
@@ -144,6 +146,7 @@ android_app {
libs: [
"telephony-common",
"android.car",
+ "android.car.user",
],
dxflags: ["--multi-dex"],
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 45d218548d1a..2c5120dd06f3 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -25,10 +25,10 @@
<color name="notification_legacy_background_color">@*android:color/notification_material_background_color</color>
<!-- The color of the material notification background when dimmed -->
- <color name="notification_material_background_dimmed_color">#aa212121</color>
+ <color name="notification_material_background_dimmed_color">#aa000000</color>
<!-- The color of the dividing line between grouped notifications while . -->
- <color name="notification_divider_color">#000</color>
+ <color name="notification_divider_color">#212121</color>
<!-- The background color of the notification shade -->
<color name="notification_shade_background_color">#181818</color>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 67db68deb928..216ed68e4fbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -1141,9 +1141,13 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
private void updateNotificationColor() {
+ Configuration currentConfig = getResources().getConfiguration();
+ boolean nightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+ == Configuration.UI_MODE_NIGHT_YES;
+
mNotificationColor = ContrastColorUtil.resolveContrastColor(mContext,
getStatusBarNotification().getNotification().color,
- getBackgroundColorWithoutTint());
+ getBackgroundColorWithoutTint(), nightMode);
mNotificationColorAmbient = ContrastColorUtil.resolveAmbientColor(mContext,
getStatusBarNotification().getNotification().color);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 2cbb78a4a8f5..3744105b8b94 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -356,10 +356,11 @@ public class CarVolumeDialogImpl implements VolumeDialog {
if (supplementalIconId != 0) {
Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
supplementalIcon.mutate().setTint(color);
- listItem.setSupplementalIcon(supplementalIcon, true,
- supplementalIconOnClickListener);
+ listItem.setSupplementalIcon(supplementalIcon, true);
+ listItem.setSupplementalIconListener(supplementalIconOnClickListener);
} else {
listItem.setSupplementalEmptyIcon(true);
+ listItem.setSupplementalIconListener(null);
}
mVolumeLineItems.add(listItem);
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index 6057614f26ee..aac37a290edc 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -38,7 +38,8 @@ LOCAL_JAVA_LIBRARIES := \
android.test.runner \
telephony-common \
android.test.base \
- android.car
+ android.car \
+ android.car.user
LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
diff --git a/packages/VpnDialogs/res/values-es-rUS/strings.xml b/packages/VpnDialogs/res/values-es-rUS/strings.xml
index 3732ebc6a333..21cfc042e707 100644
--- a/packages/VpnDialogs/res/values-es-rUS/strings.xml
+++ b/packages/VpnDialogs/res/values-es-rUS/strings.xml
@@ -17,7 +17,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="prompt" msgid="3183836924226407828">"Solicitud de conexión"</string>
- <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quiere configurar una conexión VPN que permite controlar el tráfico de la red. Acéptala solo si confías en la fuente. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece en la parte superior de la pantalla cuando la VPN está activa."</string>
+ <string name="warning" msgid="809658604548412033">"<xliff:g id="APP">%s</xliff:g> quiere configurar una conexión VPN capaz de controlar el tráfico de la red. Acéptala solo si confías en la fuente. &lt;br /&gt; &lt;br /&gt; &lt;img src=vpn_icon /&gt; aparece en la parte superior de la pantalla cuando se activa la VPN."</string>
<string name="legacy_title" msgid="192936250066580964">"La VPN está conectada."</string>
<string name="session" msgid="6470628549473641030">"Sesión:"</string>
<string name="duration" msgid="3584782459928719435">"Duración:"</string>
diff --git a/proto/src/metrics_constants/OWNERS b/proto/src/metrics_constants/OWNERS
index 9c70a5e366b9..7009282b66e1 100644
--- a/proto/src/metrics_constants/OWNERS
+++ b/proto/src/metrics_constants/OWNERS
@@ -1,3 +1,4 @@
+cwren@android.com
yanglu@google.com
yaochen@google.com
yro@google.com
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java
new file mode 100644
index 000000000000..1ae598ec9920
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkHash.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.encryption.chunk;
+
+import com.android.internal.util.Preconditions;
+import java.util.Arrays;
+import java.util.Base64;
+
+/**
+ * Represents the SHA-256 hash of the plaintext of a chunk, which is frequently used as a key.
+ *
+ * <p>This class is {@link Comparable} and implements {@link #equals(Object)} and {@link
+ * #hashCode()}.
+ */
+public class ChunkHash implements Comparable<ChunkHash> {
+ /** The length of the hash in bytes. The hash is a SHA-256, so this is 256 bits. */
+ public static final int HASH_LENGTH_BYTES = 256 / 8;
+
+ private static final int UNSIGNED_MASK = 0xFF;
+
+ private final byte[] mHash;
+
+ /** Constructs a new instance which wraps the given SHA-256 hash bytes. */
+ public ChunkHash(byte[] hash) {
+ Preconditions.checkArgument(hash.length == HASH_LENGTH_BYTES, "Hash must have 256 bits");
+ mHash = hash;
+ }
+
+ public byte[] getHash() {
+ return mHash;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ChunkHash)) {
+ return false;
+ }
+
+ ChunkHash chunkHash = (ChunkHash) o;
+ return Arrays.equals(mHash, chunkHash.mHash);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(mHash);
+ }
+
+ @Override
+ public int compareTo(ChunkHash other) {
+ return lexicographicalCompareUnsignedBytes(getHash(), other.getHash());
+ }
+
+ @Override
+ public String toString() {
+ return Base64.getEncoder().encodeToString(mHash);
+ }
+
+ private static int lexicographicalCompareUnsignedBytes(byte[] left, byte[] right) {
+ int minLength = Math.min(left.length, right.length);
+ for (int i = 0; i < minLength; i++) {
+ int result = toInt(left[i]) - toInt(right[i]);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return left.length - right.length;
+ }
+
+ private static int toInt(byte value) {
+ return value & UNSIGNED_MASK;
+ }
+}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 499c03d05bf2..ad2f82c9b19f 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -81,6 +81,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseLongArray;
+import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -3637,6 +3638,8 @@ class AlarmManagerService extends SystemService {
if (DEBUG_BATCH) {
Slog.v(TAG, "Time changed notification from kernel; rebatching");
}
+ // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs.
+ StatsLog.write(StatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC);
removeImpl(mTimeTickSender);
removeImpl(mDateChangeSender);
rebatchAllAlarms();
diff --git a/services/core/java/com/android/server/HardwarePropertiesManagerService.java b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
index 4016d29fd2e6..e21a3d7917d1 100644
--- a/services/core/java/com/android/server/HardwarePropertiesManagerService.java
+++ b/services/core/java/com/android/server/HardwarePropertiesManagerService.java
@@ -26,7 +26,6 @@ import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING;
import static android.os.HardwarePropertiesManager.TEMPERATURE_THROTTLING_BELOW_VR_MIN;
import android.Manifest;
-import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
@@ -34,8 +33,8 @@ import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.CpuUsageInfo;
import android.os.IHardwarePropertiesManager;
-import android.os.Process;
import android.os.UserHandle;
+
import com.android.internal.util.DumpUtils;
import com.android.server.vr.VrManagerInternal;
@@ -166,11 +165,11 @@ public class HardwarePropertiesManagerService extends IHardwarePropertiesManager
final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
if (!dpm.isDeviceOwnerApp(callingPackage)
- && !vrService.isCurrentVrListener(callingPackage, userId)
&& mContext.checkCallingOrSelfPermission(Manifest.permission.DEVICE_POWER)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("The caller is not a device owner, bound VrListenerService"
- + ", or holding the DEVICE_POWER permission.");
+ != PackageManager.PERMISSION_GRANTED
+ && (vrService == null || !vrService.isCurrentVrListener(callingPackage, userId))) {
+ throw new SecurityException("The caller is neither a device owner"
+ + ", nor holding the DEVICE_POWER permission, nor the current VrListener.");
}
}
}
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index 01e81525d5b5..380f6a7e581e 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -612,7 +612,7 @@ public class IpSecService extends IIpSecService.Stub {
mSrvConfig
.getNetdInstance()
.ipSecDeleteSecurityAssociation(
- mResourceId,
+ uid,
mConfig.getSourceAddress(),
mConfig.getDestinationAddress(),
spi,
@@ -679,7 +679,7 @@ public class IpSecService extends IIpSecService.Stub {
mSrvConfig
.getNetdInstance()
.ipSecDeleteSecurityAssociation(
- mResourceId, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
+ uid, mSourceAddress, mDestinationAddress, mSpi, 0, 0);
}
} catch (ServiceSpecificException | RemoteException e) {
Log.e(TAG, "Failed to delete SPI reservation with ID: " + mResourceId, e);
@@ -821,13 +821,13 @@ public class IpSecService extends IIpSecService.Stub {
for (int selAddrFamily : ADDRESS_FAMILIES) {
netd.ipSecDeleteSecurityPolicy(
- 0,
+ uid,
selAddrFamily,
IpSecManager.DIRECTION_OUT,
mOkey,
0xffffffff);
netd.ipSecDeleteSecurityPolicy(
- 0,
+ uid,
selAddrFamily,
IpSecManager.DIRECTION_IN,
mIkey,
@@ -1083,7 +1083,8 @@ public class IpSecService extends IIpSecService.Stub {
}
checkNotNull(binder, "Null Binder passed to allocateSecurityParameterIndex");
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int callingUid = Binder.getCallingUid();
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
final int resourceId = mNextResourceId++;
int spi = IpSecManager.INVALID_SECURITY_PARAMETER_INDEX;
@@ -1096,7 +1097,7 @@ public class IpSecService extends IIpSecService.Stub {
spi =
mSrvConfig
.getNetdInstance()
- .ipSecAllocateSpi(resourceId, "", destinationAddress, requestedSpi);
+ .ipSecAllocateSpi(callingUid, "", destinationAddress, requestedSpi);
Log.d(TAG, "Allocated SPI " + spi);
userRecord.mSpiRecords.put(
resourceId,
@@ -1264,7 +1265,8 @@ public class IpSecService extends IIpSecService.Stub {
// TODO: Check that underlying network exists, and IP addresses not assigned to a different
// network (b/72316676).
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int callerUid = Binder.getCallingUid();
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(callerUid);
if (!userRecord.mTunnelQuotaTracker.isAvailable()) {
return new IpSecTunnelInterfaceResponse(IpSecManager.Status.RESOURCE_UNAVAILABLE);
}
@@ -1285,7 +1287,7 @@ public class IpSecService extends IIpSecService.Stub {
for (int selAddrFamily : ADDRESS_FAMILIES) {
// Always send down correct local/remote addresses for template.
netd.ipSecAddSecurityPolicy(
- 0, // Use 0 for reqId
+ callerUid,
selAddrFamily,
IpSecManager.DIRECTION_OUT,
localAddr,
@@ -1294,7 +1296,7 @@ public class IpSecService extends IIpSecService.Stub {
okey,
0xffffffff);
netd.ipSecAddSecurityPolicy(
- 0, // Use 0 for reqId
+ callerUid,
selAddrFamily,
IpSecManager.DIRECTION_IN,
remoteAddr,
@@ -1532,7 +1534,7 @@ public class IpSecService extends IIpSecService.Stub {
mSrvConfig
.getNetdInstance()
.ipSecAddSecurityAssociation(
- resourceId,
+ Binder.getCallingUid(),
c.getMode(),
c.getSourceAddress(),
c.getDestinationAddress(),
@@ -1623,13 +1625,14 @@ public class IpSecService extends IIpSecService.Stub {
@Override
public synchronized void applyTransportModeTransform(
ParcelFileDescriptor socket, int direction, int resourceId) throws RemoteException {
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int callingUid = Binder.getCallingUid();
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
checkDirection(direction);
// Get transform record; if no transform is found, will throw IllegalArgumentException
TransformRecord info = userRecord.mTransformRecords.getResourceOrThrow(resourceId);
// TODO: make this a function.
- if (info.pid != getCallingPid() || info.uid != getCallingUid()) {
+ if (info.pid != getCallingPid() || info.uid != callingUid) {
throw new SecurityException("Only the owner of an IpSec Transform may apply it!");
}
@@ -1643,7 +1646,7 @@ public class IpSecService extends IIpSecService.Stub {
.getNetdInstance()
.ipSecApplyTransportModeTransform(
socket.getFileDescriptor(),
- resourceId,
+ callingUid,
direction,
c.getSourceAddress(),
c.getDestinationAddress(),
@@ -1675,7 +1678,8 @@ public class IpSecService extends IIpSecService.Stub {
enforceTunnelPermissions(callingPackage);
checkDirection(direction);
- UserRecord userRecord = mUserResourceTracker.getUserRecord(Binder.getCallingUid());
+ int callingUid = Binder.getCallingUid();
+ UserRecord userRecord = mUserResourceTracker.getUserRecord(callingUid);
// Get transform record; if no transform is found, will throw IllegalArgumentException
TransformRecord transformInfo =
@@ -1717,7 +1721,7 @@ public class IpSecService extends IIpSecService.Stub {
mSrvConfig
.getNetdInstance()
.ipSecUpdateSecurityPolicy(
- 0, // Use 0 for reqId
+ callingUid,
selAddrFamily,
direction,
tunnelInterfaceInfo.getLocalAddress(),
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 708350d6f174..40f81b3c2850 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -20,7 +20,7 @@ import static android.view.textservice.TextServicesManager.DISABLE_PER_PROFILE_S
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
-import com.android.internal.inputmethod.LocaleUtils;
+import com.android.internal.inputmethod.InputMethodUtils;
import com.android.internal.textservice.ISpellCheckerService;
import com.android.internal.textservice.ISpellCheckerServiceCallback;
import com.android.internal.textservice.ISpellCheckerSession;
@@ -461,7 +461,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
// is pre-installed or not.
final Locale systemLocal = mContext.getResources().getConfiguration().locale;
final ArrayList<Locale> suitableLocales =
- LocaleUtils.getSuitableLocalesForSpellChecker(systemLocal);
+ InputMethodUtils.getSuitableLocalesForSpellChecker(systemLocal);
if (DBG) {
Slog.w(TAG, "findAvailSystemSpellCheckerLocked suitableLocales="
+ Arrays.toString(suitableLocales.toArray(new Locale[suitableLocales.size()])));
@@ -475,7 +475,7 @@ public class TextServicesManagerService extends ITextServicesManager.Stub {
final int subtypeCount = info.getSubtypeCount();
for (int subtypeIndex = 0; subtypeIndex < subtypeCount; ++subtypeIndex) {
final SpellCheckerSubtype subtype = info.getSubtypeAt(subtypeIndex);
- final Locale subtypeLocale = LocaleUtils.constructLocaleFromString(
+ final Locale subtypeLocale = InputMethodUtils.constructLocaleFromString(
subtype.getLocale());
if (locale.equals(subtypeLocale)) {
// TODO: We may have more spell checkers that fall into this category.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2ee598fee535..b64e8b87aeec 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2382,7 +2382,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
int logSampleRate = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, -1);
+ Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE, 0x200);
if (logSampleRate < 0 || logSampleRate > 0x10000) {
logSampleRate = -1;
}
@@ -11941,7 +11941,9 @@ public class ActivityManagerService extends IActivityManager.Stub
printed = true;
}
pw.print(" "); UserHandle.formatUid(pw, reg.uid);
- pw.print(" "); pw.print(reg.pkg); pw.print(":");
+ pw.print(" "); pw.print(reg.pkg);
+ final IUidObserver observer = mUidObservers.getRegisteredCallbackItem(i);
+ pw.print(" "); pw.print(observer.getClass().getTypeName()); pw.print(":");
if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
pw.print(" IDLE");
}
diff --git a/services/core/java/com/android/server/am/BaseErrorDialog.java b/services/core/java/com/android/server/am/BaseErrorDialog.java
index 347a357aae04..cd4d6a3e14c5 100644
--- a/services/core/java/com/android/server/am/BaseErrorDialog.java
+++ b/services/core/java/com/android/server/am/BaseErrorDialog.java
@@ -33,7 +33,7 @@ class BaseErrorDialog extends AlertDialog {
private boolean mConsuming = true;
public BaseErrorDialog(Context context) {
- super(context, com.android.internal.R.style.Theme_Dialog_AppError);
+ super(context, com.android.internal.R.style.Theme_DeviceDefault_Dialog_AppError);
context.assertRuntimeOverlayThemable();
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 1b688a6cd9c6..76c191d5e9ea 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -26,8 +26,8 @@ import android.util.Pair;
import android.util.Slog;
import android.util.Spline;
-import com.android.internal.util.Preconditions;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
import com.android.server.display.utils.Plog;
import java.io.PrintWriter;
@@ -77,8 +77,8 @@ public abstract class BrightnessMappingStrategy {
Slog.w(TAG, "Screen brightness mapping does not cover whole range of available " +
"backlight values, autobrightness functionality may be impaired.");
}
- BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder();
- builder.setCurve(luxLevels, brightnessLevelsNits);
+ BrightnessConfiguration.Builder builder = new BrightnessConfiguration.Builder(
+ luxLevels, brightnessLevelsNits);
return new PhysicalMappingStrategy(builder.build(), nitsRange, backlightRange,
autoBrightnessAdjustmentMaxGamma);
} else if (isValidMapping(luxLevels, brightnessLevelsBacklight)) {
diff --git a/services/core/java/com/android/server/InputContentUriTokenHandler.java b/services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java
index 6338b2f338ab..845fca1127dd 100644
--- a/services/core/java/com/android/server/InputContentUriTokenHandler.java
+++ b/services/core/java/com/android/server/inputmethod/InputContentUriTokenHandler.java
@@ -14,11 +14,10 @@
** limitations under the License.
*/
-package com.android.server;
+package com.android.server.inputmethod;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
-import android.app.ActivityManager;
import android.app.UriGrantsManager;
import android.content.Intent;
import android.net.Uri;
@@ -28,6 +27,7 @@ import android.os.RemoteException;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.inputmethod.IInputContentUriToken;
+import com.android.server.LocalServices;
import com.android.server.uri.UriGrantsManagerInternal;
final class InputContentUriTokenHandler extends IInputContentUriToken.Stub {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e435a4fd6384..49f33e09a724 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -13,7 +13,7 @@
* the License.
*/
-package com.android.server;
+package com.android.server.inputmethod;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
@@ -149,7 +149,9 @@ import com.android.internal.view.IInputMethodSession;
import com.android.internal.view.IInputSessionCallback;
import com.android.internal.view.InputBindResult;
import com.android.internal.view.InputMethodClient;
-import com.android.server.inputmethod.InputMethodManagerInternal;
+import com.android.server.EventLogTags;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
import com.android.server.statusbar.StatusBarManagerService;
import com.android.server.wm.WindowManagerInternal;
@@ -253,7 +255,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
* the notification.
*/
private static final String ACTION_SHOW_INPUT_METHOD_PICKER =
- "com.android.server.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
+ "com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER";
/**
* Debug flag for overriding runtime {@link SystemProperties}.
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index b4bc7f507701..452b699667b7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -46,9 +46,9 @@ public class NetworkPolicyLogger {
static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
private static final int MAX_LOG_SIZE =
- ActivityManager.isLowRamDeviceStatic() ? 20 : 50;
+ ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
private static final int MAX_NETWORK_BLOCKED_LOG_SIZE =
- ActivityManager.isLowRamDeviceStatic() ? 50 : 100;
+ ActivityManager.isLowRamDeviceStatic() ? 100 : 400;
private static final int EVENT_TYPE_GENERIC = 0;
private static final int EVENT_NETWORK_BLOCKED = 1;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 76f969508b28..48e09d744ff4 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -796,7 +796,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
try {
mActivityManager.registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE|ActivityManager.UID_OBSERVER_GONE,
- ActivityManager.PROCESS_STATE_UNKNOWN, null);
+ NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE, "android");
mNetworkManager.registerObserver(mAlertObserver);
} catch (RemoteException e) {
// ignored; both services live in system_server
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 340ae0ad637a..7751f5f9bcb8 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -694,7 +694,8 @@ abstract public class ManagedServices {
for (int userId : userIds) {
if (enabled) {
- if (isPackageOrComponentAllowed(component.toString(), userId)) {
+ if (isPackageOrComponentAllowed(component.toString(), userId)
+ || isPackageOrComponentAllowed(component.getPackageName(), userId)) {
registerServiceLocked(component, userId);
} else {
Slog.d(TAG, component + " no longer has permission to be bound");
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 593e7cdf4d66..13ff6e8e551f 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -107,7 +107,7 @@ public class PreferencesHelper implements RankingConfig {
}
// pkg|uid => PackagePreferences
- private final ArrayMap<String, PackagePreferences> mPackagePreferencess = new ArrayMap<>();
+ private final ArrayMap<String, PackagePreferences> mPackagePreferences = new ArrayMap<>();
// pkg => PackagePreferences
private final ArrayMap<String, PackagePreferences> mRestoredWithoutUids = new ArrayMap<>();
@@ -142,109 +142,117 @@ public class PreferencesHelper implements RankingConfig {
if (type != XmlPullParser.START_TAG) return;
String tag = parser.getName();
if (!TAG_RANKING.equals(tag)) return;
- // Clobber groups and channels with the xml, but don't delete other data that wasn't present
- // at the time of serialization.
- mRestoredWithoutUids.clear();
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
- tag = parser.getName();
- if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
- return;
- }
- if (type == XmlPullParser.START_TAG) {
- if (TAG_PACKAGE.equals(tag)) {
- int uid = XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
- String name = parser.getAttributeValue(null, ATT_NAME);
- if (!TextUtils.isEmpty(name)) {
- if (forRestore) {
- try {
- //TODO: http://b/22388012
- uid = mPm.getPackageUidAsUser(name,
- UserHandle.USER_SYSTEM);
- } catch (PackageManager.NameNotFoundException e) {
- // noop
+ synchronized (mPackagePreferences) {
+ // Clobber groups and channels with the xml, but don't delete other data that wasn't present
+
+ // at the time of serialization.
+ mRestoredWithoutUids.clear();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
+ tag = parser.getName();
+ if (type == XmlPullParser.END_TAG && TAG_RANKING.equals(tag)) {
+ return;
+ }
+ if (type == XmlPullParser.START_TAG) {
+ if (TAG_PACKAGE.equals(tag)) {
+ int uid = XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
+ String name = parser.getAttributeValue(null, ATT_NAME);
+ if (!TextUtils.isEmpty(name)) {
+ if (forRestore) {
+ try {
+ //TODO: http://b/22388012
+ uid = mPm.getPackageUidAsUser(name,
+ UserHandle.USER_SYSTEM);
+ } catch (PackageManager.NameNotFoundException e) {
+ // noop
+ }
}
- }
- PackagePreferences r = getOrCreatePackagePreferences(name, uid,
- XmlUtils.readIntAttribute(
- parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
- XmlUtils.readIntAttribute(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
- XmlUtils.readIntAttribute(
- parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
- XmlUtils.readBooleanAttribute(
- parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
- r.importance = XmlUtils.readIntAttribute(
- parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
- r.priority = XmlUtils.readIntAttribute(
- parser, ATT_PRIORITY, DEFAULT_PRIORITY);
- r.visibility = XmlUtils.readIntAttribute(
- parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
- r.showBadge = XmlUtils.readBooleanAttribute(
- parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
- r.lockedAppFields = XmlUtils.readIntAttribute(parser,
- ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS);
-
- final int innerDepth = parser.getDepth();
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > innerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
+ PackagePreferences r = getOrCreatePackagePreferences(name, uid,
+ XmlUtils.readIntAttribute(
+ parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
+ XmlUtils.readIntAttribute(parser, ATT_PRIORITY,
+ DEFAULT_PRIORITY),
+ XmlUtils.readIntAttribute(
+ parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
+ XmlUtils.readBooleanAttribute(
+ parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
+ r.importance = XmlUtils.readIntAttribute(
+ parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+ r.priority = XmlUtils.readIntAttribute(
+ parser, ATT_PRIORITY, DEFAULT_PRIORITY);
+ r.visibility = XmlUtils.readIntAttribute(
+ parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
+ r.showBadge = XmlUtils.readBooleanAttribute(
+ parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
+ r.lockedAppFields = XmlUtils.readIntAttribute(parser,
+ ATT_APP_USER_LOCKED_FIELDS, DEFAULT_LOCKED_APP_FIELDS);
+
+ final int innerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
- String tagName = parser.getName();
- // Channel groups
- if (TAG_GROUP.equals(tagName)) {
- String id = parser.getAttributeValue(null, ATT_ID);
- CharSequence groupName = parser.getAttributeValue(null, ATT_NAME);
- if (!TextUtils.isEmpty(id)) {
- NotificationChannelGroup group
- = new NotificationChannelGroup(id, groupName);
- group.populateFromXml(parser);
- r.groups.put(id, group);
+ String tagName = parser.getName();
+ // Channel groups
+ if (TAG_GROUP.equals(tagName)) {
+ String id = parser.getAttributeValue(null, ATT_ID);
+ CharSequence groupName = parser.getAttributeValue(null,
+ ATT_NAME);
+ if (!TextUtils.isEmpty(id)) {
+ NotificationChannelGroup group
+ = new NotificationChannelGroup(id, groupName);
+ group.populateFromXml(parser);
+ r.groups.put(id, group);
+ }
}
- }
- // Channels
- if (TAG_CHANNEL.equals(tagName)) {
- String id = parser.getAttributeValue(null, ATT_ID);
- String channelName = parser.getAttributeValue(null, ATT_NAME);
- int channelImportance = XmlUtils.readIntAttribute(
- parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
- if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
- NotificationChannel channel = new NotificationChannel(id,
- channelName, channelImportance);
- if (forRestore) {
- channel.populateFromXmlForRestore(parser, mContext);
- } else {
- channel.populateFromXml(parser);
+ // Channels
+ if (TAG_CHANNEL.equals(tagName)) {
+ String id = parser.getAttributeValue(null, ATT_ID);
+ String channelName = parser.getAttributeValue(null, ATT_NAME);
+ int channelImportance = XmlUtils.readIntAttribute(
+ parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
+ if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
+ NotificationChannel channel = new NotificationChannel(id,
+ channelName, channelImportance);
+ if (forRestore) {
+ channel.populateFromXmlForRestore(parser, mContext);
+ } else {
+ channel.populateFromXml(parser);
+ }
+ r.channels.put(id, channel);
}
- r.channels.put(id, channel);
}
- }
- // Delegate
- if (TAG_DELEGATE.equals(tagName)) {
- int delegateId =
- XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
- String delegateName =
- XmlUtils.readStringAttribute(parser, ATT_NAME);
- boolean delegateEnabled = XmlUtils.readBooleanAttribute(
- parser, ATT_ENABLED, Delegate.DEFAULT_ENABLED);
- boolean userAllowed = XmlUtils.readBooleanAttribute(
- parser, ATT_USER_ALLOWED, Delegate.DEFAULT_USER_ALLOWED);
- Delegate d = null;
- if (delegateId != UNKNOWN_UID && !TextUtils.isEmpty(delegateName)) {
- d = new Delegate(
- delegateName, delegateId, delegateEnabled, userAllowed);
+ // Delegate
+ if (TAG_DELEGATE.equals(tagName)) {
+ int delegateId =
+ XmlUtils.readIntAttribute(parser, ATT_UID, UNKNOWN_UID);
+ String delegateName =
+ XmlUtils.readStringAttribute(parser, ATT_NAME);
+ boolean delegateEnabled = XmlUtils.readBooleanAttribute(
+ parser, ATT_ENABLED, Delegate.DEFAULT_ENABLED);
+ boolean userAllowed = XmlUtils.readBooleanAttribute(
+ parser, ATT_USER_ALLOWED,
+ Delegate.DEFAULT_USER_ALLOWED);
+ Delegate d = null;
+ if (delegateId != UNKNOWN_UID && !TextUtils.isEmpty(
+ delegateName)) {
+ d = new Delegate(
+ delegateName, delegateId, delegateEnabled,
+ userAllowed);
+ }
+ r.delegate = d;
}
- r.delegate = d;
- }
- }
+ }
- try {
- deleteDefaultChannelIfNeeded(r);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.e(TAG, "deleteDefaultChannelIfNeeded - Exception: " + e);
+ try {
+ deleteDefaultChannelIfNeeded(r);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "deleteDefaultChannelIfNeeded - Exception: " + e);
+ }
}
}
}
@@ -255,8 +263,8 @@ public class PreferencesHelper implements RankingConfig {
private PackagePreferences getPackagePreferences(String pkg, int uid) {
final String key = packagePreferencesKey(pkg, uid);
- synchronized (mPackagePreferencess) {
- return mPackagePreferencess.get(key);
+ synchronized (mPackagePreferences) {
+ return mPackagePreferences.get(key);
}
}
@@ -268,10 +276,10 @@ public class PreferencesHelper implements RankingConfig {
private PackagePreferences getOrCreatePackagePreferences(String pkg, int uid, int importance,
int priority, int visibility, boolean showBadge) {
final String key = packagePreferencesKey(pkg, uid);
- synchronized (mPackagePreferencess) {
+ synchronized (mPackagePreferences) {
PackagePreferences
r = (uid == UNKNOWN_UID) ? mRestoredWithoutUids.get(pkg)
- : mPackagePreferencess.get(key);
+ : mPackagePreferences.get(key);
if (r == null) {
r = new PackagePreferences();
r.pkg = pkg;
@@ -290,7 +298,7 @@ public class PreferencesHelper implements RankingConfig {
if (r.uid == UNKNOWN_UID) {
mRestoredWithoutUids.put(pkg, r);
} else {
- mPackagePreferencess.put(key, r);
+ mPackagePreferences.put(key, r);
}
}
return r;
@@ -364,10 +372,10 @@ public class PreferencesHelper implements RankingConfig {
out.startTag(null, TAG_RANKING);
out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
- synchronized (mPackagePreferencess) {
- final int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(i);
+ final PackagePreferences r = mPackagePreferences.valueAt(i);
//TODO: http://b/22388012
if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
continue;
@@ -882,10 +890,10 @@ public class PreferencesHelper implements RankingConfig {
public int getBlockedAppCount(int userId) {
int count = 0;
- synchronized (mPackagePreferencess) {
- final int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(i);
+ final PackagePreferences r = mPackagePreferences.valueAt(i);
if (userId == UserHandle.getUserId(r.uid)
&& r.importance == IMPORTANCE_NONE) {
count++;
@@ -896,11 +904,11 @@ public class PreferencesHelper implements RankingConfig {
}
public void updateChannelsBypassingDnd() {
- synchronized (mPackagePreferencess) {
- final int numPackagePreferencess = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ final int numPackagePreferencess = mPackagePreferences.size();
for (int PackagePreferencesIndex = 0; PackagePreferencesIndex < numPackagePreferencess;
PackagePreferencesIndex++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(PackagePreferencesIndex);
+ final PackagePreferences r = mPackagePreferences.valueAt(PackagePreferencesIndex);
final int numChannels = r.channels.size();
for (int channelIndex = 0; channelIndex < numChannels; channelIndex++) {
@@ -1064,8 +1072,8 @@ public class PreferencesHelper implements RankingConfig {
pw.println("per-package config:");
pw.println("PackagePreferencess:");
- synchronized (mPackagePreferencess) {
- dumpPackagePreferencess(pw, prefix, filter, mPackagePreferencess);
+ synchronized (mPackagePreferences) {
+ dumpPackagePreferencess(pw, prefix, filter, mPackagePreferences);
}
pw.println("Restored without uid:");
dumpPackagePreferencess(pw, prefix, filter, mRestoredWithoutUids);
@@ -1073,9 +1081,9 @@ public class PreferencesHelper implements RankingConfig {
public void dump(ProtoOutputStream proto,
@NonNull NotificationManagerService.DumpFilter filter) {
- synchronized (mPackagePreferencess) {
+ synchronized (mPackagePreferences) {
dumpPackagePreferencess(proto, RankingHelperProto.RECORDS, filter,
- mPackagePreferencess);
+ mPackagePreferences);
}
dumpPackagePreferencess(proto, RankingHelperProto.RECORDS_RESTORED_WITHOUT_UID, filter,
mRestoredWithoutUids);
@@ -1160,10 +1168,10 @@ public class PreferencesHelper implements RankingConfig {
} catch (JSONException e) {
// pass
}
- synchronized (mPackagePreferencess) {
- final int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ final int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(i);
+ final PackagePreferences r = mPackagePreferences.valueAt(i);
if (filter == null || filter.matches(r.pkg)) {
JSONObject PackagePreferences = new JSONObject();
try {
@@ -1240,11 +1248,11 @@ public class PreferencesHelper implements RankingConfig {
}
public Map<Integer, String> getPackageBans() {
- synchronized (mPackagePreferencess) {
- final int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ final int N = mPackagePreferences.size();
ArrayMap<Integer, String> packageBans = new ArrayMap<>(N);
for (int i = 0; i < N; i++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(i);
+ final PackagePreferences r = mPackagePreferences.valueAt(i);
if (r.importance == IMPORTANCE_NONE) {
packageBans.put(r.uid, r.pkg);
}
@@ -1284,9 +1292,9 @@ public class PreferencesHelper implements RankingConfig {
private Map<String, Integer> getPackageChannels() {
ArrayMap<String, Integer> packageChannels = new ArrayMap<>();
- synchronized (mPackagePreferencess) {
- for (int i = 0; i < mPackagePreferencess.size(); i++) {
- final PackagePreferences r = mPackagePreferencess.valueAt(i);
+ synchronized (mPackagePreferences) {
+ for (int i = 0; i < mPackagePreferences.size(); i++) {
+ final PackagePreferences r = mPackagePreferences.valueAt(i);
int channelCount = 0;
for (int j = 0; j < r.channels.size(); j++) {
if (!r.channels.valueAt(j).isDeleted()) {
@@ -1300,22 +1308,22 @@ public class PreferencesHelper implements RankingConfig {
}
public void onUserRemoved(int userId) {
- synchronized (mPackagePreferencess) {
- int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ int N = mPackagePreferences.size();
for (int i = N - 1; i >= 0; i--) {
- PackagePreferences PackagePreferences = mPackagePreferencess.valueAt(i);
+ PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
if (UserHandle.getUserId(PackagePreferences.uid) == userId) {
- mPackagePreferencess.removeAt(i);
+ mPackagePreferences.removeAt(i);
}
}
}
}
protected void onLocaleChanged(Context context, int userId) {
- synchronized (mPackagePreferencess) {
- int N = mPackagePreferencess.size();
+ synchronized (mPackagePreferences) {
+ int N = mPackagePreferences.size();
for (int i = 0; i < N; i++) {
- PackagePreferences PackagePreferences = mPackagePreferencess.valueAt(i);
+ PackagePreferences PackagePreferences = mPackagePreferences.valueAt(i);
if (UserHandle.getUserId(PackagePreferences.uid) == userId) {
if (PackagePreferences.channels.containsKey(
NotificationChannel.DEFAULT_CHANNEL_ID)) {
@@ -1341,8 +1349,8 @@ public class PreferencesHelper implements RankingConfig {
for (int i = 0; i < size; i++) {
final String pkg = pkgList[i];
final int uid = uidList[i];
- synchronized (mPackagePreferencess) {
- mPackagePreferencess.remove(packagePreferencesKey(pkg, uid));
+ synchronized (mPackagePreferences) {
+ mPackagePreferences.remove(packagePreferencesKey(pkg, uid));
}
mRestoredWithoutUids.remove(pkg);
updated = true;
@@ -1355,8 +1363,8 @@ public class PreferencesHelper implements RankingConfig {
try {
r.uid = mPm.getPackageUidAsUser(r.pkg, changeUserId);
mRestoredWithoutUids.remove(pkg);
- synchronized (mPackagePreferencess) {
- mPackagePreferencess.put(packagePreferencesKey(r.pkg, r.uid), r);
+ synchronized (mPackagePreferences) {
+ mPackagePreferences.put(packagePreferencesKey(r.pkg, r.uid), r);
}
updated = true;
} catch (PackageManager.NameNotFoundException e) {
@@ -1365,11 +1373,13 @@ public class PreferencesHelper implements RankingConfig {
}
// Package upgrade
try {
- PackagePreferences fullPackagePreferences = getPackagePreferences(pkg,
- mPm.getPackageUidAsUser(pkg, changeUserId));
- if (fullPackagePreferences != null) {
- createDefaultChannelIfNeeded(fullPackagePreferences);
- deleteDefaultChannelIfNeeded(fullPackagePreferences);
+ synchronized (mPackagePreferences) {
+ PackagePreferences fullPackagePreferences = getPackagePreferences(pkg,
+ mPm.getPackageUidAsUser(pkg, changeUserId));
+ if (fullPackagePreferences != null) {
+ createDefaultChannelIfNeeded(fullPackagePreferences);
+ deleteDefaultChannelIfNeeded(fullPackagePreferences);
+ }
}
} catch (PackageManager.NameNotFoundException e) {
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index df680f2582c6..ac496a84f178 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -356,8 +356,8 @@ public abstract class WindowManagerInternal {
/**
* Notifies WindowManagerService that the current IME window status is being changed.
*
- * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested
- * caller of this method.</p>
+ * <p>Only {@link com.android.server.inputmethod.InputMethodManagerService} is the expected and
+ * tested caller of this method.</p>
*
* @param imeToken token to track the active input method. Corresponding IME windows can be
* identified by checking {@link android.view.WindowManager.LayoutParams#token}.
@@ -376,8 +376,8 @@ public abstract class WindowManagerInternal {
/**
* Notifies WindowManagerService that the current IME window status is being changed.
*
- * <p>Only {@link com.android.server.InputMethodManagerService} is the expected and tested
- * caller of this method.</p>
+ * <p>Only {@link com.android.server.inputmethod.InputMethodManagerService} is the expected and
+ * tested caller of this method.</p>
*
* @param imeToken token to track the active input method. Corresponding IME windows can be
* identified by checking {@link android.view.WindowManager.LayoutParams#token}.
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0b6a33f8c013..c80b9d84ce61 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -82,6 +82,7 @@ import com.android.server.biometrics.face.FaceService;
import com.android.server.biometrics.fingerprint.FingerprintService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
+import com.android.server.inputmethod.InputMethodManagerService;
import com.android.server.job.JobSchedulerService;
import com.android.server.lights.LightsService;
import com.android.server.media.MediaResourceMonitorService;
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index ccc092d3b0e7..0176dd496a33 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -228,6 +228,9 @@ public class IpClient extends StateMachine {
// Encourages logging of any available arguments, and all call sites
// are necessarily logged identically.
//
+ // NOTE: Log first because passed objects may or may not be thread-safe and
+ // once passed on to the callback they may be modified by another thread.
+ //
// TODO: Find an lighter weight approach.
private class LoggingCallbackWrapper extends Callback {
private static final String PREFIX = "INVOKE ";
@@ -243,63 +246,63 @@ public class IpClient extends StateMachine {
@Override
public void onPreDhcpAction() {
- mCallback.onPreDhcpAction();
log("onPreDhcpAction()");
+ mCallback.onPreDhcpAction();
}
@Override
public void onPostDhcpAction() {
- mCallback.onPostDhcpAction();
log("onPostDhcpAction()");
+ mCallback.onPostDhcpAction();
}
@Override
public void onNewDhcpResults(DhcpResults dhcpResults) {
- mCallback.onNewDhcpResults(dhcpResults);
log("onNewDhcpResults({" + dhcpResults + "})");
+ mCallback.onNewDhcpResults(dhcpResults);
}
@Override
public void onProvisioningSuccess(LinkProperties newLp) {
- mCallback.onProvisioningSuccess(newLp);
log("onProvisioningSuccess({" + newLp + "})");
+ mCallback.onProvisioningSuccess(newLp);
}
@Override
public void onProvisioningFailure(LinkProperties newLp) {
- mCallback.onProvisioningFailure(newLp);
log("onProvisioningFailure({" + newLp + "})");
+ mCallback.onProvisioningFailure(newLp);
}
@Override
public void onLinkPropertiesChange(LinkProperties newLp) {
- mCallback.onLinkPropertiesChange(newLp);
log("onLinkPropertiesChange({" + newLp + "})");
+ mCallback.onLinkPropertiesChange(newLp);
}
@Override
public void onReachabilityLost(String logMsg) {
- mCallback.onReachabilityLost(logMsg);
log("onReachabilityLost(" + logMsg + ")");
+ mCallback.onReachabilityLost(logMsg);
}
@Override
public void onQuit() {
- mCallback.onQuit();
log("onQuit()");
+ mCallback.onQuit();
}
@Override
public void installPacketFilter(byte[] filter) {
- mCallback.installPacketFilter(filter);
log("installPacketFilter(byte[" + filter.length + "])");
+ mCallback.installPacketFilter(filter);
}
@Override
public void startReadPacketFilter() {
- mCallback.startReadPacketFilter();
log("startReadPacketFilter()");
+ mCallback.startReadPacketFilter();
}
@Override
public void setFallbackMulticastFilter(boolean enabled) {
- mCallback.setFallbackMulticastFilter(enabled);
log("setFallbackMulticastFilter(" + enabled + ")");
+ mCallback.setFallbackMulticastFilter(enabled);
}
@Override
public void setNeighborDiscoveryOffload(boolean enable) {
- mCallback.setNeighborDiscoveryOffload(enable);
log("setNeighborDiscoveryOffload(" + enable + ")");
+ mCallback.setNeighborDiscoveryOffload(enable);
}
}
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 2691701f79af..8b5977144db1 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -75,6 +75,7 @@ LOCAL_AIDL_INCLUDES := \
LOCAL_STATIC_JAVA_LIBRARIES := \
platform-robolectric-android-all-stubs \
android-support-test \
+ guava \
mockito-robolectric-prebuilt \
platform-test-annotations \
truth-prebuilt \
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
new file mode 100644
index 000000000000..3b6e038ec8cb
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunk/ChunkHashTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.encryption.chunk;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.primitives.Bytes;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class ChunkHashTest {
+ private static final int HASH_LENGTH_BYTES = 256 / 8;
+ private static final byte[] TEST_HASH_1 = Arrays.copyOf(new byte[] {1}, HASH_LENGTH_BYTES);
+ private static final byte[] TEST_HASH_2 = Arrays.copyOf(new byte[] {2}, HASH_LENGTH_BYTES);
+
+ @Test
+ public void testGetHash_returnsHash() {
+ ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
+
+ byte[] hash = chunkHash.getHash();
+
+ assertThat(hash).asList().containsExactlyElementsIn(Bytes.asList(TEST_HASH_1)).inOrder();
+ }
+
+ @Test
+ public void testEquals() {
+ ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+ assertThat(chunkHash1).isEqualTo(equalChunkHash1);
+ assertThat(chunkHash1).isNotEqualTo(chunkHash2);
+ }
+
+ @Test
+ public void testHashCode() {
+ ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash equalChunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+ int hash1 = chunkHash1.hashCode();
+ int equalHash1 = equalChunkHash1.hashCode();
+ int hash2 = chunkHash2.hashCode();
+
+ assertThat(hash1).isEqualTo(equalHash1);
+ assertThat(hash1).isNotEqualTo(hash2);
+ }
+
+ @Test
+ public void testCompareTo_whenEqual_returnsZero() {
+ ChunkHash chunkHash = new ChunkHash(TEST_HASH_1);
+ ChunkHash equalChunkHash = new ChunkHash(TEST_HASH_1);
+
+ int result = chunkHash.compareTo(equalChunkHash);
+
+ assertThat(result).isEqualTo(0);
+ }
+
+ @Test
+ public void testCompareTo_whenArgumentGreater_returnsNegative() {
+ ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+ int result = chunkHash1.compareTo(chunkHash2);
+
+ assertThat(result).isLessThan(0);
+ }
+
+ @Test
+ public void testCompareTo_whenArgumentSmaller_returnsPositive() {
+ ChunkHash chunkHash1 = new ChunkHash(TEST_HASH_1);
+ ChunkHash chunkHash2 = new ChunkHash(TEST_HASH_2);
+
+ int result = chunkHash2.compareTo(chunkHash1);
+
+ assertThat(result).isGreaterThan(0);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index eb28e1ae2f23..1eb88baafa48 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -100,6 +100,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
@@ -365,7 +366,7 @@ public class NetworkPolicyManagerServiceTest {
return null;
}
}).when(mActivityManager).registerUidObserver(any(), anyInt(),
- eq(ActivityManager.PROCESS_STATE_UNKNOWN), isNull(String.class));
+ eq(NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE), isNull(String.class));
mFutureIntent = newRestrictBackgroundChangedFuture();
mService = new NetworkPolicyManagerService(mServiceContext, mActivityManager,
diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
index e6ca03b17092..48dda019f570 100644
--- a/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/BrightnessMappingStrategyTest.java
@@ -152,8 +152,7 @@ public class BrightnessMappingStrategyTest {
final float[] lux = { 0f, 1f };
final float[] nits = { 0, PowerManager.BRIGHTNESS_ON };
- BrightnessConfiguration config = new BrightnessConfiguration.Builder()
- .setCurve(lux, nits)
+ BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.build();
strategy.setBrightnessConfiguration(config);
assertNotEquals(1.0f, strategy.getBrightness(1f), 0.01 /*tolerance*/);
@@ -214,8 +213,7 @@ public class BrightnessMappingStrategyTest {
DISPLAY_RANGE_NITS[DISPLAY_RANGE_NITS.length - 1]
};
- BrightnessConfiguration config = new BrightnessConfiguration.Builder()
- .setCurve(lux, nits)
+ BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits)
.build();
strategy.setBrightnessConfiguration(config);
assertEquals(1.0f, strategy.getBrightness(1f), 0.01 /*tolerance*/);
diff --git a/startop/OWNERS b/startop/OWNERS
new file mode 100644
index 000000000000..bfe96d3ed15c
--- /dev/null
+++ b/startop/OWNERS
@@ -0,0 +1,5 @@
+# mailing list: startop-eng@google.com
+chriswailes@google.com
+eholk@google.com
+iam@google.com
+sehr@google.com
diff --git a/startop/scripts/app_startup/analyze_metrics.py b/startop/scripts/app_startup/analyze_metrics.py
new file mode 100755
index 000000000000..d74d6f68d823
--- /dev/null
+++ b/startop/scripts/app_startup/analyze_metrics.py
@@ -0,0 +1,457 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018, 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.
+
+"""
+Perform statistical analysis on measurements produced by app_startup_runner.py
+
+Install:
+$> sudo apt-get install python3-scipy
+
+Usage:
+$> ./analyze_metrics.py <filename.csv> [<filename2.csv> ...]
+$> ./analyze_metrics.py --help
+"""
+
+import argparse
+import csv
+import itertools
+import os
+import subprocess
+import sys
+import tempfile
+from typing import Any, List, Dict, Iterable, TextIO, Tuple
+
+from scipy import stats as sc
+import numpy as np
+
+
+# These CSV columns are considered labels. Everything after them in the same row are metrics.
+_LABEL_COLUMNS=['packages', 'readaheads', 'compiler_filters']
+# The metric series with the 'cold' readahead is the baseline.
+# All others (warm, jit, etc) are the potential improvements.
+
+#fixme: this should probably be an option
+_BASELINE=('readaheads', 'cold')
+# ignore this for some statistic calculations
+_IGNORE_PAIR=('readaheads', 'warm')
+_PLOT_SUBKEY='readaheads'
+_PLOT_GROUPKEY='packages'
+_PLOT_DATA_INDEX = 0
+_DELTA=50
+_DELTA2=100
+_PVALUE_THRESHOLD=0.10
+_debug = False # See -d/--debug flag.
+
+def parse_options(argv: List[str] = None):
+ """Parse command line arguments and return an argparse Namespace object."""
+ parser = argparse.ArgumentParser(description="Perform statistical analysis on measurements produced by app_start_runner.py.")
+ parser.add_argument('input_files', metavar='file.csv', nargs='+', help='CSV file produced by app_startup_runner.py')
+
+ parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
+ parser.add_argument('-os', '--output-samples', dest='output_samples', default='/dev/null', action='store', help='Store CSV for per-sample data')
+ parser.add_argument('-oc', '--output-comparable', dest='output_comparable', default='/dev/null', action='store', help='Output CSV for comparable against baseline')
+ parser.add_argument('-ocs', '--output-comparable-significant', dest='output_comparable_significant', default='/dev/null', action='store', help='Output CSV for comparable against baseline (significant only)')
+ parser.add_argument('-pt', '--pvalue-threshold', dest='pvalue_threshold', type=float, default=_PVALUE_THRESHOLD, action='store')
+ parser.add_argument('-dt', '--delta-threshold', dest='delta_threshold', type=int, default=_DELTA, action='store')
+
+ return parser.parse_args(argv)
+
+def _debug_print(*args, **kwargs):
+ """Print the args to sys.stderr if the --debug/-d flag was passed in."""
+ global _debug
+ if _debug:
+ print(*args, **kwargs, file=sys.stderr)
+
+def _expand_gen_repr(args):
+ new_args_list = []
+ for i in args:
+ # detect iterable objects that do not have their own override of __str__
+ if hasattr(i, '__iter__'):
+ to_str = getattr(i, '__str__')
+ if to_str.__objclass__ == object:
+ # the repr for a generator is just type+address, expand it out instead.
+ new_args_list.append([_expand_gen_repr([j])[0] for j in i])
+ continue
+ # normal case: uses the built-in to-string
+ new_args_list.append(i)
+ return new_args_list
+
+def _debug_print_gen(*args, **kwargs):
+ """Like _debug_print but will turn any iterable args into a list."""
+ if not _debug:
+ return
+
+ new_args_list = _expand_gen_repr(args)
+ _debug_print(*new_args_list, **kwargs)
+
+def read_headers(input_file: TextIO) -> Tuple[List[str], List[str]]:
+ _debug_print("read_headers for file: ", input_file.name)
+ csv_reader = csv.reader(input_file)
+
+ label_num_columns = len(_LABEL_COLUMNS)
+
+ try:
+ header = next(csv_reader)
+ except StopIteration:
+ header = None
+ _debug_print('header', header)
+
+ if not header:
+ return (None, None)
+
+ labels = header[0:label_num_columns]
+ data = header[label_num_columns:]
+
+ return (labels, data)
+
+def read_labels_and_data(input_file: TextIO) -> Iterable[Tuple[List[str], List[int]]]:
+ _debug_print("print_analysis for file: ", input_file.name)
+ csv_reader = csv.reader(input_file)
+
+ # Skip the header because it doesn't contain any data.
+ # To get the header see read_headers function.
+ try:
+ header = next(csv_reader)
+ except StopIteration:
+ header = None
+
+ label_num_columns = len(_LABEL_COLUMNS)
+
+ for row in csv_reader:
+ if len(row) > 0 and row[0][0] == ';':
+ _debug_print("skip comment line", row)
+ continue
+
+ labels = row[0:label_num_columns]
+ data = [int(i) for i in row[label_num_columns:]]
+
+# _debug_print("labels:", labels)
+# _debug_print("data:", data)
+
+ yield (labels, data)
+
+def group_metrics_by_label(it: Iterable[Tuple[List[str], List[int]]]):
+ prev_labels = None
+ data_2d = []
+
+ for label_list, data_list in it:
+ if prev_labels != label_list:
+ if prev_labels:
+# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
+ yield (prev_labels, data_2d)
+ data_2d = []
+
+ data_2d.append(data_list)
+ prev_labels = label_list
+
+ if prev_labels:
+# _debug_print("grouped labels:", prev_labels, "data_2d:", data_2d)
+ yield (prev_labels, data_2d)
+
+def data_to_numpy(it: Iterable[Tuple[List[str], List[List[int]]]]) -> Iterable[Tuple[List[str], Any]]:
+ for label_list, data_2d in it:
+ yield (label_list, np.asarray(data_2d, dtype=int))
+
+def iterate_columns(np_data_2d):
+ for col in range(np_data_2d.shape[1]):
+ col_as_array = np_data_2d[:, col]
+ yield col_as_array
+
+def confidence_interval(np_data_2d, percent=0.95):
+ """
+ Given some data [[a,b,c],[d,e,f,]...]
+
+ We assume the same metric is in the column (e.g. [a,d])
+ and that data in the rows (e.g. [b,e]) are separate metric values.
+
+ We then calculate the CI for each metric individually returning it as a list of tuples.
+ """
+ arr = []
+ for col_2d in iterate_columns(np_data_2d):
+ mean = col_2d.mean()
+ sigma = col_2d.std()
+
+ ci = sc.norm.interval(percent, loc=mean, scale=sigma / np.sqrt(len(col_2d)))
+ arr.append(ci)
+
+ # TODO: This seems to be returning NaN when all the samples have the same exact value
+ # (e.g. stddev=0, which can trivially happen when sample count = 1).
+
+ return arr
+
+def print_analysis(it, label_header: List[str], data_header: List[str], output_samples: str):
+ print(label_header)
+
+ with open(output_samples, "w") as output_file:
+
+ csv_writer = csv.writer(output_file)
+ csv_writer.writerow(label_header + ['mean', 'std', 'confidence_interval_a', 'confidence_interval_b'])
+
+ for label_list, np_data_2d in it:
+ print("**********************")
+ print(label_list)
+ print()
+ print(" ", data_header)
+ # aggregate computation column-wise
+ print("Mean: ", np_data_2d.mean(axis=0))
+ print("Std: ", np_data_2d.std(axis=0))
+ print("CI95%:", confidence_interval(np_data_2d))
+ print("SEM: ", stats_standard_error_one(np_data_2d, axis=0))
+
+ #ci = confidence_interval(np_data_2d)[_PLOT_DATA_INDEX]
+ sem = stats_standard_error_one(np_data_2d, axis=0)[_PLOT_DATA_INDEX]
+ mean = np_data_2d.mean(axis=0)[_PLOT_DATA_INDEX]
+
+ ci = (mean - sem, mean + sem)
+
+ csv_writer.writerow(label_list + [mean, np_data_2d.std(axis=0)[_PLOT_DATA_INDEX], ci[0], ci[1]])
+
+def from_file_group_by_labels(input_file):
+ (label_header, data_header) = read_headers(input_file)
+ label_data_iter = read_labels_and_data(input_file)
+ grouped_iter = group_metrics_by_label(label_data_iter)
+ grouped_numpy_iter = data_to_numpy(grouped_iter)
+
+ return grouped_numpy_iter, label_header, data_header
+
+def list_without_index(list, index):
+ return list[:index] + list[index+1:]
+
+def group_by_without_baseline_key(grouped_numpy_iter, label_header):
+ """
+ Data is considered comparable if the only difference is the baseline key
+ (i.e. the readahead is different but the package, compilation filter, etc, are the same).
+
+ Returns iterator that's grouped by the non-baseline labels to an iterator of
+ (label_list, data_2d).
+ """
+ baseline_index = label_header.index(_BASELINE[0])
+
+ def get_label_without_baseline(tpl):
+ label_list, _ = tpl
+ return list_without_index(label_list, baseline_index)
+ # [['pkgname', 'compfilter', 'warm'], [data]]
+ # [['pkgname', 'compfilter', 'cold'], [data2]]
+ # [['pkgname2', 'compfilter', 'warm'], [data3]]
+ #
+ # ->
+ # ( [['pkgname', 'compfilter', 'warm'], [data]] # ignore baseline label change.
+ # [['pkgname', 'compfilter', 'cold'], [data2]] ), # split here because the pkgname changed.
+ # ( [['pkgname2', 'compfilter', 'warm'], [data3]] )
+ for group_info, it in itertools.groupby(grouped_numpy_iter, key = get_label_without_baseline):
+ yield it
+
+ # TODO: replace this messy manual iteration/grouping with pandas
+
+def iterate_comparable_metrics(without_baseline_iter, label_header):
+ baseline_index = label_header.index(_BASELINE[0])
+ baseline_value = _BASELINE[1]
+
+ _debug_print("iterate comparables")
+
+ def is_baseline_fun(tp):
+ ll, dat = tp
+ return ll[baseline_index] == baseline_value
+
+ # iterating here when everything but the baseline key is the same.
+ for it in without_baseline_iter:
+ it1, it2 = itertools.tee(it)
+
+ # find all the baseline data.
+ baseline_filter_it = filter(is_baseline_fun, it1)
+
+ # find non-baseline data.
+ nonbaseline_filter_it = itertools.filterfalse(is_baseline_fun, it2)
+
+ yield itertools.product(baseline_filter_it, nonbaseline_filter_it)
+
+def stats_standard_error_one(a, axis):
+ a_std = a.std(axis=axis, ddof=0)
+ a_len = a.shape[axis]
+
+ return a_std / np.sqrt(a_len)
+
+def stats_standard_error(a, b, axis):
+ a_std = a.std(axis=axis, ddof=0)
+ b_std = b.std(axis=axis, ddof=0)
+
+ a_len = a.shape[axis]
+ b_len = b.shape[axis]
+
+ temp1 = a_std*a_std/a_len
+ temp2 = b_std*b_std/b_len
+
+ return np.sqrt(temp1 + temp2)
+
+def stats_tvalue(a, b, axis, delta = 0):
+ a_mean = a.mean(axis=axis)
+ b_mean = b.mean(axis=axis)
+
+ return (a_mean - b_mean - delta) / stats_standard_error(a, b, axis)
+
+def stats_pvalue(a, b, axis, delta, left:bool = False):
+ """
+ Single-tailed 2-sample t-test.
+
+ Returns p-value for the null hypothesis: mean(a) - mean(b) >= delta.
+ :param a: numpy 2d array
+ :param b: numpy 2d array
+ :param axis: which axis to do the calculations across
+ :param delta: test value of mean differences
+ :param left: if true then use <= delta instead of >= delta
+ :return: p-value
+ """
+ # implement our own pvalue calculation because the built-in t-test (t,p values)
+ # only offer delta=0 , e.g. m1-m1 ? 0
+ # we are however interested in m1-m2 ? delta
+ t_value = stats_tvalue(a, b, axis, delta)
+
+ # 2-sample degrees of freedom is using the array sizes - 2.
+ dof = a.shape[axis] + b.shape[axis] - 2
+
+ if left:
+ # left tailed test. e.g. m1-m2 <= delta
+ return sc.t.cdf(t_value, dof)
+ else:
+ # right tailed test. e.g. m1-m2 >= delta
+ return sc.t.sf(t_value, dof)
+ # a left+right tailed test is a 2-tail t-test and can be done using ttest_ind for delta=0
+
+def print_comparable_analysis(comparable_metrics_iter, label_header, data_header, output_comparable: str, output_comparable_significant: str):
+ baseline_value = _BASELINE[1]
+ baseline_index = label_header.index(_BASELINE[0])
+
+ old_baseline_label_list = None
+ delta = _DELTA
+ filter_value = _IGNORE_PAIR[1]
+ filter_index = label_header.index(_IGNORE_PAIR[0])
+
+ pvalue_threshold = _PVALUE_THRESHOLD
+ ci_threshold = (1 - _PVALUE_THRESHOLD) * 100.0
+
+ with open(output_comparable, "w") as output_file:
+
+ csv_writer = csv.writer(output_file)
+ csv_writer.writerow(label_header + ['mean', 'mean_diff', 'sem', 'pvalue_2tailed', 'pvalue_gt%d' %(_DELTA), 'pvalue_gt%d' %(_DELTA2)])
+
+ print("------------------------------------------------------------------")
+ print("Comparison against the baseline %s = %s" %(_BASELINE, baseline_value))
+ print("--- Right-tailed t-test checks if the baseline >= current %s by at least %d" %(_BASELINE[0], delta))
+ print()
+
+ global_stats = {'better_than_delta': [], 'better_than_delta_p95': []}
+
+ for nested_it in comparable_metrics_iter:
+ print("************************")
+
+ better_than_delta = []
+ better_than_delta_p95 = []
+
+ saw_baseline_once = False
+
+ for ((baseline_label_list, baseline_np_data_2d), (rest_label_list, rest_np_data_2d)) in nested_it:
+ _debug_print("baseline_label_list:", baseline_label_list)
+ _debug_print("baseline_np_data_2d:", baseline_np_data_2d)
+ _debug_print("rest_label_list:", rest_label_list)
+ _debug_print("rest_np_data_2d:", rest_np_data_2d)
+
+ mean_diff = baseline_np_data_2d.mean(axis=0) - rest_np_data_2d.mean(axis=0)
+ # 2-sample 2-tailed t-test with delta=0
+ # e.g. "Is it true that usually the two sample means are different?"
+ t_statistic, t_pvalue = sc.ttest_ind(baseline_np_data_2d, rest_np_data_2d, axis=0)
+
+ # 2-sample 1-tailed t-test with delta=50
+ # e.g. "Is it true that usually the sample means better than 50ms?"
+ t2 = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
+ p2 = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=delta)
+
+ t2_b = stats_tvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
+ p2_b = stats_pvalue(baseline_np_data_2d, rest_np_data_2d, axis=0, delta=_DELTA2)
+
+ print("%s vs %s" %(rest_label_list, baseline_value))
+ print(" ", data_header)
+ print("Mean Difference: ", mean_diff)
+ print("T-test (2-tailed) != 0: t=%s, p=%s" %(t_statistic, t_pvalue))
+ print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA, t2, p2))
+ print("T-test (right-tailed) >= %d: t=%s, p=%s" %(_DELTA2, t2_b, p2_b))
+
+ def write_out_values(label_list, *args):
+ csv_writer.writerow(label_list + [i[_PLOT_DATA_INDEX] for i in args])
+
+ sem = stats_standard_error(baseline_np_data_2d, rest_np_data_2d, axis=0)
+ if saw_baseline_once == False:
+ saw_baseline_once = True
+ base_sem = stats_standard_error_one(baseline_np_data_2d, axis=0)
+ write_out_values(baseline_label_list, baseline_np_data_2d.mean(axis=0), [0], base_sem, [None], [None], [None])
+ write_out_values(rest_label_list, rest_np_data_2d.mean(axis=0), mean_diff, sem, t_pvalue, p2, p2_b)
+
+ # now do the global statistics aggregation
+
+ if rest_label_list[filter_index] == filter_value:
+ continue
+
+ if mean_diff > delta:
+ better_than_delta.append((mean_diff, p2, rest_label_list))
+
+ if p2 <= pvalue_threshold:
+ better_than_delta_p95.append((mean_diff, rest_label_list))
+
+ if better_than_delta:
+ global_stats['better_than_delta'].append(better_than_delta)
+ if better_than_delta_p95:
+ global_stats['better_than_delta_p95'].append(better_than_delta_p95)
+
+ print("------------------------")
+ print("Global statistics:")
+ print("//// Rows with %s=%s are ignored here." %_IGNORE_PAIR)
+ print("- # of results with mean diff better than delta(%d) = %d" %(delta, len(global_stats['better_than_delta'])))
+ print(" > (meandiff, pvalue, labels)")
+ for i in global_stats['better_than_delta']:
+ print(" > %s" %i)
+ print("- # of results with mean diff better than delta(%d) CI%d%% = %d" %(delta, ci_threshold, len(global_stats['better_than_delta_p95'])))
+ print(" > (meandiff, labels)")
+ for i in global_stats['better_than_delta_p95']:
+ print(" > %s" %i)
+
+def main():
+ global _debug
+ global _DELTA
+ global _PVALUE_THRESHOLD
+
+ opts = parse_options()
+ _debug = opts.debug
+ _debug_print("parsed options: ", opts)
+
+ _PVALUE_THRESHOLD = opts.pvalue_threshold or _PVALUE_THRESHOLD
+
+ for file_name in opts.input_files:
+ with open(file_name, 'r') as input_file:
+ (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
+ print_analysis(grouped_numpy_iter, label_header, data_header, opts.output_samples)
+
+ with open(file_name, 'r') as input_file:
+ (grouped_numpy_iter, label_header, data_header) = from_file_group_by_labels(input_file)
+ without_baseline_iter = group_by_without_baseline_key(grouped_numpy_iter, label_header)
+ #_debug_print_gen(without_baseline_iter)
+
+ comparable_metrics_iter = iterate_comparable_metrics(without_baseline_iter, label_header)
+ print_comparable_analysis(comparable_metrics_iter, label_header, data_header, opts.output_comparable, opts.output_comparable_significant)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner.py b/startop/scripts/app_startup/app_startup_runner.py
new file mode 100755
index 000000000000..780bb4eaeeef
--- /dev/null
+++ b/startop/scripts/app_startup/app_startup_runner.py
@@ -0,0 +1,322 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018, 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.
+
+#
+#
+# Measure application start-up time by launching applications under various combinations.
+# See --help for more details.
+#
+#
+# Sample usage:
+# $> ./app_startup_runner.py -p com.google.android.calculator -r warm -r cold -lc 10 -o out.csv
+# $> ./analyze_metrics.py out.csv
+#
+#
+
+import argparse
+import csv
+import itertools
+import os
+import subprocess
+import sys
+import tempfile
+from typing import Any, Callable, Dict, Generic, Iterable, List, NamedTuple, TextIO, Tuple, TypeVar, Optional, Union
+
+# The following command line options participate in the combinatorial generation.
+# All other arguments have a global effect.
+_COMBINATORIAL_OPTIONS=['packages', 'readaheads', 'compiler_filters']
+_TRACING_READAHEADS=['mlock', 'fadvise']
+_FORWARD_OPTIONS={'loop_count': '--count'}
+_RUN_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'run_app_with_prefetch')
+
+RunCommandArgs = NamedTuple('RunCommandArgs', [('package', str), ('readahead', str), ('compiler_filter', Optional[str])])
+CollectorPackageInfo = NamedTuple('CollectorPackageInfo', [('package', str), ('compiler_filter', str)])
+_COLLECTOR_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'collector')
+_COLLECTOR_TIMEOUT_MULTIPLIER = 2 # take the regular --timeout and multiply by 2; systrace starts up slowly.
+
+_UNLOCK_SCREEN_SCRIPT=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'unlock_screen')
+
+# This must be the only mutable global variable. All other global variables are constants to avoid magic literals.
+_debug = False # See -d/--debug flag.
+_DEBUG_FORCE = None # Ignore -d/--debug if this is not none.
+
+# Type hinting names.
+T = TypeVar('T')
+NamedTupleMeta = Callable[..., T] # approximation of a (S : NamedTuple<T> where S() == T) metatype.
+
+def parse_options(argv: List[str] = None):
+ """Parse command line arguments and return an argparse Namespace object."""
+ parser = argparse.ArgumentParser(description="Run one or more Android applications under various settings in order to measure startup time.")
+ # argparse considers args starting with - and -- optional in --help, even though required=True.
+ # by using a named argument group --help will clearly say that it's required instead of optional.
+ required_named = parser.add_argument_group('required named arguments')
+ required_named.add_argument('-p', '--package', action='append', dest='packages', help='package of the application', required=True)
+ required_named.add_argument('-r', '--readahead', action='append', dest='readaheads', help='which readahead mode to use', choices=('warm', 'cold', 'mlock', 'fadvise'), required=True)
+
+ # optional arguments
+ # use a group here to get the required arguments to appear 'above' the optional arguments in help.
+ optional_named = parser.add_argument_group('optional named arguments')
+ optional_named.add_argument('-c', '--compiler-filter', action='append', dest='compiler_filters', help='which compiler filter to use. if omitted it does not enforce the app\'s compiler filter', choices=('speed', 'speed-profile', 'quicken'))
+ optional_named.add_argument('-s', '--simulate', dest='simulate', action='store_true', help='Print which commands will run, but don\'t run the apps')
+ optional_named.add_argument('-d', '--debug', dest='debug', action='store_true', help='Add extra debugging output')
+ optional_named.add_argument('-o', '--output', dest='output', action='store', help='Write CSV output to file.')
+ optional_named.add_argument('-t', '--timeout', dest='timeout', action='store', type=int, help='Timeout after this many seconds when executing a single run.')
+ optional_named.add_argument('-lc', '--loop-count', dest='loop_count', default=1, type=int, action='store', help='How many times to loop a single run.')
+ optional_named.add_argument('-in', '--inodes', dest='inodes', type=str, action='store', help='Path to inodes file (system/extras/pagecache/pagecache.py -d inodes)')
+
+ return parser.parse_args(argv)
+
+# TODO: refactor this with a common library file with analyze_metrics.py
+def _debug_print(*args, **kwargs):
+ """Print the args to sys.stderr if the --debug/-d flag was passed in."""
+ if _debug:
+ print(*args, **kwargs, file=sys.stderr)
+
+def _expand_gen_repr(args):
+ """Like repr but any generator-like object has its iterator consumed
+ and then called repr on."""
+ new_args_list = []
+ for i in args:
+ # detect iterable objects that do not have their own override of __str__
+ if hasattr(i, '__iter__'):
+ to_str = getattr(i, '__str__')
+ if to_str.__objclass__ == object:
+ # the repr for a generator is just type+address, expand it out instead.
+ new_args_list.append([_expand_gen_repr([j])[0] for j in i])
+ continue
+ # normal case: uses the built-in to-string
+ new_args_list.append(i)
+ return new_args_list
+
+def _debug_print_gen(*args, **kwargs):
+ """Like _debug_print but will turn any iterable args into a list."""
+ if not _debug:
+ return
+
+ new_args_list = _expand_gen_repr(args)
+ _debug_print(*new_args_list, **kwargs)
+
+def _debug_print_nd(*args, **kwargs):
+ """Like _debug_print but will turn any NamedTuple-type args into a string."""
+ if not _debug:
+ return
+
+ new_args_list = []
+ for i in args:
+ if hasattr(i, '_field_types'):
+ new_args_list.append("%s: %s" %(i.__name__, i._field_types))
+ else:
+ new_args_list.append(i)
+
+ _debug_print(*new_args_list, **kwargs)
+
+def dict_lookup_any_key(dictionary: dict, *keys: List[Any]):
+ for k in keys:
+ if k in dictionary:
+ return dictionary[k]
+ raise KeyError("None of the keys %s were in the dictionary" %(keys))
+
+def generate_run_combinations(named_tuple: NamedTupleMeta[T], opts_dict: Dict[str, List[Optional[str]]])\
+ -> Iterable[T]:
+ """
+ Create all possible combinations given the values in opts_dict[named_tuple._fields].
+
+ :type T: type annotation for the named_tuple type.
+ :param named_tuple: named tuple type, whose fields are used to make combinations for
+ :param opts_dict: dictionary of keys to value list. keys correspond to the named_tuple fields.
+ :return: an iterable over named_tuple instances.
+ """
+ combinations_list = []
+ for k in named_tuple._fields:
+ # the key can be either singular or plural , e.g. 'package' or 'packages'
+ val = dict_lookup_any_key(opts_dict, k, k + "s")
+
+ # treat {'x': None} key value pairs as if it was [None]
+ # otherwise itertools.product throws an exception about not being able to iterate None.
+ combinations_list.append(val or [None])
+
+ _debug_print("opts_dict: ", opts_dict)
+ _debug_print_nd("named_tuple: ", named_tuple)
+ _debug_print("combinations_list: ", combinations_list)
+
+ for combo in itertools.product(*combinations_list):
+ yield named_tuple(*combo)
+
+def key_to_cmdline_flag(key: str) -> str:
+ """Convert key into a command line flag, e.g. 'foo-bars' -> '--foo-bar' """
+ if key.endswith("s"):
+ key = key[:-1]
+ return "--" + key.replace("_", "-")
+
+def as_run_command(tpl: NamedTuple) -> List[Union[str, Any]]:
+ """
+ Convert a named tuple into a command-line compatible arguments list.
+
+ Example: ABC(1, 2, 3) -> ['--a', 1, '--b', 2, '--c', 3]
+ """
+ args = []
+ for key, value in tpl._asdict().items():
+ if value is None:
+ continue
+ args.append(key_to_cmdline_flag(key))
+ args.append(value)
+ return args
+
+def generate_group_run_combinations(run_combinations: Iterable[NamedTuple], dst_nt: NamedTupleMeta[T])\
+ -> Iterable[Tuple[T, Iterable[NamedTuple]]]:
+
+ def group_by_keys(src_nt):
+ src_d = src_nt._asdict()
+ # now remove the keys that aren't legal in dst.
+ for illegal_key in set(src_d.keys()) - set(dst_nt._fields):
+ if illegal_key in src_d:
+ del src_d[illegal_key]
+
+ return dst_nt(**src_d)
+
+ for args_list_it in itertools.groupby(run_combinations, group_by_keys):
+ (group_key_value, args_it) = args_list_it
+ yield (group_key_value, args_it)
+
+def parse_run_script_csv_file(csv_file: TextIO) -> List[int]:
+ """Parse a CSV file full of integers into a flat int list."""
+ csv_reader = csv.reader(csv_file)
+ arr = []
+ for row in csv_reader:
+ for i in row:
+ if i:
+ arr.append(int(i))
+ return arr
+
+def make_script_command_with_temp_output(script: str, args: List[str], **kwargs)\
+ -> Tuple[str, TextIO]:
+ """
+ Create a command to run a script given the args.
+ Appends --count <loop_count> --output <tmp-file-name>.
+ Returns a tuple (cmd, tmp_file)
+ """
+ tmp_output_file = tempfile.NamedTemporaryFile(mode='r')
+ cmd = [script] + args
+ for key, value in kwargs.items():
+ cmd += ['--%s' %(key), "%s" %(value)]
+ if _debug:
+ cmd += ['--verbose']
+ cmd = cmd + ["--output", tmp_output_file.name]
+ return cmd, tmp_output_file
+
+def execute_arbitrary_command(cmd: List[str], simulate: bool, timeout: int) -> Tuple[bool, str]:
+ if simulate:
+ print(" ".join(cmd))
+ return (True, "")
+ else:
+ _debug_print("[EXECUTE]", cmd)
+ proc = subprocess.Popen(cmd,
+ stderr=subprocess.STDOUT,
+ stdout=subprocess.PIPE,
+ universal_newlines=True)
+ try:
+ script_output = proc.communicate(timeout=timeout)[0]
+ except subprocess.TimeoutExpired:
+ print("[TIMEDOUT]")
+ proc.kill()
+ script_output = proc.communicate()[0]
+
+ _debug_print("[STDOUT]", script_output)
+ return_code = proc.wait()
+ passed = (return_code == 0)
+ _debug_print("[$?]", return_code)
+ if not passed:
+ print("[FAILED, code:%s]" %(return_code), script_output, file=sys.stderr)
+
+ return (passed, script_output)
+
+def execute_run_combos(grouped_run_combos: Iterable[Tuple[CollectorPackageInfo, Iterable[RunCommandArgs]]], simulate: bool, inodes_path: str, timeout: int, loop_count: int, need_trace: bool):
+ # nothing will work if the screen isn't unlocked first.
+ execute_arbitrary_command([_UNLOCK_SCREEN_SCRIPT], simulate, timeout)
+
+ for collector_info, run_combos in grouped_run_combos:
+ #collector_args = ["--package", package_name]
+ collector_args = as_run_command(collector_info)
+ # TODO: forward --wait_time for how long systrace runs?
+ # TODO: forward --trace_buffer_size for size of systrace buffer size?
+ collector_cmd, collector_tmp_output_file = make_script_command_with_temp_output(_COLLECTOR_SCRIPT, collector_args, inodes=inodes_path)
+
+ with collector_tmp_output_file:
+ collector_passed = True
+ if need_trace:
+ collector_timeout = timeout and _COLLECTOR_TIMEOUT_MULTIPLIER * timeout
+ (collector_passed, collector_script_output) = execute_arbitrary_command(collector_cmd, simulate, collector_timeout)
+ # TODO: consider to print a ; collector wrote file to <...> into the CSV file so we know it was ran.
+
+ for combos in run_combos:
+ args = as_run_command(combos)
+
+ cmd, tmp_output_file = make_script_command_with_temp_output(_RUN_SCRIPT, args, count=loop_count, input=collector_tmp_output_file.name)
+ with tmp_output_file:
+ (passed, script_output) = execute_arbitrary_command(cmd, simulate, timeout)
+ parsed_output = simulate and [1,2,3] or parse_run_script_csv_file(tmp_output_file)
+ yield (passed, script_output, parsed_output)
+
+def gather_results(commands: Iterable[Tuple[bool, str, List[int]]], key_list: List[str], value_list: List[Tuple[str, ...]]):
+ _debug_print("gather_results: key_list = ", key_list)
+ yield key_list + ["time(ms)"]
+
+ stringify_none = lambda s: s is None and "<none>" or s
+
+ for ((passed, script_output, run_result_list), values) in itertools.zip_longest(commands, value_list):
+ if not passed:
+ continue
+ for result in run_result_list:
+ yield [stringify_none(i) for i in values] + [result]
+
+ yield ["; avg(%s), min(%s), max(%s), count(%s)" %(sum(run_result_list, 0.0) / len(run_result_list), min(run_result_list), max(run_result_list), len(run_result_list)) ]
+
+def eval_and_save_to_csv(output, annotated_result_values):
+ csv_writer = csv.writer(output)
+ for row in annotated_result_values:
+ csv_writer.writerow(row)
+ output.flush() # see the output live.
+
+def main():
+ global _debug
+
+ opts = parse_options()
+ _debug = opts.debug
+ if _DEBUG_FORCE is not None:
+ _debug = _DEBUG_FORCE
+ _debug_print("parsed options: ", opts)
+ need_trace = not not set(opts.readaheads).intersection(set(_TRACING_READAHEADS))
+ if need_trace and not opts.inodes:
+ print("Error: Missing -in/--inodes, required when using a readahead of %s" %(_TRACING_READAHEADS), file=sys.stderr)
+ return 1
+
+ output_file = opts.output and open(opts.output, 'w') or sys.stdout
+
+ combos = lambda: generate_run_combinations(RunCommandArgs, vars(opts))
+ _debug_print_gen("run combinations: ", combos())
+
+ grouped_combos = lambda: generate_group_run_combinations(combos(), CollectorPackageInfo)
+ _debug_print_gen("grouped run combinations: ", grouped_combos())
+
+ exec = execute_run_combos(grouped_combos(), opts.simulate, opts.inodes, opts.timeout, opts.loop_count, need_trace)
+ results = gather_results(exec, _COMBINATORIAL_OPTIONS, combos())
+ eval_and_save_to_csv(output_file, results)
+
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/startop/scripts/app_startup/app_startup_runner_test.py b/startop/scripts/app_startup/app_startup_runner_test.py
new file mode 100755
index 000000000000..f96f802a3aef
--- /dev/null
+++ b/startop/scripts/app_startup/app_startup_runner_test.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python3
+#
+# Copyright 2018, 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.
+#
+
+"""
+Unit tests for the app_startup_runner.py script.
+
+Install:
+ $> sudo apt-get install python3-pytest ## OR
+ $> pip install -U pytest
+See also https://docs.pytest.org/en/latest/getting-started.html
+
+Usage:
+ $> ./app_startup_runner_test.py
+ $> pytest app_startup_runner_test.py
+ $> python -m pytest app_startup_runner_test.py
+
+See also https://docs.pytest.org/en/latest/usage.html
+"""
+
+# global imports
+from contextlib import contextmanager
+import io
+import shlex
+import sys
+import typing
+
+# pip imports
+import pytest
+
+# local imports
+import app_startup_runner as asr
+
+#
+# Argument Parsing Helpers
+#
+
+@contextmanager
+def ignore_stdout_stderr():
+ """Ignore stdout/stderr output for duration of this context."""
+ old_stdout = sys.stdout
+ old_stderr = sys.stderr
+ sys.stdout = io.StringIO()
+ sys.stderr = io.StringIO()
+ try:
+ yield
+ finally:
+ sys.stdout = old_stdout
+ sys.stderr = old_stderr
+
+@contextmanager
+def argparse_bad_argument(msg):
+ """
+ Assert that a SystemExit is raised when executing this context.
+ If the assertion fails, print the message 'msg'.
+ """
+ with pytest.raises(SystemExit, message=msg):
+ with ignore_stdout_stderr():
+ yield
+
+def assert_bad_argument(args, msg):
+ """
+ Assert that the command line arguments in 'args' are malformed.
+ Prints 'msg' if the assertion fails.
+ """
+ with argparse_bad_argument(msg):
+ parse_args(args)
+
+def parse_args(args):
+ """
+ :param args: command-line like arguments as a single string
+ :return: dictionary of parsed key/values
+ """
+ # "-a b -c d" => ['-a', 'b', '-c', 'd']
+ return vars(asr.parse_options(shlex.split(args)))
+
+def default_dict_for_parsed_args(**kwargs):
+ """
+ # Combine it with all of the "optional" parameters' default values.
+ """
+ d = {'compiler_filters': None, 'simulate': False, 'debug': False, 'output': None, 'timeout': None, 'loop_count': 1, 'inodes': None}
+ d.update(kwargs)
+ return d
+
+def default_mock_dict_for_parsed_args(include_optional=True, **kwargs):
+ """
+ Combine default dict with all optional parameters with some mock required parameters.
+ """
+ d = {'packages': ['com.fake.package'], 'readaheads': ['warm']}
+ if include_optional:
+ d.update(default_dict_for_parsed_args())
+ d.update(kwargs)
+ return d
+
+def parse_optional_args(str):
+ """
+ Parse an argument string which already includes all the required arguments
+ in default_mock_dict_for_parsed_args.
+ """
+ req = "--package com.fake.package --readahead warm"
+ return parse_args("%s %s" %(req, str))
+
+def test_argparse():
+ # missing arguments
+ assert_bad_argument("", "-p and -r are required")
+ assert_bad_argument("-r warm", "-p is required")
+ assert_bad_argument("--readahead warm", "-p is required")
+ assert_bad_argument("-p com.fake.package", "-r is required")
+ assert_bad_argument("--package com.fake.package", "-r is required")
+
+ # required arguments are parsed correctly
+ ad = default_dict_for_parsed_args # assert dict
+
+ assert parse_args("--package xyz --readahead warm") == ad(packages=['xyz'], readaheads=['warm'])
+ assert parse_args("-p xyz -r warm") == ad(packages=['xyz'], readaheads=['warm'])
+
+ assert parse_args("-p xyz -r warm -s") == ad(packages=['xyz'], readaheads=['warm'], simulate=True)
+ assert parse_args("-p xyz -r warm --simulate") == ad(packages=['xyz'], readaheads=['warm'], simulate=True)
+
+ # optional arguments are parsed correctly.
+ mad = default_mock_dict_for_parsed_args # mock assert dict
+ assert parse_optional_args("--output filename.csv") == mad(output='filename.csv')
+ assert parse_optional_args("-o filename.csv") == mad(output='filename.csv')
+
+ assert parse_optional_args("--timeout 123") == mad(timeout=123)
+ assert parse_optional_args("-t 456") == mad(timeout=456)
+
+ assert parse_optional_args("--loop-count 123") == mad(loop_count=123)
+ assert parse_optional_args("-lc 456") == mad(loop_count=456)
+
+ assert parse_optional_args("--inodes bar") == mad(inodes="bar")
+ assert parse_optional_args("-in baz") == mad(inodes="baz")
+
+
+def generate_run_combinations(*args):
+ # expand out the generator values so that assert x == y works properly.
+ return [i for i in asr.generate_run_combinations(*args)]
+
+def test_generate_run_combinations():
+ blank_nd = typing.NamedTuple('Blank')
+ assert generate_run_combinations(blank_nd, {}) == [()], "empty"
+ assert generate_run_combinations(blank_nd, {'a' : ['a1', 'a2']}) == [()], "empty filter"
+ a_nd = typing.NamedTuple('A', [('a', str)])
+ assert generate_run_combinations(a_nd, {'a': None}) == [(None,)], "None"
+ assert generate_run_combinations(a_nd, {'a': ['a1', 'a2']}) == [('a1',), ('a2',)], "one item"
+ assert generate_run_combinations(a_nd,
+ {'a' : ['a1', 'a2'], 'b': ['b1', 'b2']}) == [('a1',), ('a2',)],\
+ "one item filter"
+ ab_nd = typing.NamedTuple('AB', [('a', str), ('b', str)])
+ assert generate_run_combinations(ab_nd,
+ {'a': ['a1', 'a2'],
+ 'b': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
+ ab_nd('a1', 'b2'),
+ ab_nd('a2', 'b1'),
+ ab_nd('a2', 'b2')],\
+ "two items"
+
+ assert generate_run_combinations(ab_nd,
+ {'as': ['a1', 'a2'],
+ 'bs': ['b1', 'b2']}) == [ab_nd('a1', 'b1'),
+ ab_nd('a1', 'b2'),
+ ab_nd('a2', 'b1'),
+ ab_nd('a2', 'b2')],\
+ "two items plural"
+
+def test_key_to_cmdline_flag():
+ assert asr.key_to_cmdline_flag("abc") == "--abc"
+ assert asr.key_to_cmdline_flag("foos") == "--foo"
+ assert asr.key_to_cmdline_flag("ba_r") == "--ba-r"
+ assert asr.key_to_cmdline_flag("ba_zs") == "--ba-z"
+
+
+def test_make_script_command_with_temp_output():
+ cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script", args=[], count=1)
+ with tmp_file:
+ assert cmd_str == ["fake_script", "--count", "1", "--output", tmp_file.name]
+
+ cmd_str, tmp_file = asr.make_script_command_with_temp_output("fake_script", args=['a', 'b'], count=2)
+ with tmp_file:
+ assert cmd_str == ["fake_script", "a", "b", "--count", "2", "--output", tmp_file.name]
+
+def test_parse_run_script_csv_file():
+ # empty file -> empty list
+ f = io.StringIO("")
+ assert asr.parse_run_script_csv_file(f) == []
+
+ # common case
+ f = io.StringIO("1,2,3")
+ assert asr.parse_run_script_csv_file(f) == [1,2,3]
+
+ # ignore trailing comma
+ f = io.StringIO("1,2,3,4,5,")
+ assert asr.parse_run_script_csv_file(f) == [1,2,3,4,5]
+
+
+if __name__ == '__main__':
+ pytest.main()
diff --git a/startop/scripts/app_startup/launch_application b/startop/scripts/app_startup/launch_application
new file mode 100755
index 000000000000..bc4ec51d6d08
--- /dev/null
+++ b/startop/scripts/app_startup/launch_application
@@ -0,0 +1,41 @@
+#!/bin/bash
+#
+# Copyright 2018, 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source "$DIR/lib/common"
+
+launch_application() {
+ local package="$1"
+ local activity="$2"
+ local am_output="$(adb shell am start -S -W "$package"/"$activity")"
+ verbose_print adb shell am start -S -W "$package"/"$activity"
+ if [[ $? -ne 0 ]]; then
+ echo "am start failed" >&2
+
+ return 1
+ fi
+
+ # for everything else use the am start "TotalTime" output.
+ verbose_print "$am_output"
+ local total_time="$(echo "$am_output" | grep 'TotalTime:' | sed 's/TotalTime: //g')"
+ verbose_print "total time: $total_time"
+
+ # TODO: Extract alternative metrics such as the #reportFullyDrawn.
+
+ echo "$total_time"
+}
+
+launch_application "$@"
diff --git a/startop/scripts/app_startup/lib/common b/startop/scripts/app_startup/lib/common
new file mode 100755
index 000000000000..4d5a53e4bb0c
--- /dev/null
+++ b/startop/scripts/app_startup/lib/common
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+if [[ -z $ANDROID_BUILD_TOP ]]; then
+ echo "Please run source build/envsetup.sh first" >&2
+ exit 1
+fi
+
+source $ANDROID_BUILD_TOP/build/envsetup.sh
+
+verbose_print() {
+ if [[ "$verbose" == "y" ]]; then
+ echo "$@" >&2
+ fi
+}
diff --git a/startop/scripts/app_startup/run_app_with_prefetch b/startop/scripts/app_startup/run_app_with_prefetch
new file mode 100755
index 000000000000..1ff5fc64116f
--- /dev/null
+++ b/startop/scripts/app_startup/run_app_with_prefetch
@@ -0,0 +1,344 @@
+#!/bin/bash
+#
+# Copyright 2018, 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.
+
+usage() {
+ cat <<EOF
+Usage: run_app_with_prefetch --package <name> [OPTIONS]...
+
+ -p, --package <name> package of the app to test
+ -a, --activity <name> activity to use
+ -h, --help usage information (this)
+ -v, --verbose enable extra verbose printing
+ -i, --input <file> trace file protobuf (default 'TraceFile.pb')
+ -r, --readahead <mode> cold, warm, fadvise, mlock (default 'warm')
+ -w, --when <when> aot or jit (default 'aot')
+ -c, --count <count> how many times to run (default 1)
+ -s, --sleep <sec> how long to sleep after readahead
+ -t, --timeout <sec> how many seconds to timeout in between each app run (default 10)
+ -o, --output <file.csv> what file to write the performance results into as csv (default stdout)
+EOF
+}
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source "$DIR/lib/common"
+
+needs_trace_file="n"
+input_file=""
+package=""
+mode='warm'
+count=2
+sleep_time=2
+timeout=10
+output="" # stdout by default
+when="aot"
+parse_arguments() {
+ while [[ $# -gt 0 ]]; do
+ case "$1" in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ -p|--package)
+ package="$2"
+ shift
+ ;;
+ -a|--activity)
+ activity="$2"
+ shift
+ ;;
+ -i|--input)
+ input_file="$2"
+ shift
+ ;;
+ -v|--verbose)
+ export verbose="y"
+ ;;
+ -r|--readahead)
+ mode="$2"
+ shift
+ ;;
+ -c|--count)
+ count="$2"
+ ((count+=1))
+ shift
+ ;;
+ -s|--sleep)
+ sleep_time="$2"
+ shift
+ ;;
+ -t|--timeout)
+ timeout="$2"
+ shift
+ ;;
+ -o|--output)
+ output="$2"
+ shift
+ ;;
+ -w|--when)
+ when="$2"
+ shift
+ ;;
+ --compiler-filter)
+ # ignore any '--compiler-filter xyz' settings.
+ # FIXME: app_startup_runner.py should not be passing this flag.
+ shift
+ ;;
+ *)
+ echo "Invalid argument: $1" >&2
+ exit 1
+ esac
+ shift
+ done
+}
+
+echo_to_output_file() {
+ if [[ "x$output" != x ]]; then
+ echo "$@" >> $output
+ fi
+ # Always echo to stdout as well.
+ echo "$@"
+}
+
+get_activity_name() {
+ local package="$1"
+ local action_key="android.intent.action.MAIN:"
+
+ local activity_line="$(adb shell cmd package query-activities --brief -a android.intent.action.MAIN -c android.intent.category.LAUNCHER | grep "$package")"
+ #echo $activity_line
+ IFS="/" read -a array <<< "$activity_line"
+ local activity_name="${array[1]}"
+ echo "$activity_name"
+ #adb shell am start "$package/$activity_name"
+}
+
+find_package_path() {
+ local pkg="$1"
+
+ res="$(adb shell find "/data/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
+ if [[ -z $res ]]; then
+ res="$(adb shell find "/system/app/$pkg"-'*' -maxdepth 0 2> /dev/null)"
+ fi
+ echo "$res"
+}
+
+remote_pkill() {
+ local what="$1"
+ adb shell "for i in $(pid $what); do kill \$i; done"
+}
+
+# Main entry point
+if [[ $# -eq 0 ]]; then
+ usage
+ exit 1
+else
+ parse_arguments "$@"
+
+ # if we do not have have package exit early with an error
+ [[ "$package" == "" ]] && echo "--package not specified" 1>&2 && exit 1
+
+ if [[ $mode != "cold" && $mode != "warm" ]]; then
+ needs_trace_file="y"
+ if [[ -z "$input_file" ]] || ! [[ -f $input_file ]]; then
+ echo "--input not specified" 1>&2
+ exit 1
+ fi
+ fi
+
+ if [[ "$activity" == "" ]]; then
+ activity="$(get_activity_name "$package")"
+ if [[ "$activity" == "" ]]; then
+ echo "Activity name could not be found, invalid package name?" 1>&2
+ exit 1
+ else
+ verbose_print "Activity name inferred: " "$activity"
+ fi
+ fi
+fi
+
+adb root > /dev/null
+
+if [[ ($when == jit) || ($when == aot) ]] && [[ "$(adb shell getenforce)" != "Permissive" ]]; then
+ echo "Disable selinux permissions and restart framework."
+ adb shell setenforce 0
+ adb shell stop
+ adb shell start
+ adb wait-for-device
+fi
+
+# TODO: set performance governor etc, preferrably only once
+# before every single app run.
+
+# Kill everything before running.
+remote_pkill "$package"
+sleep 1
+
+timings_array=()
+
+package_path="$(find_package_path "$package")"
+if [[ $? -ne 0 ]]; then
+ echo "Failed to detect package path for '$package'" >&2
+ exit 1
+fi
+verbose_print "Package was in path '$package_path'"
+
+
+
+
+keep_application_trace_file=n
+application_trace_file_path="$package_path/TraceFile.pb"
+trace_file_directory="$package_path"
+if [[ $needs_trace_file == y ]]; then
+ # system server always passes down the package path in a hardcoded spot.
+ if [[ $when == "jit" ]]; then
+ verbose_print adb push "$input_file" "$application_trace_file_path"
+ adb push "$input_file" "$application_trace_file_path"
+ keep_application_trace_file="y"
+ else
+ # otherwise use a temporary directory to get normal non-jit behavior.
+ trace_file_directory="/data/local/tmp/prefetch/$package"
+ adb shell mkdir -p "$trace_file_directory"
+ verbose_print adb push "$input_file" "$trace_file_directory/TraceFile.pb"
+ adb push "$input_file" "$trace_file_directory/TraceFile.pb"
+ fi
+fi
+
+# Everything other than JIT: remove the trace file,
+# otherwise system server activity hints will kick in
+# and the new just-in-time app pre-warmup will happen.
+if [[ $keep_application_trace_file == "n" ]]; then
+ adb shell "[[ -f '$application_trace_file_path' ]] && rm '$application_trace_file_path'"
+fi
+
+# Perform AOT readahead/pinning/etc when an application is about to be launched.
+# For JIT readahead, we allow the system to handle it itself (this is a no-op).
+#
+# For warm, cold, etc modes which don't need readahead this is always a no-op.
+perform_aot() {
+ local the_when="$1" # user: aot, jit
+ local the_mode="$2" # warm, cold, fadvise, mlock, etc.
+
+ if [[ $the_when != "aot" ]]; then
+ # TODO: just in time implementation.. should probably use system server.
+ return 0
+ fi
+
+ # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
+ if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
+
+ # TODO: add activity_hint_sender.exp
+ verbose_print "starting with package=$package package_path=$trace_file_directory"
+ coproc hint_sender_fd { $ANDROID_BUILD_TOP/system/iorap/src/sh/activity_hint_sender.exp "$package" "$trace_file_directory" "$the_mode"; }
+ hint_sender_pid=$!
+ verbose_print "Activity hint sender began"
+
+ notification_success="n"
+ while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
+ verbose_print "$hint_sender_output"
+ if [[ "$hint_sender_output" == "Press any key to send completed event..."* ]]; then
+ verbose_print "WE DID SEE NOTIFICATION SUCCESS."
+ notification_success='y'
+ # Give it some time to actually perform the readaheads.
+ sleep $sleep_time
+ break
+ fi
+ done
+
+ if [[ $notification_success == 'n' ]]; then
+ echo "[FATAL] Activity hint notification failed." 1>&2
+ exit 1
+ fi
+ fi
+}
+
+perform_aot_cleanup() {
+ local the_when="$1" # user: aot, jit
+ local the_mode="$2" # warm, cold, fadvise, mlock, etc.
+
+ if [[ $the_when != "aot" ]]; then
+ # TODO: just in time implementation.. should probably use system server.
+ return 0
+ fi
+
+ # any non-warm/non-cold modes should use the iorap-activity-hint wrapper script.
+ if [[ $the_mode != 'warm' && $the_mode != 'cold' ]]; then
+ # Clean up the hint sender by telling it that the launch was completed,
+ # and to shutdown the watcher.
+ echo "Done\n" >&"${hint_sender_fd[1]}"
+
+ while read -r -u "${hint_sender_fd[0]}" hint_sender_output; do
+ verbose_print "$hint_sender_output"
+ done
+
+ wait $hint_sender_pid
+ fi
+}
+
+# TODO: This loop logic could probably be moved into app_startup_runner.py
+for ((i=0;i<count;++i)) do
+ verbose_print "=========================================="
+ verbose_print "==== ITERATION $i ===="
+ verbose_print "=========================================="
+ if [[ $mode != "warm" ]]; then
+ verbose_print "Drop caches for non-warm start."
+ # Drop all caches to get cold starts.
+ adb shell "echo 3 > /proc/sys/vm/drop_caches"
+ fi
+
+ perform_aot "$when" "$mode"
+
+ verbose_print "Running with timeout $timeout"
+
+ # TODO: multiple metrics output.
+ total_time="$(timeout $timeout $DIR/launch_application "$package" "$activity")"
+
+ if [[ $? -ne 0 ]]; then
+ echo "WARNING: Skip bad result, try iteration again." >&2
+ ((i=i-1))
+ continue
+ fi
+
+ perform_aot_cleanup "$when" "$mode"
+
+ echo "Iteration $i. Total time was: $total_time"
+
+ timings_array+=($total_time)
+done
+
+# drop the first result which is usually garbage.
+timings_array=("${timings_array[@]:1}")
+
+
+# Print out interactive/debugging timings and averages.
+# Other scripts should use the --output flag and parse the CSV.
+for tim in "${timings_array[@]}"; do
+ echo_to_output_file -ne "$tim,"
+done
+echo_to_output_file ""
+
+average_string=$(echo "${timings_array[@]}" | awk '{s+=$0}END{print "Average:",s/NR}' RS=" ")
+echo -ne ${average_string}.
+if [[ x$output != x ]]; then
+ echo " Saved results to '$output'"
+fi
+
+# Temporary hack around multiple activities being launched with different package paths (for same app):
+# Clean up all left-over TraceFile.pb
+adb shell 'for i in $(find /data/app -name TraceFile.pb); do rm \$i; done'
+
+# Kill the process to ensure AM isn't keeping it around.
+remote_pkill "$package"
+
+exit 0
diff --git a/core/tests/webkit/apk_with_native_libs/jni/Android.mk b/startop/scripts/app_startup/unlock_screen
index fd5b5eb50c5f..478294c9f35d 100644..100755
--- a/core/tests/webkit/apk_with_native_libs/jni/Android.mk
+++ b/startop/scripts/app_startup/unlock_screen
@@ -1,32 +1,22 @@
+#!/bin/bash
#
-# Copyright (C) 2017 The Android Open Source Project
+# Copyright 2018, 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
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-#
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libwebviewtest_jni
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := WebViewTestJniOnLoad.cpp
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_MULTILIB := both
-
-include $(BUILD_SHARED_LIBRARY)
+# This turns the screen on if it's off.
+# If it's on it does nothing unless its on the home screen, in which case it opens up some background
+# menu.
+#
+# However, this menu is ignored because "am start" commands still work as expected.
+adb shell input keyevent MENU
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1d9e6052a31c..8ebfec47c4ea 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1589,12 +1589,14 @@ public class SubscriptionManager {
}
/**
- * @return true if a valid subId else false
- * @hide
+ * Checks if the supplied subscription ID is valid.
+ * Note: a valid subscription ID does not necessarily correspond to an active subscription.
+ *
+ * @param subscriptionId The subscription ID.
+ * @return true if the supplied subscriptionId is valid; false otherwise.
*/
- @UnsupportedAppUsage
- public static boolean isValidSubscriptionId(int subId) {
- return subId > INVALID_SUBSCRIPTION_ID ;
+ public static boolean isValidSubscriptionId(int subscriptionId) {
+ return subscriptionId > INVALID_SUBSCRIPTION_ID;
}
/**
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 102cb7c77055..99a5a69213fa 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -41,9 +41,9 @@ import android.net.Network;
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.ParcelFileDescriptor;
-import android.test.mock.MockContext;
import android.support.test.filters.SmallTest;
import android.system.Os;
+import android.test.mock.MockContext;
import java.net.Socket;
import java.util.Arrays;
@@ -121,6 +121,7 @@ public class IpSecServiceParameterizedTest {
IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
IpSecService mIpSecService;
Network fakeNetwork = new Network(0xAB);
+ int mUid = Os.getuid();
private static final IpSecAlgorithm AUTH_ALGO =
new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA256, AUTH_KEY, AUTH_KEY.length * 4);
@@ -181,7 +182,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecDeleteSecurityAssociation(
- eq(spiResp.resourceId),
+ eq(mUid),
anyString(),
anyString(),
eq(TEST_SPI),
@@ -189,8 +190,7 @@ public class IpSecServiceParameterizedTest {
anyInt());
// Verify quota and RefcountedResource objects cleaned up
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
assertEquals(0, userRecord.mSpiQuotaTracker.mCurrent);
try {
userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
@@ -209,8 +209,7 @@ public class IpSecServiceParameterizedTest {
mIpSecService.allocateSecurityParameterIndex(
mDestinationAddr, TEST_SPI, new Binder());
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
userRecord.mSpiRecords.getRefcountedResourceOrThrow(spiResp.resourceId);
@@ -218,7 +217,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecDeleteSecurityAssociation(
- eq(spiResp.resourceId),
+ eq(mUid),
anyString(),
anyString(),
eq(TEST_SPI),
@@ -270,7 +269,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecAddSecurityAssociation(
- eq(createTransformResp.resourceId),
+ eq(mUid),
anyInt(),
anyString(),
anyString(),
@@ -305,7 +304,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecAddSecurityAssociation(
- eq(createTransformResp.resourceId),
+ eq(mUid),
anyInt(),
anyString(),
anyString(),
@@ -361,13 +360,12 @@ public class IpSecServiceParameterizedTest {
IpSecTransformResponse createTransformResp =
mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
mIpSecService.releaseSecurityParameterIndex(ipSecConfig.getSpiResourceId());
verify(mMockNetd, times(0))
.ipSecDeleteSecurityAssociation(
- eq(createTransformResp.resourceId),
+ eq(mUid),
anyString(),
anyString(),
eq(TEST_SPI),
@@ -389,7 +387,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd, times(1))
.ipSecDeleteSecurityAssociation(
- eq(createTransformResp.resourceId),
+ eq(mUid),
anyString(),
anyString(),
eq(TEST_SPI),
@@ -397,8 +395,7 @@ public class IpSecServiceParameterizedTest {
anyInt());
// Verify quota and RefcountedResource objects cleaned up
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
assertEquals(0, userRecord.mTransformQuotaTracker.mCurrent);
assertEquals(1, userRecord.mSpiQuotaTracker.mCurrent);
@@ -433,8 +430,7 @@ public class IpSecServiceParameterizedTest {
IpSecTransformResponse createTransformResp =
mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
userRecord.mTransformRecords.getRefcountedResourceOrThrow(
createTransformResp.resourceId);
@@ -443,7 +439,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecDeleteSecurityAssociation(
- eq(createTransformResp.resourceId),
+ eq(mUid),
anyString(),
anyString(),
eq(TEST_SPI),
@@ -477,7 +473,7 @@ public class IpSecServiceParameterizedTest {
verify(mMockNetd)
.ipSecApplyTransportModeTransform(
eq(pfd.getFileDescriptor()),
- eq(resourceId),
+ eq(mUid),
eq(IpSecManager.DIRECTION_OUT),
anyString(),
anyString(),
@@ -509,8 +505,7 @@ public class IpSecServiceParameterizedTest {
createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
// Check that we have stored the tracking object, and retrieve it
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
createTunnelResp.resourceId);
@@ -530,8 +525,7 @@ public class IpSecServiceParameterizedTest {
IpSecTunnelInterfaceResponse createTunnelResp =
createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
mIpSecService.deleteTunnelInterface(createTunnelResp.resourceId, "blessedPackage");
@@ -551,8 +545,7 @@ public class IpSecServiceParameterizedTest {
IpSecTunnelInterfaceResponse createTunnelResp =
createAndValidateTunnel(mSourceAddr, mDestinationAddr, "blessedPackage");
- IpSecService.UserRecord userRecord =
- mIpSecService.mUserResourceTracker.getUserRecord(Os.getuid());
+ IpSecService.UserRecord userRecord = mIpSecService.mUserResourceTracker.getUserRecord(mUid);
IpSecService.RefcountedResource refcountedRecord =
userRecord.mTunnelInterfaceRecords.getRefcountedResourceOrThrow(
createTunnelResp.resourceId);
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index 29bf74c7a8b9..e50c70d0656a 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -1,18 +1,24 @@
#!/bin/bash
-LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
+LOCAL_DIR="$( dirname "${BASH_SOURCE}" )"
-if git branch -vv | grep "^*" | grep "\[aosp/master" > /dev/null; then
+if git branch -vv | grep -q -P "^\*[^\[]+\[aosp/"; then
# Change appears to be in AOSP
exit 0
else
# Change appears to be non-AOSP; search for files
- git show --name-only --pretty=format: $1 | grep $2 | while read file; do
- echo
+ count=0
+ while read -r file ; do
+ if (( count == 0 )); then
+ echo
+ fi
echo -e "\033[0;31mThe source of truth for '$file' is in AOSP.\033[0m"
+ (( count++ ))
+ done < <(git show --name-only --pretty=format: $1 | grep -- "$2")
+ if (( count != 0 )); then
echo
- echo "If your change contains no confidential details, please upload and merge"
- echo "this change at https://android-review.googlesource.com/."
+ echo "If your change contains no confidential details (such as security fixes), please"
+ echo "upload and merge this change at https://android-review.googlesource.com/."
echo
exit 77
- done
+ fi
fi