diff options
93 files changed, 1509 insertions, 890 deletions
diff --git a/Android.bp b/Android.bp index 03abf7563137..e65ba0f6a95f 100644 --- a/Android.bp +++ b/Android.bp @@ -249,8 +249,7 @@ java_library { "core/java/android/os/storage/IStorageEventListener.aidl", "core/java/android/os/storage/IStorageShutdownObserver.aidl", "core/java/android/os/storage/IObbActionListener.aidl", - "core/java/android/security/IConfirmationPromptCallback.aidl", - "core/java/android/security/IKeystoreService.aidl", + ":keystore_aidl", "core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl", "core/java/android/service/autofill/IAutoFillService.aidl", "core/java/android/service/autofill/IAutofillFieldClassificationService.aidl", @@ -643,6 +642,7 @@ java_library { "system/netd/server/binder", "system/vold/binder", "system/bt/binder", + "system/security/keystore/binder", ], }, diff --git a/api/current.txt b/api/current.txt index 042360e6ff1b..53f503a59ecb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1468,6 +1468,7 @@ package android { field public static final deprecated int unfocusedMonthDateColor = 16843588; // 0x1010344 field public static final int unselectedAlpha = 16843278; // 0x101020e field public static final int updatePeriodMillis = 16843344; // 0x1010250 + field public static final int urlBarResourceId = 16844164; // 0x1010584 field public static final int use32bitAbi = 16844053; // 0x1010515 field public static final int useDefaultMargins = 16843641; // 0x1010379 field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310 @@ -12554,6 +12555,7 @@ package android.database.sqlite { method public abstract void onUpgrade(android.database.sqlite.SQLiteDatabase, int, int); method public void setIdleConnectionTimeout(long); method public void setLookasideConfig(int, int); + method public void setOpenParams(android.database.sqlite.SQLiteDatabase.OpenParams); method public void setWriteAheadLoggingEnabled(boolean); } diff --git a/api/system-current.txt b/api/system-current.txt index 39cbe90894ee..5afb455d9640 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -229,7 +229,6 @@ package android.app { method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions); method public deprecated boolean isBackgroundVisibleBehind(); method public deprecated void onBackgroundVisibleBehindChanged(boolean); - method public void setDisablePreviewScreenshots(boolean); } public static abstract interface Activity.TranslucentConversionListener { @@ -3606,11 +3605,14 @@ package android.os { } public abstract class HwBinder implements android.os.IHwBinder { + ctor public HwBinder(); method public static final void configureRpcThreadpool(long, boolean); method public static void enableInstrumentation(); method public static final android.os.IHwBinder getService(java.lang.String, java.lang.String) throws java.util.NoSuchElementException, android.os.RemoteException; method public static final android.os.IHwBinder getService(java.lang.String, java.lang.String, boolean) throws java.util.NoSuchElementException, android.os.RemoteException; method public static final void joinRpcThreadpool(); + method public abstract void onTransact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException; + method public final void registerService(java.lang.String) throws android.os.RemoteException; method public final void transact(int, android.os.HwParcel, android.os.HwParcel, int) throws android.os.RemoteException; } diff --git a/api/test-current.txt b/api/test-current.txt index b02da04bbcd1..eda6296fb39a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1047,6 +1047,15 @@ package android.view.accessibility { } +package android.view.animation { + + public class AnimationUtils { + method public static void lockAnimationClock(long); + method public static void unlockAnimationClock(); + } + +} + package android.view.autofill { public final class AutofillId implements android.os.Parcelable { diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 67b9089c8315..740fdc0af5f1 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -116,10 +116,8 @@ LOCAL_SRC_FILES := \ LOCAL_CFLAGS += \ -Wall \ + -Wextra \ -Werror \ - -Wno-missing-field-initializers \ - -Wno-unused-variable \ - -Wno-unused-function \ -Wno-unused-parameter ifeq (debug,) diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp index 7b0b69a4bcae..6894bcf53e79 100644 --- a/cmds/statsd/src/FieldValue.cpp +++ b/cmds/statsd/src/FieldValue.cpp @@ -23,6 +23,23 @@ namespace android { namespace os { namespace statsd { +int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) { + int32_t field = 0; + for (int32_t i = 0; i <= depth; i++) { + int32_t shiftBits = 8 * (kMaxLogDepth - i); + field |= (pos[i] << shiftBits); + } + + if (includeDepth) { + field |= (depth << 24); + } + return field; +} + +int32_t encodeMatcherMask(int32_t mask[], int32_t depth) { + return getEncodedField(mask, depth, false) | 0xff000000; +} + bool Field::matches(const Matcher& matcher) const { if (mTag != matcher.mMatcher.getTag()) { return false; @@ -32,7 +49,7 @@ bool Field::matches(const Matcher& matcher) const { } return false; -}; +} void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask, std::vector<Matcher>* output) { @@ -71,7 +88,6 @@ void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* if (matcher.child_size() == 0) { output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth))); - Matcher matcher = Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)); } else { for (const auto& child : matcher.child()) { translateFieldMatcher(tag, child, depth + 1, pos, mask, output); diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index 7484108d9e1a..d17dded8d691 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -33,29 +33,14 @@ const int32_t kClearLastBitDeco = 0x7f; enum Type { INT, LONG, FLOAT, STRING }; +int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth); -static int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) { - int32_t field = 0; - for (int32_t i = 0; i <= depth; i++) { - int32_t shiftBits = 8 * (kMaxLogDepth - i); - field |= (pos[i] << shiftBits); - } - - if (includeDepth) { - field |= (depth << 24); - } - return field; -} - -static int32_t encodeMatcherMask(int32_t mask[], int32_t depth) { - return getEncodedField(mask, depth, false) | 0xff000000; -} +int32_t encodeMatcherMask(int32_t mask[], int32_t depth); // Get the encoded field for a leaf with a [field] number at depth 0; -static int32_t getSimpleField(size_t field) { +inline int32_t getSimpleField(size_t field) { return ((int32_t)field << 8 * 2); } - /** * Field is a wrapper class for 2 integers that represents the field of a log element in its Atom * proto. diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp index 68e2176c2e6d..d901bd669591 100644 --- a/cmds/statsd/src/HashableDimensionKey.cpp +++ b/cmds/statsd/src/HashableDimensionKey.cpp @@ -68,7 +68,6 @@ bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue> for (const auto& value : values) { // TODO: potential optimization here to break early because all fields are naturally // sorted. - int32_t filteredField; if (value.mField.matches(matcher)) { matchedResults.push_back(FieldValue( Field(value.mField.getTag(), (value.mField.getField() & matcher.mMask)), @@ -148,7 +147,6 @@ void filterGaugeValues(const std::vector<Matcher>& matcherFields, const std::vector<FieldValue>& values, std::vector<FieldValue>* output) { for (const auto& field : matcherFields) { for (const auto& value : values) { - int filteredField; if (value.mField.matches(field)) { output->push_back(value); } diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index afb2c4782fac..87dec5d1656d 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -58,7 +58,7 @@ const int FIELD_ID_REPORTS = 2; const int FIELD_ID_UID = 1; const int FIELD_ID_ID = 2; // for ConfigMetricsReport -const int FIELD_ID_METRICS = 1; +// const int FIELD_ID_METRICS = 1; // written in MetricsManager.cpp const int FIELD_ID_UID_MAP = 2; const int FIELD_ID_LAST_REPORT_ELAPSED_NANOS = 3; const int FIELD_ID_CURRENT_REPORT_ELAPSED_NANOS = 4; diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index bb47653f03b0..0a4e412bff20 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -124,8 +124,6 @@ void StatsService::init_build_type_callback(void* cookie, const char* /*name*/, */ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - status_t err; - switch (code) { case SHELL_COMMAND_TRANSACTION: { int in = data.readFileDescriptor(); @@ -240,8 +238,8 @@ status_t StatsService::command(FILE* in, FILE* out, FILE* err, Vector<String8>& return cmd_write_data_to_disk(out); } - if (!args[0].compare(String8("log-app-hook"))) { - return cmd_log_app_hook(out, args); + if (!args[0].compare(String8("log-app-breadcrumb"))) { + return cmd_log_app_breadcrumb(out, args); } if (!args[0].compare(String8("clear-puller-cache"))) { @@ -284,8 +282,8 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, " Flushes all data on memory to disk.\n"); fprintf(out, "\n"); fprintf(out, "\n"); - fprintf(out, "usage: adb shell cmd stats log-app-hook [UID] LABEL STATE\n"); - fprintf(out, " Writes an AppHook event to the statslog buffer.\n"); + fprintf(out, "usage: adb shell cmd stats log-app-breadcrumb [UID] LABEL STATE\n"); + fprintf(out, " Writes an AppBreadcrumbReported event to the statslog buffer.\n"); fprintf(out, " UID The uid to use. It is only possible to pass a UID\n"); fprintf(out, " parameter on eng builds. If UID is omitted the calling\n"); fprintf(out, " uid is used.\n"); @@ -551,7 +549,7 @@ status_t StatsService::cmd_write_data_to_disk(FILE* out) { return NO_ERROR; } -status_t StatsService::cmd_log_app_hook(FILE* out, const Vector<String8>& args) { +status_t StatsService::cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& args) { bool good = false; int32_t uid; int32_t label; @@ -573,13 +571,13 @@ status_t StatsService::cmd_log_app_hook(FILE* out, const Vector<String8>& args) good = true; } else { fprintf(out, - "Selecting a UID for writing AppHook can only be dumped for other UIDs on eng" + "Selecting a UID for writing Appbreadcrumb can only be dumped for other UIDs on eng" " or userdebug builds.\n"); } } if (good) { - fprintf(out, "Logging AppHook(%d, %d, %d) to statslog.\n", uid, label, state); - android::util::stats_write(android::util::APP_HOOK, uid, label, state); + fprintf(out, "Logging AppBreadcrumbReported(%d, %d, %d) to statslog.\n", uid, label, state); + android::util::stats_write(android::util::APP_BREADCRUMB_REPORTED, uid, label, state); } else { print_cmd_help(out); return UNKNOWN_ERROR; diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 3dc19fe08d94..fd658690435e 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -193,9 +193,10 @@ private: status_t cmd_write_data_to_disk(FILE* out); /** - * Write an AppHook event to the StatsLog buffer, as though StatsLog.write(APP_HOOK). + * Write an AppBreadcrumbReported event to the StatsLog buffer, as though StatsLog.write + * (APP_BREADCRUMB_REPORTED). */ - status_t cmd_log_app_hook(FILE* out, const Vector<String8>& args); + status_t cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& args); /** * Print contents of a pulled metrics source. diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 4c6a36bd9270..1224504c6703 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -85,7 +85,7 @@ message Atom { PacketWakeupOccurred packet_wakeup_occurred = 44; DropboxErrorChanged dropbox_error_changed = 45; AnomalyDetected anomaly_detected = 46; - AppHook app_hook = 47; + AppBreadcrumbReported app_breadcrumb_reported = 47; AppStartChanged app_start_changed = 48; AppStartCancelChanged app_start_cancel_changed = 49; AppStartFullyDrawnChanged app_start_fully_drawn_changed = 50; @@ -202,9 +202,10 @@ message UidProcessStateChanged { * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java */ message ProcessLifeCycleStateChanged { - optional int32 uid = 1; // TODO: should be a string tagged w/ uid annotation + // TODO: should be a string tagged w/ uid annotation + optional int32 uid = 1; - // TODO: What is this? + // The process name (usually same as the app name). optional string name = 2; // What lifecycle state the process changed to. @@ -312,7 +313,7 @@ message GpsScanStateChanged { message SyncStateChanged { repeated AttributionNode attribution_node = 1; - // Name of the sync (as named in the app) + // Name of the sync (as named in the app). Can be chosen at run-time. optional string name = 2; enum State { @@ -615,7 +616,7 @@ message KernelWakeupReported { optional string wakeup_reason_name = 1; // Duration (in microseconds) for the wake-up interrupt to be serviced. - optional int64 duration_usec = 2; + optional int64 duration_micros = 2; } /** @@ -692,10 +693,10 @@ message ShutdownSequenceReported { // Beginning of shutdown time in ms using wall clock time since unix epoch. // Default: 0 if no start time received. - optional int64 start_time_ms = 3; + optional int64 start_time_millis = 3; // Duration of shutdown in ms. Default: 0 if no duration received. - optional int64 duration_ms = 4; + optional int64 duration_millis = 4; } @@ -715,13 +716,13 @@ message BootSequenceReported { optional string system_reason = 2; // End of boot time in ms from unix epoch using system wall clock. - optional int64 end_time_ms = 3; + optional int64 end_time_millis = 3; // Total boot duration in ms. - optional int64 total_duration_ms = 4; + optional int64 total_duration_millis = 4; // Bootloader duration in ms. - optional int64 bootloader_duration_ms = 5; + optional int64 bootloader_duration_millis = 5; // Time since last boot in ms. Default: 0 if not available. optional int64 time_since_last_boot = 6; @@ -762,7 +763,7 @@ message CallStateChanged { */ message DaveyOccurred { // Amount of time it took to render the frame. Should be >=700ms. - optional int64 jank_duration_ms = 1; + optional int64 jank_duration_millis = 1; } /** @@ -863,7 +864,7 @@ message DropboxErrorChanged { * Logged from: * frameworks/base/core/java/android/util/StatsLog.java */ -message AppHook { +message AppBreadcrumbReported { // The uid of the application that sent this custom atom. optional int32 uid = 1; @@ -924,16 +925,16 @@ message AppStartChanged { optional bool is_instant_app = 6; // Device uptime when activity started. - optional int64 activity_start_msec = 7; + optional int64 activity_start_millis = 7; optional android.app.AppTransitionReasonEnum reason = 8; - optional int32 transition_delay_msec = 9; + optional int32 transition_delay_millis = 9; // -1 if not set. - optional int32 starting_window_delay_msec = 10; + optional int32 starting_window_delay_millis = 10; // -1 if not set. - optional int32 bind_application_delay_msec = 11; - optional int32 windows_drawn_delay_msec = 12; + optional int32 bind_application_delay_millis = 11; + optional int32 windows_drawn_delay_millis = 12; // Empty if not set. optional string launch_token = 13; @@ -981,7 +982,7 @@ message AppStartFullyDrawnChanged { optional bool transition_process_running = 5; // App startup time (until call to Activity#reportFullyDrawn()). - optional int64 app_startup_time_ms = 6; + optional int64 app_startup_time_millis = 6; } /** @@ -1303,7 +1304,7 @@ message SubsystemSleepState { // The number of times it entered, or voted for entering the sleep state optional uint64 count = 3; // The length of time spent in, or spent voting for, the sleep state - optional uint64 timeMs = 4; + optional uint64 time_millis = 4; } /** @@ -1316,7 +1317,7 @@ message SubsystemSleepState { message CpuTimePerFreq { optional uint32 cluster = 1; optional uint32 freq_index = 2; - optional uint64 time_ms = 3; + optional uint64 time_millis = 3; } /** @@ -1325,8 +1326,8 @@ message CpuTimePerFreq { */ message CpuTimePerUid { optional uint64 uid = 1; - optional uint64 user_time_ms = 2; - optional uint64 sys_time_ms = 3; + optional uint64 user_time_millis = 2; + optional uint64 sys_time_millis = 3; } /** @@ -1337,7 +1338,7 @@ message CpuTimePerUid { message CpuTimePerUidFreq { optional uint64 uid = 1; optional uint64 freq_idx = 2; - optional uint64 time_ms = 3; + optional uint64 time_millis = 3; } /** @@ -1345,16 +1346,16 @@ message CpuTimePerUidFreq { */ message WifiActivityEnergyInfo { // timestamp(wall clock) of record creation - optional uint64 timestamp_ms = 1; + optional uint64 timestamp_millis = 1; // stack reported state // TODO: replace this with proto enum optional int32 stack_state = 2; // tx time in ms - optional uint64 controller_tx_time_ms = 3; + optional uint64 controller_tx_time_millis = 3; // rx time in ms - optional uint64 controller_rx_time_ms = 4; + optional uint64 controller_rx_time_millis = 4; // idle time in ms - optional uint64 controller_idle_time_ms = 5; + optional uint64 controller_idle_time_millis = 5; // product of current(mA), voltage(V) and time(ms) optional uint64 controller_energy_used = 6; } @@ -1364,11 +1365,11 @@ message WifiActivityEnergyInfo { */ message ModemActivityInfo { // timestamp(wall clock) of record creation - optional uint64 timestamp_ms = 1; + optional uint64 timestamp_millis = 1; // sleep time in ms. - optional uint64 sleep_time_ms = 2; + optional uint64 sleep_time_millis = 2; // idle time in ms - optional uint64 controller_idle_time_ms = 3; + optional uint64 controller_idle_time_millis = 3; /** * Tx power index * index 0 = tx_power < 0dBm @@ -1378,17 +1379,17 @@ message ModemActivityInfo { * index 4 = tx_power > 20dBm */ // tx time in ms at power level 0 - optional uint64 controller_tx_time_pl0_ms = 4; + optional uint64 controller_tx_time_pl0_millis = 4; // tx time in ms at power level 1 - optional uint64 controller_tx_time_pl1_ms = 5; + optional uint64 controller_tx_time_pl1_millis = 5; // tx time in ms at power level 2 - optional uint64 controller_tx_time_pl2_ms = 6; + optional uint64 controller_tx_time_pl2_millis = 6; // tx time in ms at power level 3 - optional uint64 controller_tx_time_pl3_ms = 7; + optional uint64 controller_tx_time_pl3_millis = 7; // tx time in ms at power level 4 - optional uint64 controller_tx_time_pl4_ms = 8; + optional uint64 controller_tx_time_pl4_millis = 8; // rx time in ms at power level 5 - optional uint64 controller_rx_time_ms = 9; + optional uint64 controller_rx_time_millis = 9; // product of current(mA), voltage(V) and time(ms) optional uint64 energy_used = 10; } @@ -1399,15 +1400,15 @@ message ModemActivityInfo { */ message BluetoothActivityInfo { // timestamp(wall clock) of record creation - optional uint64 timestamp_ms = 1; + optional uint64 timestamp_millis = 1; // bluetooth stack state optional int32 bluetooth_stack_state = 2; // tx time in ms - optional uint64 controller_tx_time_ms = 3; + optional uint64 controller_tx_time_millis = 3; // rx time in ms - optional uint64 controller_rx_time_ms = 4; + optional uint64 controller_rx_time_millis = 4; // idle time in ms - optional uint64 controller_idle_time_ms = 5; + optional uint64 controller_idle_time_millis = 5; // product of current(mA), voltage(V) and time(ms) optional uint64 energy_used = 6; } @@ -1445,7 +1446,7 @@ message ProcessMemoryState { * Elapsed real time from SystemClock. */ message SystemElapsedRealtime { - optional uint64 time_ms = 1; + optional uint64 time_millis = 1; } /* @@ -1456,7 +1457,7 @@ message SystemUptime { // This clock stops when the system enters deep sleep (CPU off, display dark, device waiting // for external input). // It is not affected by clock scaling, idle, or other power saving mechanisms. - optional uint64 uptime_ms = 1; + optional uint64 uptime_millis = 1; } /* @@ -1470,8 +1471,9 @@ message SystemUptime { */ message CpuActiveTime { optional uint64 uid = 1; - optional uint64 idx = 2; - optional uint64 time_ms = 3; + optional uint32 cluster_number =2; + optional uint64 idx = 3; + optional uint64 time_millis = 4; } /** @@ -1486,7 +1488,7 @@ message CpuActiveTime { message CpuClusterTime { optional uint64 uid = 1; optional uint64 idx = 2; - optional uint64 time_ms = 3; + optional uint64 time_millis = 3; } /* diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index e2e94263ed8f..66cb1d04a4e1 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -45,18 +45,9 @@ const int FIELD_ID_CONFIG_STATS = 3; const int FIELD_ID_ATOM_STATS = 7; const int FIELD_ID_UIDMAP_STATS = 8; const int FIELD_ID_ANOMALY_ALARM_STATS = 9; -const int FIELD_ID_PULLED_ATOM_STATS = 10; +// const int FIELD_ID_PULLED_ATOM_STATS = 10; // The proto is written in stats_log_util.cpp const int FIELD_ID_LOGGER_ERROR_STATS = 11; -const int FIELD_ID_MATCHER_STATS_NAME = 1; -const int FIELD_ID_MATCHER_STATS_COUNT = 2; - -const int FIELD_ID_CONDITION_STATS_NAME = 1; -const int FIELD_ID_CONDITION_STATS_COUNT = 2; - -const int FIELD_ID_METRIC_STATS_NAME = 1; -const int FIELD_ID_METRIC_STATS_COUNT = 2; - const int FIELD_ID_ATOM_STATS_TAG = 1; const int FIELD_ID_ATOM_STATS_COUNT = 2; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 7489d9b72e94..f07fc66dbcbb 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -178,10 +178,6 @@ bool LogEvent::write(const AttributionNode& node) { void LogEvent::init(android_log_context context) { android_log_list_element elem; int i = 0; - - int seenListStart = 0; - - int32_t field = 0; int depth = -1; int pos[] = {1, 1, 1}; do { diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index af22578cc758..67d95dbd4cc5 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -150,10 +150,9 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eve std::unordered_set<HashableDimensionKey> conditionDimensionsKeySet; - ConditionState conditionState = mWizard->getMetConditionDimension( - mConditionTrackerIndex, mDimensionsInCondition, &conditionDimensionsKeySet); + mWizard->getMetConditionDimension(mConditionTrackerIndex, mDimensionsInCondition, + &conditionDimensionsKeySet); - bool condition = (conditionState == ConditionState::kTrue); for (auto& pair : mCurrentSlicedDurationTrackerMap) { conditionDimensionsKeySet.erase(pair.first.getDimensionKeyInCondition()); } diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index af3b4c5a648a..8aa816938c0d 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -334,7 +334,6 @@ void GaugeMetricProducer::onMatchedLogEventInternalLocked( } void GaugeMetricProducer::updateCurrentSlicedBucketForAnomaly() { - status_t err = NO_ERROR; for (const auto& slice : *mCurrentSlicedBucket) { if (slice.second.empty()) { continue; diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index ae48c522363a..66e1aeb8f43e 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -188,7 +188,7 @@ void MetricsManager::onLogEvent(const LogEvent& event) { return; } - if (event.GetTagId() == android::util::APP_HOOK) { // Check that app hook fields are valid. + if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) { // Check that app hook fields are valid. // TODO: Find a way to make these checks easier to maintain if the app hooks get changed. status_t err = NO_ERROR; diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp index c29876b5eae0..95df5ae6e8bd 100644 --- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp +++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp @@ -177,7 +177,6 @@ bool MaxDurationTracker::flushCurrentBucket( false; // has either a kStarted or kPaused event across bucket boundaries // meaning we need to carry them over to the new bucket. for (auto it = mInfos.begin(); it != mInfos.end(); ++it) { - int64_t finalDuration = it->second.lastDuration; if (it->second.state == DurationState::kStopped) { // No need to keep buckets for events that were stopped before. mInfos.erase(it); diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp index e73577041f75..f7b768f5f2b2 100644 --- a/cmds/statsd/src/stats_log_util.cpp +++ b/cmds/statsd/src/stats_log_util.cpp @@ -41,15 +41,12 @@ const int DIMENSIONS_VALUE_FIELD = 1; const int DIMENSIONS_VALUE_VALUE_STR = 2; const int DIMENSIONS_VALUE_VALUE_INT = 3; const int DIMENSIONS_VALUE_VALUE_LONG = 4; -const int DIMENSIONS_VALUE_VALUE_BOOL = 5; +// const int DIMENSIONS_VALUE_VALUE_BOOL = 5; // logd doesn't have bool data type. const int DIMENSIONS_VALUE_VALUE_FLOAT = 6; const int DIMENSIONS_VALUE_VALUE_TUPLE = 7; const int DIMENSIONS_VALUE_TUPLE_VALUE = 1; -// for MessageValue Proto -const int FIELD_ID_FIELD_VALUE_IN_MESSAGE_VALUE_PROTO = 1; - // for PulledAtomStats proto const int FIELD_ID_PULLED_ATOM_STATS = 10; const int FIELD_ID_PULL_ATOM_ID = 1; @@ -131,11 +128,6 @@ void writeDimensionToProto(const HashableDimensionKey& dimension, ProtoOutputStr protoOutput->end(topToken); } -// for Field Proto -const int FIELD_FIELD = 1; -const int FIELD_POSITION_INDEX = 2; -const int FIELD_CHILD = 3; - // Supported Atoms format // XYZ_Atom { // repeated SubMsg field_1 = 1; diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp index 674d810a9ea9..6aa7dd64393e 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_test.cpp @@ -161,21 +161,21 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) { EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + bucketSizeNs); EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().type(), AppStartChanged::HOT); EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_name(), "activity_name2"); - EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_msec(), 102L); + EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_millis(), 102L); EXPECT_EQ(data.bucket_info(1).atom_size(), 1); EXPECT_EQ(data.bucket_info(1).start_bucket_nanos(), bucketStartTimeNs + bucketSizeNs); EXPECT_EQ(data.bucket_info(1).end_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().type(), AppStartChanged::WARM); EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().activity_name(), "activity_name4"); - EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().activity_start_msec(), 104L); + EXPECT_EQ(data.bucket_info(1).atom(0).app_start_changed().activity_start_millis(), 104L); EXPECT_EQ(data.bucket_info(2).atom_size(), 1); EXPECT_EQ(data.bucket_info(2).start_bucket_nanos(), bucketStartTimeNs + 2 * bucketSizeNs); EXPECT_EQ(data.bucket_info(2).end_bucket_nanos(), bucketStartTimeNs + 3 * bucketSizeNs); EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().type(), AppStartChanged::COLD); EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().activity_name(), "activity_name5"); - EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().activity_start_msec(), 105L); + EXPECT_EQ(data.bucket_info(2).atom(0).app_start_changed().activity_start_millis(), 105L); data = gaugeMetrics.data(1); @@ -189,7 +189,7 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) { EXPECT_EQ(data.bucket_info(0).end_bucket_nanos(), bucketStartTimeNs + 3 * bucketSizeNs); EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().type(), AppStartChanged::COLD); EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_name(), "activity_name7"); - EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_msec(), 201L); + EXPECT_EQ(data.bucket_info(0).atom(0).app_start_changed().activity_start_millis(), 201L); } #else diff --git a/core/java/Android.bp b/core/java/Android.bp index f7c5c57a07e4..fb27f74211fb 100644 --- a/core/java/Android.bp +++ b/core/java/Android.bp @@ -7,33 +7,3 @@ filegroup { name: "IDropBoxManagerService.aidl", srcs: ["com/android/internal/os/IDropBoxManagerService.aidl"], } - -// only used by key_store_service -cc_library_shared { - name: "libkeystore_aidl", - srcs: ["android/security/IKeystoreService.aidl", - "android/security/IConfirmationPromptCallback.aidl"], - aidl: { - export_aidl_headers: true, - include_dirs: [ - "frameworks/base/core/java/", - "system/security/keystore/", - ], - }, - shared_libs: [ - "libbinder", - "libcutils", - "libhardware", - "libhidlbase", - "libhidltransport", - "libhwbinder", - "liblog", - "libkeystore_parcelables", - "libselinux", - "libutils", - ], - export_shared_lib_headers: [ - "libbinder", - "libkeystore_parcelables", - ], -} diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index bcd88fee6720..3283759d81e0 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -7751,7 +7751,6 @@ public class Activity extends ContextThemeWrapper * @param disable {@code true} to disable preview screenshots; {@code false} otherwise. * @hide */ - @SystemApi public void setDisablePreviewScreenshots(boolean disable) { try { ActivityManager.getService().setDisablePreviewScreenshots(mToken, disable); diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 0f1c249faf83..1312a2e6b623 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -1303,6 +1303,17 @@ public class AssistStructure implements Parcelable { } /** + * @hide + */ + public void setWebDomain(@Nullable String domain) { + if (domain == null) return; + + final Uri uri = Uri.parse(domain); + mWebScheme = uri.getScheme(); + mWebDomain = uri.getHost(); + } + + /** * Returns the scheme of the HTML document represented by this view. * * <p>Typically used when the view associated with the view is a container for an HTML @@ -1889,14 +1900,7 @@ public class AssistStructure implements Parcelable { @Override public void setWebDomain(@Nullable String domain) { - if (domain == null) { - mNode.mWebScheme = null; - mNode.mWebDomain = null; - return; - } - Uri uri = Uri.parse(domain); - mNode.mWebScheme = uri.getScheme(); - mNode.mWebDomain = uri.getHost(); + mNode.setWebDomain(domain); } @Override diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java index a2991e6e9cb6..64e9e5db7c4b 100644 --- a/core/java/android/database/sqlite/SQLiteOpenHelper.java +++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java @@ -58,7 +58,7 @@ public abstract class SQLiteOpenHelper { private SQLiteDatabase mDatabase; private boolean mIsInitializing; - private final SQLiteDatabase.OpenParams.Builder mOpenParamsBuilder; + private SQLiteDatabase.OpenParams.Builder mOpenParamsBuilder; /** * Create a helper object to create, open, and/or manage a database. @@ -163,8 +163,7 @@ public abstract class SQLiteOpenHelper { mName = name; mNewVersion = version; mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion); - mOpenParamsBuilder = openParamsBuilder; - mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY); + setOpenParamsBuilder(openParamsBuilder); } /** @@ -230,6 +229,30 @@ public abstract class SQLiteOpenHelper { } /** + * Sets configuration parameters that are used for opening {@link SQLiteDatabase}. + * <p>Please note that {@link SQLiteDatabase#CREATE_IF_NECESSARY} flag will always be set when + * opening the database + * + * @param openParams configuration parameters that are used for opening {@link SQLiteDatabase}. + * @throws IllegalStateException if the database is already open + */ + public void setOpenParams(@NonNull SQLiteDatabase.OpenParams openParams) { + Preconditions.checkNotNull(openParams); + synchronized (this) { + if (mDatabase != null && mDatabase.isOpen()) { + throw new IllegalStateException( + "OpenParams cannot be set after opening the database"); + } + setOpenParamsBuilder(new SQLiteDatabase.OpenParams.Builder(openParams)); + } + } + + private void setOpenParamsBuilder(SQLiteDatabase.OpenParams.Builder openParamsBuilder) { + mOpenParamsBuilder = openParamsBuilder; + mOpenParamsBuilder.addOpenFlags(SQLiteDatabase.CREATE_IF_NECESSARY); + } + + /** * Sets the maximum number of milliseconds that SQLite connection is allowed to be idle * before it is closed and removed from the pool. * diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 3f8eaa902cb2..8502fc413c05 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -341,7 +341,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri */ @SuppressWarnings({"unchecked"}) public List<CaptureRequest.Key<?>> getAvailablePhysicalCameraRequestKeys() { - if (mAvailableSessionKeys == null) { + if (mAvailablePhysicalRequestKeys == null) { Object crKey = CaptureRequest.Key.class; Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>)crKey; @@ -1790,11 +1790,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * The respective value of such request key can be obtained by calling * {@link CaptureRequest.Builder#getPhysicalCameraKey }. Capture requests that contain * individual physical device requests must be built via - * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}. - * Such extended capture requests can be passed only to - * {@link CameraCaptureSession#capture } or {@link CameraCaptureSession#captureBurst } and - * not to {@link CameraCaptureSession#setRepeatingRequest } or - * {@link CameraCaptureSession#setRepeatingBurst }.</p> + * {@link android.hardware.camera2.CameraDevice#createCaptureRequest(int, Set)}.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Limited capability</b> - * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index fd285aef864f..72db33f90c20 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -863,11 +863,8 @@ public abstract class CameraDevice implements AutoCloseable { * request for a specific physical camera. The settings are chosen * to be the best options for the specific logical camera device. If * additional physical camera ids are passed, then they will also use the - * same settings template. Requests containing individual physical camera - * settings can be passed only to {@link CameraCaptureSession#capture} or - * {@link CameraCaptureSession#captureBurst} and not to - * {@link CameraCaptureSession#setRepeatingRequest} or - * {@link CameraCaptureSession#setRepeatingBurst}</p> + * same settings template. Clients can further modify individual camera + * settings by calling {@link CaptureRequest.Builder#setPhysicalCameraKey}.</p> * * <p>Individual physical camera settings will only be honored for camera session * that was initialiazed with corresponding physical camera id output configuration @@ -896,8 +893,8 @@ public abstract class CameraDevice implements AutoCloseable { * @see #TEMPLATE_STILL_CAPTURE * @see #TEMPLATE_VIDEO_SNAPSHOT * @see #TEMPLATE_MANUAL - * @see CaptureRequest.Builder#setKey - * @see CaptureRequest.Builder#getKey + * @see CaptureRequest.Builder#setPhysicalCameraKey + * @see CaptureRequest.Builder#getPhysicalCameraKey */ @NonNull public CaptureRequest.Builder createCaptureRequest(@RequestTemplate int templateType, diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index cdee1101c27b..228fe7a3dae5 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -29,7 +29,13 @@ public abstract class HwBinder implements IHwBinder { private static final NativeAllocationRegistry sNativeRegistry; - /** @hide */ + /** + * Create and initialize a HwBinder object and the native objects + * used to allow this to participate in hwbinder transactions. + * + * @hide + */ + @SystemApi public HwBinder() { native_setup(); @@ -44,12 +50,28 @@ public abstract class HwBinder implements IHwBinder { int code, HwParcel request, HwParcel reply, int flags) throws RemoteException; - /** @hide */ + /** + * Process a hwbinder transaction. + * + * @param code interface specific code for interface. + * @param request parceled transaction + * @param reply object to parcel reply into + * @param flags transaction flags to be chosen by wire protocol + * + * @hide + */ + @SystemApi public abstract void onTransact( int code, HwParcel request, HwParcel reply, int flags) throws RemoteException; - /** @hide */ + /** + * Registers this service with the hwservicemanager. + * + * @param serviceName instance name of the service + * @hide + */ + @SystemApi public native final void registerService(String serviceName) throws RemoteException; diff --git a/core/java/android/security/IConfirmationPromptCallback.aidl b/core/java/android/security/IConfirmationPromptCallback.aidl deleted file mode 100644 index 96a1a04828b5..000000000000 --- a/core/java/android/security/IConfirmationPromptCallback.aidl +++ /dev/null @@ -1,27 +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.security; - -/** - * This must be kept manually in sync with system/security/keystore until AIDL - * can generate both Java and C++ bindings. - * - * @hide - */ -interface IConfirmationPromptCallback { - oneway void onConfirmationPromptCompleted(in int result, in byte[] dataThatWasConfirmed); -} diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl deleted file mode 100644 index 738eb6865230..000000000000 --- a/core/java/android/security/IKeystoreService.aidl +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2015, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security; - -import android.security.keymaster.ExportResult; -import android.security.keymaster.KeyCharacteristics; -import android.security.keymaster.KeymasterArguments; -import android.security.keymaster.KeymasterCertificateChain; -import android.security.keymaster.KeymasterBlob; -import android.security.keymaster.OperationResult; -import android.security.KeystoreArguments; - -/** - * This must be kept manually in sync with system/security/keystore until AIDL - * can generate both Java and C++ bindings. - * - * @hide - */ -interface IKeystoreService { - int getState(int userId); - byte[] get(String name, int uid); - int insert(String name, in byte[] item, int uid, int flags); - int del(String name, int uid); - int exist(String name, int uid); - String[] list(String namePrefix, int uid); - int reset(); - int onUserPasswordChanged(int userId, String newPassword); - int lock(int userId); - int unlock(int userId, String userPassword); - int isEmpty(int userId); - int generate(String name, int uid, int keyType, int keySize, int flags, - in KeystoreArguments args); - int import_key(String name, in byte[] data, int uid, int flags); - byte[] sign(String name, in byte[] data); - int verify(String name, in byte[] data, in byte[] signature); - byte[] get_pubkey(String name); - String grant(String name, int granteeUid); - int ungrant(String name, int granteeUid); - long getmtime(String name, int uid); - int is_hardware_backed(String string); - int clear_uid(long uid); - - // Keymaster 0.4 methods - int addRngEntropy(in byte[] data, int flags); - int generateKey(String alias, in KeymasterArguments arguments, in byte[] entropy, int uid, - int flags, out KeyCharacteristics characteristics); - int getKeyCharacteristics(String alias, in KeymasterBlob clientId, in KeymasterBlob appId, - int uid, out KeyCharacteristics characteristics); - int importKey(String alias, in KeymasterArguments arguments, int format, - in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics); - ExportResult exportKey(String alias, int format, in KeymasterBlob clientId, - in KeymasterBlob appId, int uid); - OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable, - in KeymasterArguments params, in byte[] entropy, int uid); - OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input); - OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature, - in byte[] entropy); - int abort(IBinder handle); - boolean isOperationAuthorized(IBinder token); - int addAuthToken(in byte[] authToken); - int onUserAdded(int userId, int parentId); - int onUserRemoved(int userId); - int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain); - int attestDeviceIds(in KeymasterArguments params, out KeymasterCertificateChain chain); - int onDeviceOffBody(); - int importWrappedKey(in String wrappedKeyAlias, in byte[] wrappedKey, - in String wrappingKeyAlias, in byte[] maskingKey, in KeymasterArguments arguments, - in long rootSid, in long fingerprintSid, - out KeyCharacteristics characteristics); - int presentConfirmationPrompt(IBinder listener, String promptText, in byte[] extraData, - in String locale, in int uiOptionsAsFlags); - int cancelConfirmationPrompt(IBinder listener); -} diff --git a/core/java/android/security/KeystoreArguments.aidl b/core/java/android/security/KeystoreArguments.aidl deleted file mode 100644 index dc8ed50182ed..000000000000 --- a/core/java/android/security/KeystoreArguments.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2015, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security; - -/* @hide */ -parcelable KeystoreArguments cpp_header "keystore/KeystoreArguments.h"; diff --git a/core/java/android/security/keymaster/ExportResult.aidl b/core/java/android/security/keymaster/ExportResult.aidl deleted file mode 100644 index 17486531a3f0..000000000000 --- a/core/java/android/security/keymaster/ExportResult.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.keymaster; - -/* @hide */ -parcelable ExportResult cpp_header "keystore/ExportResult.h"; diff --git a/core/java/android/security/keymaster/KeyCharacteristics.aidl b/core/java/android/security/keymaster/KeyCharacteristics.aidl deleted file mode 100644 index 32e75ad267b2..000000000000 --- a/core/java/android/security/keymaster/KeyCharacteristics.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.keymaster; - -/* @hide */ -parcelable KeyCharacteristics cpp_header "keystore/KeyCharacteristics.h"; diff --git a/core/java/android/security/keymaster/KeymasterArguments.aidl b/core/java/android/security/keymaster/KeymasterArguments.aidl deleted file mode 100644 index 44d9f0954781..000000000000 --- a/core/java/android/security/keymaster/KeymasterArguments.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.keymaster; - -/* @hide */ -parcelable KeymasterArguments cpp_header "keystore/KeymasterArguments.h"; diff --git a/core/java/android/security/keymaster/KeymasterBlob.aidl b/core/java/android/security/keymaster/KeymasterBlob.aidl deleted file mode 100644 index 5c5db9ec314b..000000000000 --- a/core/java/android/security/keymaster/KeymasterBlob.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.keymaster; - -/* @hide */ -parcelable KeymasterBlob cpp_header "keystore/KeymasterBlob.h"; diff --git a/core/java/android/security/keymaster/KeymasterCertificateChain.aidl b/core/java/android/security/keymaster/KeymasterCertificateChain.aidl deleted file mode 100644 index ddb5cae1a254..000000000000 --- a/core/java/android/security/keymaster/KeymasterCertificateChain.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2016 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.security.keymaster; - -/* @hide */ -parcelable KeymasterCertificateChain cpp_header "keystore/KeymasterCertificateChain.h"; diff --git a/core/java/android/security/keymaster/OperationResult.aidl b/core/java/android/security/keymaster/OperationResult.aidl deleted file mode 100644 index db689d46521a..000000000000 --- a/core/java/android/security/keymaster/OperationResult.aidl +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.security.keymaster; - -/* @hide */ -parcelable OperationResult cpp_header "keystore/OperationResult.h"; diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java index 7383de738ad6..f644887676a2 100644 --- a/core/java/android/service/autofill/AutofillServiceInfo.java +++ b/core/java/android/service/autofill/AutofillServiceInfo.java @@ -32,12 +32,12 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.AttributeSet; import android.util.Log; +import android.util.Pair; import android.util.Xml; import com.android.internal.R; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - import com.android.internal.util.XmlUtils; import org.xmlpull.v1.XmlPullParser; @@ -80,7 +80,7 @@ public final class AutofillServiceInfo { private final String mSettingsActivity; @Nullable - private final Map<String, Long> mCompatibilityPackages; + private final Map<String, Pair<Long, String>> mCompatibilityPackages; public AutofillServiceInfo(Context context, ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { @@ -118,7 +118,7 @@ public final class AutofillServiceInfo { } String settingsActivity = null; - Map<String, Long> compatibilityPackages = null; + Map<String, Pair<Long, String>> compatibilityPackages = null; try { final Resources resources = context.getPackageManager().getResourcesForApplication( @@ -154,9 +154,10 @@ public final class AutofillServiceInfo { mCompatibilityPackages = compatibilityPackages; } - private Map<String, Long> parseCompatibilityPackages(XmlPullParser parser, Resources resources) + private Map<String, Pair<Long, String>> parseCompatibilityPackages(XmlPullParser parser, + Resources resources) throws IOException, XmlPullParserException { - Map<String, Long> compatibilityPackages = null; + Map<String, Pair<Long, String>> compatibilityPackages = null; final int outerDepth = parser.getDepth(); int type; @@ -200,11 +201,13 @@ public final class AutofillServiceInfo { } else { maxVersionCode = Long.MAX_VALUE; } + final String urlBarResourceId = cpAttributes.getString( + R.styleable.AutofillService_CompatibilityPackage_urlBarResourceId); if (compatibilityPackages == null) { compatibilityPackages = new ArrayMap<>(); } - compatibilityPackages.put(name, maxVersionCode); + compatibilityPackages.put(name, new Pair<>(maxVersionCode, urlBarResourceId)); } finally { XmlUtils.skipCurrentTag(parser); if (cpAttributes != null) { @@ -226,16 +229,28 @@ public final class AutofillServiceInfo { return mSettingsActivity; } - @Nullable public boolean isCompatibilityModeRequested(String packageName, long versionCode) { if (mCompatibilityPackages == null) { return false; } - final Long maxVersionCode = mCompatibilityPackages.get(packageName); - if (maxVersionCode == null) { + final Pair<Long, String> pair = mCompatibilityPackages.get(packageName); + if (pair == null) { return false; } - return versionCode <= maxVersionCode; + return versionCode <= pair.first; + } + + /** + * Gets the resource id of the URL bar for a package. Used in compat mode + */ + // TODO: return a list of strings instead + @Nullable + public String getUrlBarResourceId(String packageName) { + if (mCompatibilityPackages == null) { + return null; + } + final Pair<Long, String> pair = mCompatibilityPackages.get(packageName); + return pair == null ? null : pair.second; } @Override diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java index cda2f4a23c9a..535c00bc5319 100644 --- a/core/java/android/service/autofill/FillContext.java +++ b/core/java/android/service/autofill/FillContext.java @@ -177,30 +177,6 @@ public final class FillContext implements Parcelable { return foundNodes; } - /** - * Finds the {@link ViewNode} that has the requested {@code id}, if any. - * - * @hide - */ - @Nullable public ViewNode findViewNodeByAutofillId(@NonNull AutofillId id) { - final LinkedList<ViewNode> nodesToProcess = new LinkedList<>(); - final int numWindowNodes = mStructure.getWindowNodeCount(); - for (int i = 0; i < numWindowNodes; i++) { - nodesToProcess.add(mStructure.getWindowNodeAt(i).getRootViewNode()); - } - while (!nodesToProcess.isEmpty()) { - final ViewNode node = nodesToProcess.removeFirst(); - if (id.equals(node.getAutofillId())) { - return node; - } - for (int i = 0; i < node.getChildCount(); i++) { - nodesToProcess.addLast(node.getChildAt(i)); - } - } - - return null; - } - public static final Parcelable.Creator<FillContext> CREATOR = new Parcelable.Creator<FillContext>() { @Override diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java index 4805318385d5..3350f3e164bc 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -34,7 +34,7 @@ public final class StatsLog extends StatsLogInternal { */ public static boolean logStart(int label) { if (label >= 0 && label < 16) { - StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__START); + StatsLog.write(APP_BREADCRUMB_REPORTED, label, APP_BREADCRUMB_REPORTED__STATE__START); return true; } return false; @@ -48,7 +48,7 @@ public final class StatsLog extends StatsLogInternal { */ public static boolean logStop(int label) { if (label >= 0 && label < 16) { - StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__STOP); + StatsLog.write(APP_BREADCRUMB_REPORTED, label, APP_BREADCRUMB_REPORTED__STATE__STOP); return true; } return false; @@ -62,7 +62,8 @@ public final class StatsLog extends StatsLogInternal { */ public static boolean logEvent(int label) { if (label >= 0 && label < 16) { - StatsLog.write(APP_HOOK, label, APP_HOOK__STATE__UNSPECIFIED); + StatsLog.write(APP_BREADCRUMB_REPORTED, label, + APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED); return true; } return false; diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java index 370c97e37262..e50d40ef098f 100644 --- a/core/java/android/view/ThreadedRenderer.java +++ b/core/java/android/view/ThreadedRenderer.java @@ -331,6 +331,7 @@ public final class ThreadedRenderer { private static final int FLAG_DUMP_FRAMESTATS = 1 << 0; private static final int FLAG_DUMP_RESET = 1 << 1; + private static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS; @IntDef(flag = true, prefix = { "FLAG_DUMP_" }, value = { FLAG_DUMP_FRAMESTATS, @@ -636,7 +637,10 @@ public final class ThreadedRenderer { */ void dumpGfxInfo(PrintWriter pw, FileDescriptor fd, String[] args) { pw.flush(); - int flags = 0; + // If there's no arguments, eg 'dumpsys gfxinfo', then dump everything. + // If there's a targetted package, eg 'dumpsys gfxinfo com.android.systemui', then only + // dump the summary information + int flags = (args == null || args.length == 0) ? FLAG_DUMP_ALL : 0; for (int i = 0; i < args.length; i++) { switch (args[i]) { case "framestats": @@ -645,6 +649,9 @@ public final class ThreadedRenderer { case "reset": flags |= FLAG_DUMP_RESET; break; + case "-a": // magic option passed when dumping a bugreport. + flags = FLAG_DUMP_ALL; + break; } } nDumpProfileInfo(mNativeProxy, fd, flags); diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index 990fbdb019d6..29f8442b2b46 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -18,6 +18,7 @@ package android.view.animation; import android.annotation.AnimRes; import android.annotation.InterpolatorRes; +import android.annotation.TestApi; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; @@ -58,14 +59,43 @@ public class AnimationUtils { } }; - /** @hide */ + /** + * Locks AnimationUtils{@link #currentAnimationTimeMillis()} to a fixed value for the current + * thread. This is used by {@link android.view.Choreographer} to ensure that all accesses + * during a vsync update are synchronized to the timestamp of the vsync. + * + * It is also exposed to tests to allow for rapid, flake-free headless testing. + * + * Must be followed by a call to {@link #unlockAnimationClock()} to allow time to + * progress. Failing to do this will result in stuck animations, scrolls, and flings. + * + * Note that time is not allowed to "rewind" and must perpetually flow forward. So the + * lock may fail if the time is in the past from a previously returned value, however + * time will be frozen for the duration of the lock. The clock is a thread-local, so + * ensure that {@link #lockAnimationClock(long)}, {@link #unlockAnimationClock()}, and + * {@link #currentAnimationTimeMillis()} are all called on the same thread. + * + * This is also not reference counted in any way. Any call to {@link #unlockAnimationClock()} + * will unlock the clock for everyone on the same thread. It is therefore recommended + * for tests to use their own thread to ensure that there is no collision with any existing + * {@link android.view.Choreographer} instance. + * + * @hide + * */ + @TestApi public static void lockAnimationClock(long vsyncMillis) { AnimationState state = sAnimationState.get(); state.animationClockLocked = true; state.currentVsyncTimeMillis = vsyncMillis; } - /** @hide */ + /** + * Frees the time lock set in place by {@link #lockAnimationClock(long)}. Must be called + * to allow the animation clock to self-update. + * + * @hide + */ + @TestApi public static void unlockAnimationClock() { sAnimationState.get().animationClockLocked = false; } diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 8b64bad8fe62..41d05a5d1ed0 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -1407,7 +1407,8 @@ public final class AutofillManager { mSessionId = mService.startSession(client.autofillClientGetActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), - mCallback != null, flags, client.autofillClientGetComponentName()); + mCallback != null, flags, client.autofillClientGetComponentName(), + isCompatibilityModeEnabledLocked()); if (mSessionId != NO_SESSION) { mState = STATE_ACTIVE; } @@ -1474,7 +1475,7 @@ public final class AutofillManager { client.autofillClientGetActivityToken(), mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(), mCallback != null, flags, client.autofillClientGetComponentName(), - mSessionId, action); + mSessionId, action, isCompatibilityModeEnabledLocked()); if (newId != mSessionId) { if (sDebug) Log.d(TAG, "Session restarted: " + mSessionId + "=>" + newId); mSessionId = newId; diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl index 001854716715..56f79abf6c19 100644 --- a/core/java/android/view/autofill/IAutoFillManager.aidl +++ b/core/java/android/view/autofill/IAutoFillManager.aidl @@ -38,7 +38,7 @@ interface IAutoFillManager { void removeClient(in IAutoFillManagerClient client, int userId); int startSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, - in ComponentName componentName); + in ComponentName componentName, boolean compatMode); FillEventHistory getFillEventHistory(); boolean restoreSession(int sessionId, in IBinder activityToken, in IBinder appCallback); void updateSession(int sessionId, in AutofillId id, in Rect bounds, @@ -46,7 +46,7 @@ interface IAutoFillManager { int updateOrRestartSession(IBinder activityToken, in IBinder appCallback, in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId, boolean hasCallback, int flags, in ComponentName componentName, int sessionId, - int action); + int action, boolean compatMode); void finishSession(int sessionId, int userId); void cancelSession(int sessionId, int userId); void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index eb58b0919385..6a56f452f3fe 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -187,7 +187,7 @@ public class BatteryStatsImpl extends BatteryStats { public final AtomicFile mCheckinFile; public final AtomicFile mDailyFile; - static final int MSG_UPDATE_WAKELOCKS = 1; + static final int MSG_REPORT_CPU_UPDATE_NEEDED = 1; static final int MSG_REPORT_POWER_CHANGE = 2; static final int MSG_REPORT_CHARGING = 3; static final long DELAY_UPDATE_WAKELOCKS = 5*1000; @@ -273,10 +273,7 @@ public class BatteryStatsImpl extends BatteryStats { public void handleMessage(Message msg) { BatteryCallback cb = mCallback; switch (msg.what) { - case MSG_UPDATE_WAKELOCKS: - synchronized (BatteryStatsImpl.this) { - updateCpuTimeLocked(); - } + case MSG_REPORT_CPU_UPDATE_NEEDED: if (cb != null) { cb.batteryNeedsCpuUpdate(); } @@ -302,6 +299,10 @@ public class BatteryStatsImpl extends BatteryStats { } } + public void postBatteryNeedsCpuUpdateMsg() { + mHandler.sendEmptyMessage(MSG_REPORT_CPU_UPDATE_NEEDED); + } + /** * Update per-freq cpu times for all the uids in {@link #mPendingUids}. */ @@ -487,6 +488,10 @@ public class BatteryStatsImpl extends BatteryStats { Future<?> scheduleReadProcStateCpuTimes(boolean onBattery, boolean onBatteryScreenOff); Future<?> scheduleCopyFromAllUidsCpuTimes(boolean onBattery, boolean onBatteryScreenOff); Future<?> scheduleCpuSyncDueToSettingChange(); + Future<?> scheduleCpuSyncDueToScreenStateChange(boolean onBattery, + boolean onBatteryScreenOff); + Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis); + void cancelCpuSyncDueToWakelockChange(); } public Handler mHandler; @@ -1453,12 +1458,10 @@ public class BatteryStatsImpl extends BatteryStats { long mCount; long mLoadedCount; long mUnpluggedCount; - long mPluggedCount; LongSamplingCounter(TimeBase timeBase, Parcel in) { mTimeBase = timeBase; - mPluggedCount = in.readLong(); - mCount = mPluggedCount; + mCount = in.readLong(); mLoadedCount = in.readLong(); mUnpluggedCount = in.readLong(); timeBase.add(this); @@ -1477,16 +1480,15 @@ public class BatteryStatsImpl extends BatteryStats { @Override public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) { - mUnpluggedCount = mPluggedCount; + mUnpluggedCount = mCount; } @Override public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) { - mPluggedCount = mCount; } public long getCountLocked(int which) { - long val = mTimeBase.isRunning() ? mCount : mPluggedCount; + long val = mCount; if (which == STATS_SINCE_UNPLUGGED) { val -= mUnpluggedCount; } else if (which != STATS_SINCE_CHARGED) { @@ -1499,12 +1501,15 @@ public class BatteryStatsImpl extends BatteryStats { public void logState(Printer pw, String prefix) { pw.println(prefix + "mCount=" + mCount + " mLoadedCount=" + mLoadedCount - + " mUnpluggedCount=" + mUnpluggedCount - + " mPluggedCount=" + mPluggedCount); + + " mUnpluggedCount=" + mUnpluggedCount); } void addCountLocked(long count) { - if (mTimeBase.isRunning()) { + addCountLocked(count, mTimeBase.isRunning()); + } + + void addCountLocked(long count, boolean isRunning) { + if (isRunning) { mCount += count; } } @@ -1514,7 +1519,7 @@ public class BatteryStatsImpl extends BatteryStats { */ void reset(boolean detachIfReset) { mCount = 0; - mLoadedCount = mPluggedCount = mUnpluggedCount = 0; + mLoadedCount = mUnpluggedCount = 0; if (detachIfReset) { detach(); } @@ -1531,7 +1536,7 @@ public class BatteryStatsImpl extends BatteryStats { void readSummaryFromParcelLocked(Parcel in) { mLoadedCount = in.readLong(); mCount = mLoadedCount; - mUnpluggedCount = mPluggedCount = mLoadedCount; + mUnpluggedCount = mLoadedCount; } } @@ -3852,9 +3857,6 @@ public class BatteryStatsImpl extends BatteryStats { + Display.stateToString(screenState) + " and battery is " + (unplugged ? "on" : "off")); } - updateCpuTimeLocked(); - mExternalSync.scheduleCopyFromAllUidsCpuTimes(mOnBatteryTimeBase.isRunning(), - mOnBatteryScreenOffTimeBase.isRunning()); mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime); if (updateOnBatteryTimeBase) { @@ -4143,15 +4145,11 @@ public class BatteryStatsImpl extends BatteryStats { } private void requestWakelockCpuUpdate() { - if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { - Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); - mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); - } + mExternalSync.scheduleCpuSyncDueToWakelockChange(DELAY_UPDATE_WAKELOCKS); } private void requestImmediateCpuUpdate() { - mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); - mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS); + mExternalSync.scheduleCpuSyncDueToWakelockChange(0 /* delayMillis */); } public void setRecordAllHistoryLocked(boolean enabled) { @@ -4554,7 +4552,7 @@ public class BatteryStatsImpl extends BatteryStats { } public boolean startAddingCpuLocked() { - mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + mExternalSync.cancelCpuSyncDueToWakelockChange(); return mOnBatteryInternal; } @@ -4807,6 +4805,8 @@ public class BatteryStatsImpl extends BatteryStats { + Display.stateToString(state)); addHistoryRecordLocked(elapsedRealtime, uptime); } + mExternalSync.scheduleCpuSyncDueToScreenStateChange( + mOnBatteryTimeBase.isRunning(), mOnBatteryScreenOffTimeBase.isRunning()); if (isScreenOn(state)) { updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state, mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000); @@ -9196,8 +9196,14 @@ public class BatteryStatsImpl extends BatteryStats { } public void addCpuTimeLocked(int utime, int stime) { - mUserTime += utime; - mSystemTime += stime; + addCpuTimeLocked(utime, stime, mBsi.mOnBatteryTimeBase.isRunning()); + } + + public void addCpuTimeLocked(int utime, int stime, boolean isRunning) { + if (isRunning) { + mUserTime += utime; + mSystemTime += stime; + } } public void addForegroundTimeLocked(long ttime) { @@ -11761,13 +11767,24 @@ public class BatteryStatsImpl extends BatteryStats { } } + public boolean isOnBatteryLocked() { + return mOnBatteryTimeBase.isRunning(); + } + + public boolean isOnBatteryScreenOffLocked() { + return mOnBatteryScreenOffTimeBase.isRunning(); + } + /** * Read and distribute CPU usage across apps. If their are partial wakelocks being held * and we are on battery with screen off, we give more of the cpu time to those apps holding * wakelocks. If the screen is on, we just assign the actual cpu time an app used. + * It's possible this will be invoked after the internal battery/screen states are updated, so + * passing the appropriate battery/screen states to try attribute the cpu times to correct + * buckets. */ @GuardedBy("this") - public void updateCpuTimeLocked() { + public void updateCpuTimeLocked(boolean onBattery, boolean onBatteryScreenOff) { if (mPowerProfile == null) { return; } @@ -11784,7 +11801,7 @@ public class BatteryStatsImpl extends BatteryStats { // usually holding the wakelock on behalf of an app. // And Only distribute cpu power to wakelocks if the screen is off and we're on battery. ArrayList<StopwatchTimer> partialTimersToConsider = null; - if (mOnBatteryScreenOffTimeBase.isRunning()) { + if (onBatteryScreenOff) { partialTimersToConsider = new ArrayList<>(); for (int i = mPartialTimers.size() - 1; i >= 0; --i) { final StopwatchTimer timer = mPartialTimers.get(i); @@ -11802,7 +11819,7 @@ public class BatteryStatsImpl extends BatteryStats { // When the battery is not on, we don't attribute the cpu times to any timers but we still // need to take the snapshots. - if (!mOnBatteryInternal) { + if (!onBattery) { mKernelUidCpuTimeReader.readDelta(null); mKernelUidCpuFreqTimeReader.readDelta(null); if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { @@ -11818,16 +11835,16 @@ public class BatteryStatsImpl extends BatteryStats { mUserInfoProvider.refreshUserIds(); final SparseLongArray updatedUids = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable() ? null : new SparseLongArray(); - readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids); + readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids, onBattery); // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu // freqs, so no need to approximate these values. if (updatedUids != null) { - updateClusterSpeedTimes(updatedUids); + updateClusterSpeedTimes(updatedUids, onBattery); } - readKernelUidCpuFreqTimesLocked(partialTimersToConsider); + readKernelUidCpuFreqTimesLocked(partialTimersToConsider, onBattery, onBatteryScreenOff); if (mConstants.TRACK_CPU_ACTIVE_CLUSTER_TIME) { - readKernelUidCpuActiveTimesLocked(); - readKernelUidCpuClusterTimesLocked(); + readKernelUidCpuActiveTimesLocked(onBattery); + readKernelUidCpuClusterTimesLocked(onBattery); } } @@ -11867,7 +11884,7 @@ public class BatteryStatsImpl extends BatteryStats { * @param updatedUids The uids for which times spent at different frequencies are calculated. */ @VisibleForTesting - public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids) { + public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids, boolean onBattery) { long totalCpuClustersTimeMs = 0; // Read the time spent for each cluster at various cpu frequencies. final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][]; @@ -11909,7 +11926,7 @@ public class BatteryStatsImpl extends BatteryStats { } cpuSpeeds[speed].addCountLocked(appCpuTimeUs * clusterSpeedTimesMs[cluster][speed] - / totalCpuClustersTimeMs); + / totalCpuClustersTimeMs, onBattery); } } } @@ -11926,7 +11943,7 @@ public class BatteryStatsImpl extends BatteryStats { */ @VisibleForTesting public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, - @Nullable SparseLongArray updatedUids) { + @Nullable SparseLongArray updatedUids, boolean onBattery) { mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0; final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); final long startTimeMs = mClocks.uptimeMillis(); @@ -11977,8 +11994,8 @@ public class BatteryStatsImpl extends BatteryStats { Slog.d(TAG, sb.toString()); } - u.mUserCpuTime.addCountLocked(userTimeUs); - u.mSystemCpuTime.addCountLocked(systemTimeUs); + u.mUserCpuTime.addCountLocked(userTimeUs, onBattery); + u.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); if (updatedUids != null) { updatedUids.put(u.getUid(), userTimeUs + systemTimeUs); } @@ -12010,15 +12027,15 @@ public class BatteryStatsImpl extends BatteryStats { Slog.d(TAG, sb.toString()); } - timer.mUid.mUserCpuTime.addCountLocked(userTimeUs); - timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs); + timer.mUid.mUserCpuTime.addCountLocked(userTimeUs, onBattery); + timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs, onBattery); if (updatedUids != null) { final int uid = timer.mUid.getUid(); updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs); } final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*"); - proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000); + proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000, onBattery); mTempTotalCpuUserTimeUs -= userTimeUs; mTempTotalCpuSystemTimeUs -= systemTimeUs; @@ -12033,7 +12050,8 @@ public class BatteryStatsImpl extends BatteryStats { * @param partialTimers The wakelock holders among which the cpu freq times will be distributed. */ @VisibleForTesting - public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers) { + public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers, + boolean onBattery, boolean onBatteryScreenOff) { final boolean perClusterTimesAvailable = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable(); final int numWakelocks = partialTimers == null ? 0 : partialTimers.size(); @@ -12056,13 +12074,13 @@ public class BatteryStatsImpl extends BatteryStats { if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase); } - u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs); + u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBattery); if (u.mScreenOffCpuFreqTimeMs == null || u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) { u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray( mOnBatteryScreenOffTimeBase); } - u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs); + u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs, onBatteryScreenOff); if (perClusterTimesAvailable) { if (u.mCpuClusterSpeedTimesUs == null || @@ -12098,7 +12116,7 @@ public class BatteryStatsImpl extends BatteryStats { } else { appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000; } - cpuTimesUs[speed].addCountLocked(appAllocationUs); + cpuTimesUs[speed].addCountLocked(appAllocationUs, onBattery); freqIndex++; } } @@ -12132,7 +12150,7 @@ public class BatteryStatsImpl extends BatteryStats { } final long allocationUs = mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i); - cpuTimeUs[speed].addCountLocked(allocationUs); + cpuTimeUs[speed].addCountLocked(allocationUs, onBattery); mWakeLockAllocationsUs[cluster][speed] -= allocationUs; } } @@ -12145,7 +12163,7 @@ public class BatteryStatsImpl extends BatteryStats { * counters. */ @VisibleForTesting - public void readKernelUidCpuActiveTimesLocked() { + public void readKernelUidCpuActiveTimesLocked(boolean onBattery) { final long startTimeMs = mClocks.uptimeMillis(); mKernelUidCpuActiveTimeReader.readDelta((uid, cpuActiveTimesUs) -> { uid = mapUid(uid); @@ -12160,7 +12178,7 @@ public class BatteryStatsImpl extends BatteryStats { return; } final Uid u = getUidStatsLocked(uid); - u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesUs); + u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesUs, onBattery); }); final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; @@ -12174,7 +12192,7 @@ public class BatteryStatsImpl extends BatteryStats { * counters. */ @VisibleForTesting - public void readKernelUidCpuClusterTimesLocked() { + public void readKernelUidCpuClusterTimesLocked(boolean onBattery) { final long startTimeMs = mClocks.uptimeMillis(); mKernelUidCpuClusterTimeReader.readDelta((uid, cpuClusterTimesUs) -> { uid = mapUid(uid); @@ -12189,7 +12207,7 @@ public class BatteryStatsImpl extends BatteryStats { return; } final Uid u = getUidStatsLocked(uid); - u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesUs); + u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesUs, onBattery); }); final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs; @@ -12399,9 +12417,7 @@ public class BatteryStatsImpl extends BatteryStats { reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null, status, plugType, level, temp); - final boolean onBattery = - plugType == BATTERY_PLUGGED_NONE && - status != BatteryManager.BATTERY_STATUS_UNKNOWN; + final boolean onBattery = isOnBattery(plugType, status); final long uptime = mClocks.uptimeMillis(); final long elapsedRealtime = mClocks.elapsedRealtime(); if (!mHaveBatteryLevel) { @@ -12591,6 +12607,10 @@ public class BatteryStatsImpl extends BatteryStats { mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh); } + public static boolean isOnBattery(int plugType, int status) { + return plugType == BATTERY_PLUGGED_NONE && status != BatteryManager.BATTERY_STATUS_UNKNOWN; + } + // Inform StatsLog of setBatteryState changes. // If this is the first reporting, pass in recentPast == null. private void reportChangesToStatsLog(HistoryItem recentPast, diff --git a/core/res/res/drawable/ic_settings_24dp.xml b/core/res/res/drawable/ic_settings_24dp.xml index fc75f04ff46b..c70b122358b8 100644 --- a/core/res/res/drawable/ic_settings_24dp.xml +++ b/core/res/res/drawable/ic_settings_24dp.xml @@ -16,9 +16,9 @@ Copyright (C) 2015 The Android Open Source Project <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" - android:viewportWidth="48.0" - android:viewportHeight="48.0"> + android:viewportWidth="24.0" + android:viewportHeight="24.0"> <path - android:fillColor="#FF000000" - android:pathData="M38.86 25.95c.08,-.64.14,-1.29.14,-1.95s-.06,-1.31,-.14,-1.95l4.23,-3.31c.38,-.3.49,-.84.24,-1.28l-4,-6.93c-.25,-.43,-.77,-.61,-1.22,-.43l-4.98 2.01c-1.03,-.79,-2.16,-1.46,-3.38,-1.97L29 4.84c-.09,-.47,-.5,-.84,-1,-.84h-8c-.5 0,-.91.37,-.99.84l-.75 5.3c-1.22.51,-2.35 1.17,-3.38 1.97L9.9 10.1c-.45,-.17,-.97 0,-1.22.43l-4 6.93c-.25.43,-.14.97.24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31.14 1.95l-4.22 3.31c-.38.3,-.49.84,-.24 1.28l4 6.93c.25.43.77.61 1.22.43l4.98,-2.01c1.03.79 2.16 1.46 3.38 1.97l.75 5.3c.08.47.49.84.99.84h8c.5 0 .91,-.37.99,-.84l.75,-5.3c1.22,-.51 2.35,-1.17 3.38,-1.97l4.98 2.01c.45.17.97 0 1.22,-.43l4,-6.93c.25,-.43.14,-.97,-.24,-1.28l-4.22,-3.31zM24 31c-3.87 0,-7,-3.13,-7,-7s3.13,-7 7,-7 7 3.13 7 7,-3.13 7,-7 7z"/> + android:pathData="M19.4,13.0c0.0,-0.3 0.1,-0.6 0.1,-1.0s0.0,-0.7 -0.1,-1.0l2.1,-1.7c0.2,-0.2 0.2,-0.4 0.1,-0.6l-2.0,-3.5C19.5,5.1 19.3,5.0 19.0,5.1l-2.5,1.0c-0.5,-0.4 -1.1,-0.7 -1.7,-1.0l-0.4,-2.6C14.5,2.2 14.2,2.0 14.0,2.0l-4.0,0.0C9.8,2.0 9.5,2.2 9.5,2.4L9.1,5.1C8.5,5.3 8.0,5.7 7.4,6.1L5.0,5.1C4.7,5.0 4.5,5.1 4.3,5.3l-2.0,3.5C2.2,8.9 2.3,9.2 2.5,9.4L4.6,11.0c0.0,0.3 -0.1,0.6 -0.1,1.0s0.0,0.7 0.1,1.0l-2.1,1.7c-0.2,0.2 -0.2,0.4 -0.1,0.6l2.0,3.5C4.5,18.9 4.7,19.0 5.0,18.9l2.5,-1.0c0.5,0.4 1.1,0.7 1.7,1.0l0.4,2.6c0.0,0.2 0.2,0.4 0.5,0.4l4.0,0.0c0.2,0.0 0.5,-0.2 0.5,-0.4l0.4,-2.6c0.6,-0.3 1.2,-0.6 1.7,-1.0l2.5,1.0c0.2,0.1 0.5,0.0 0.6,-0.2l2.0,-3.5c0.1,-0.2 0.1,-0.5 -0.1,-0.6L19.4,13.0zM12.0,15.5c-1.9,0.0 -3.5,-1.6 -3.5,-3.5s1.6,-3.5 3.5,-3.5s3.5,1.6 3.5,3.5S13.9,15.5 12.0,15.5z" + android:fillColor="#FF000000" /> </vector> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 005d07dc008a..d26567e9a3f5 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7918,6 +7918,10 @@ android.content.pm.PackageInfo#getLongVersionCode()} for the target package. --> <attr name="maxLongVersionCode" format="string" /> + <!-- The resource id of view that contains the URL bar of the HTML page being loaded. + Typically used when compatibility mode is used in a browser. + --> + <attr name="urlBarResourceId" format="string" /> </declare-styleable> <!-- =============================== --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index cf7925baa578..0218750d0f87 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2913,8 +2913,8 @@ <item name="config_pictureInPictureAspectRatioLimitForMinSize" format="float" type="dimen">1.777778</item> <!-- The default gravity for the picture-in-picture window. - Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT --> - <integer name="config_defaultPictureInPictureGravity">0x55</integer> + Currently, this maps to Gravity.TOP | Gravity.RIGHT --> + <integer name="config_defaultPictureInPictureGravity">0x35</integer> <!-- The minimum aspect ratio (width/height) that is supported for picture-in-picture. Any ratio smaller than this is considered too tall and thin to be usable. Currently, this diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 93f22f25d7d3..82fefef5fef6 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2869,6 +2869,7 @@ <public name="outlineSpotShadowColor" /> <public name="outlineAmbientShadowColor" /> <public name="maxLongVersionCode" /> + <public name="urlBarResourceId" /> </public-group> <public-group type="style" first-id="0x010302e0"> diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java index 32053e30e886..cb049b780fa8 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsCpuTimesTest.java @@ -114,7 +114,7 @@ public class BatteryStatsCpuTimesTest { when(mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile)).thenReturn(freqs); // RUN - mBatteryStatsImpl.updateCpuTimeLocked(); + mBatteryStatsImpl.updateCpuTimeLocked(false, false); // VERIFY assertArrayEquals("Unexpected cpu freqs", freqs, mBatteryStatsImpl.getCpuFreqs()); @@ -134,7 +134,7 @@ public class BatteryStatsCpuTimesTest { mBatteryStatsImpl.setOnBatteryInternal(true); // RUN - mBatteryStatsImpl.updateCpuTimeLocked(); + mBatteryStatsImpl.updateCpuTimeLocked(true, false); // VERIFY verify(mUserInfoProvider).refreshUserIds(); @@ -213,7 +213,7 @@ public class BatteryStatsCpuTimesTest { } // RUN - mBatteryStatsImpl.updateClusterSpeedTimes(updatedUids); + mBatteryStatsImpl.updateClusterSpeedTimes(updatedUids, true); // VERIFY int totalClustersTimeMs = 0; @@ -261,7 +261,7 @@ public class BatteryStatsCpuTimesTest { // RUN final SparseLongArray updatedUids = new SparseLongArray(); - mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, updatedUids); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, updatedUids, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -294,7 +294,7 @@ public class BatteryStatsCpuTimesTest { }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -333,7 +333,7 @@ public class BatteryStatsCpuTimesTest { }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -368,7 +368,7 @@ public class BatteryStatsCpuTimesTest { }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -423,7 +423,7 @@ public class BatteryStatsCpuTimesTest { }).when(mKernelUidCpuTimeReader).readDelta(any(KernelUidCpuTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(null, null, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -470,7 +470,7 @@ public class BatteryStatsCpuTimesTest { // RUN final SparseLongArray updatedUids = new SparseLongArray(); - mBatteryStatsImpl.readKernelUidCpuTimesLocked(partialTimers, updatedUids); + mBatteryStatsImpl.readKernelUidCpuTimesLocked(partialTimers, updatedUids, true); // VERIFY long totalUserTimeUs = 0; @@ -549,7 +549,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -582,7 +582,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -633,7 +633,7 @@ public class BatteryStatsCpuTimesTest { when(mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()).thenReturn(true); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -676,7 +676,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -743,7 +743,7 @@ public class BatteryStatsCpuTimesTest { when(mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()).thenReturn(true); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(partialTimers); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(partialTimers, true, false); // VERIFY final long[][] expectedWakeLockUidTimesUs = new long[clusterFreqs.length][]; @@ -832,7 +832,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -865,7 +865,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -909,7 +909,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -949,7 +949,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -1006,7 +1006,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuFreqTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null); + mBatteryStatsImpl.readKernelUidCpuFreqTimesLocked(null, true, false); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -1047,7 +1047,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuActiveTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(); + mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -1073,7 +1073,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuActiveTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(); + mBatteryStatsImpl.readKernelUidCpuActiveTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -1112,7 +1112,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuClusterTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(); + mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { @@ -1142,7 +1142,7 @@ public class BatteryStatsCpuTimesTest { any(KernelUidCpuClusterTimeReader.Callback.class)); // RUN - mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(); + mBatteryStatsImpl.readKernelUidCpuClusterTimesLocked(true); // VERIFY for (int i = 0; i < testUids.length; ++i) { diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java index 82ac9da575d7..01ddc15efb47 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java @@ -161,9 +161,7 @@ public class BatteryStatsNoteTest extends TestCase { actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, elapsedTimeUs, STATS_SINCE_CHARGED); - expectedRunTimeMs = stateRuntimeMap.get( - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) - + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); + expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING, @@ -173,7 +171,8 @@ public class BatteryStatsNoteTest extends TestCase { actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND, elapsedTimeUs, STATS_SINCE_CHARGED); - expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); + expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) + + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java index 7b239f05c0d3..cb05253c6f57 100644 --- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java @@ -171,6 +171,20 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { return null; } + @Override + public Future<?> scheduleCpuSyncDueToScreenStateChange( + boolean onBattery, boolean onBatteryScreenOff) { + return null; + } + + @Override + public Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis) { + return null; + } + + @Override + public void cancelCpuSyncDueToWakelockChange() { + } } } diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk index 994131a22ab3..9b9e8113f234 100644 --- a/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk +++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/Android.mk @@ -29,13 +29,10 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES:= \ native.cpp -# All of the shard libraries we link against. -LOCAL_SHARED_LIBRARIES := liblog +LOCAL_LDLIBS := -llog LOCAL_CFLAGS += -Wall -Wextra -Werror -# Also need the JNI headers. -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) +LOCAL_SDK_VERSION := current include $(BUILD_SHARED_LIBRARY) diff --git a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp index 99cf587af2a6..fe32454aa10d 100644 --- a/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp +++ b/core/tests/hosttests/test-apps/SharedUid/32/jni/native.cpp @@ -15,12 +15,15 @@ */ #define LOG_TAG "pmtest32 native.cpp" -#include <utils/Log.h> +#include <android/log.h> #include <stdio.h> #include "jni.h" +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + static jint add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) { int result = a + b; diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk index 6c2679b30bfb..600a5d148740 100644 --- a/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk +++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/Android.mk @@ -30,14 +30,10 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES:= \ native.cpp -# All of the shared libraries we link against. -LOCAL_SHARED_LIBRARIES := \ - libutils liblog +LOCAL_LDLIBS := -llog LOCAL_CFLAGS += -Wall -Wextra -Werror -# Also need the JNI headers. -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) +LOCAL_SDK_VERSION := current include $(BUILD_SHARED_LIBRARY) diff --git a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp index 0b6d7501dcae..ad9e7469d1b8 100644 --- a/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp +++ b/core/tests/hosttests/test-apps/SharedUid/64/jni/native.cpp @@ -15,12 +15,15 @@ */ #define LOG_TAG "pmtest64 native.cpp" -#include <utils/Log.h> +#include <android/log.h> #include <stdio.h> #include "jni.h" +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + static jint add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) { int result = a + b; diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk index d668f29456c8..8e9ac6b5de95 100644 --- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk +++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/Android.mk @@ -29,14 +29,10 @@ LOCAL_MODULE_TAGS := tests LOCAL_SRC_FILES:= \ native.cpp -# All of the shard libraries we link against. LOCAL_LDLIBS = -llog -LOCAL_SHARED_LIBRARIES := liblog LOCAL_CFLAGS += -Wall -Wextra -Werror -# Also need the JNI headers. -LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) +LOCAL_SDK_VERSION := current include $(BUILD_SHARED_LIBRARY) diff --git a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp index 3947e21a77bd..5c5088f40a94 100644 --- a/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp +++ b/core/tests/hosttests/test-apps/SharedUid/dual/jni/native.cpp @@ -15,12 +15,15 @@ */ #define LOG_TAG "pmtestdual native.cpp" -#include <utils/Log.h> +#include <android/log.h> #include <stdio.h> #include "jni.h" +#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + static jint add(JNIEnv */* env */, jobject /* thiz */, jint a, jint b) { int result = a + b; diff --git a/media/OWNERS b/media/OWNERS new file mode 100644 index 000000000000..8f405e98545b --- /dev/null +++ b/media/OWNERS @@ -0,0 +1,4 @@ +elaurent@google.com +etalvala@google.com +lajos@google.com +marcone@google.com diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java index 1a54d6a3396b..b98f27ea62d0 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/EnableZenModeDialog.java @@ -76,6 +76,8 @@ public class EnableZenModeDialog { protected Uri mForeverId; private int mBucketIndex = -1; + @VisibleForTesting + protected NotificationManager mNotificationManager; private AlarmManager mAlarmManager; private int mUserId; private boolean mAttached; @@ -98,7 +100,7 @@ public class EnableZenModeDialog { } public Dialog createDialog() { - NotificationManager noMan = (NotificationManager) mContext. + mNotificationManager = (NotificationManager) mContext. getSystemService(Context.NOTIFICATION_SERVICE); mForeverId = Condition.newId(mContext).appendPath("forever").build(); mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); @@ -131,7 +133,8 @@ public class EnableZenModeDialog { Slog.d(TAG, "Invalid manual condition: " + tag.condition); } // always triggers priority-only dnd with chosen condition - noMan.setZenMode(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, + mNotificationManager.setZenMode( + Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, getRealConditionId(tag.condition), TAG); } }); @@ -465,7 +468,16 @@ public class EnableZenModeDialog { mZenAlarmWarning.setVisibility(warningText == null ? View.GONE : View.VISIBLE); } - private String computeAlarmWarningText(Condition condition) { + @VisibleForTesting + protected String computeAlarmWarningText(Condition condition) { + boolean allowAlarms = (mNotificationManager.getNotificationPolicy().priorityCategories + & NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS) != 0; + + // don't show alarm warning if alarms are allowed to bypass dnd + if (allowAlarms) { + return null; + } + final long now = System.currentTimeMillis(); final long nextAlarm = getNextAlarm(); if (nextAlarm < now) { @@ -483,14 +495,19 @@ public class EnableZenModeDialog { if (warningRes == 0) { return null; } + + return mContext.getResources().getString(warningRes, getTime(nextAlarm, now)); + } + + @VisibleForTesting + protected String getTime(long nextAlarm, long now) { final boolean soon = (nextAlarm - now) < 24 * 60 * 60 * 1000; final boolean is24 = DateFormat.is24HourFormat(mContext, ActivityManager.getCurrentUser()); final String skeleton = soon ? (is24 ? "Hm" : "hma") : (is24 ? "EEEHm" : "EEEhma"); final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); final CharSequence formattedTime = DateFormat.format(pattern, nextAlarm); final int templateRes = soon ? R.string.alarm_template : R.string.alarm_template_far; - final String template = mContext.getResources().getString(templateRes, formattedTime); - return mContext.getResources().getString(warningRes, template); + return mContext.getResources().getString(templateRes, formattedTime); } // used as the view tag on condition rows diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java index 9b5da4ae1f95..ccd2f538c731 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/EnableZenModeDialogTest.java @@ -17,15 +17,22 @@ package com.android.settingslib.notification; import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; import static junit.framework.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.app.Fragment; +import android.app.NotificationManager; import android.content.Context; +import android.content.res.Resources; import android.net.Uri; import android.service.notification.Condition; import android.view.LayoutInflater; @@ -46,7 +53,11 @@ public class EnableZenModeDialogTest { @Mock private Context mContext; @Mock + private Resources mResources; + @Mock private Fragment mFragment; + @Mock + private NotificationManager mNotificationManager; private Context mShadowContext; private LayoutInflater mLayoutInflater; @@ -58,6 +69,7 @@ public class EnableZenModeDialogTest { MockitoAnnotations.initMocks(this); mShadowContext = RuntimeEnvironment.application; when(mContext.getApplicationContext()).thenReturn(mContext); + when(mContext.getResources()).thenReturn(mResources); when(mFragment.getContext()).thenReturn(mShadowContext); mLayoutInflater = LayoutInflater.from(mShadowContext); @@ -67,6 +79,10 @@ public class EnableZenModeDialogTest { mController.mForeverId = Condition.newId(mContext).appendPath("forever").build(); when(mContext.getString(com.android.internal.R.string.zen_mode_forever)) .thenReturn("testSummary"); + NotificationManager.Policy alarmsEnabledPolicy = new NotificationManager.Policy( + NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0); + doReturn(alarmsEnabledPolicy).when(mNotificationManager).getNotificationPolicy(); + mController.mNotificationManager = mNotificationManager; mController.getContentView(); // these methods use static calls to ZenModeConfig which would normally fail in robotests, @@ -141,4 +157,38 @@ public class EnableZenModeDialogTest { assertFalse(mController.getConditionTagAt( EnableZenModeDialog.COUNTDOWN_ALARM_CONDITION_INDEX).rb.isChecked()); } + + @Test + public void testNoAlarmWarning() { + // setup alarm + long now = System.currentTimeMillis(); + doReturn(now + 100000).when(mController).getNextAlarm(); + doReturn("").when(mController).getTime(anyLong(), anyLong()); + + // allow alarms + when(mNotificationManager.getNotificationPolicy()).thenReturn( + new NotificationManager.Policy( + NotificationManager.Policy.PRIORITY_CATEGORY_ALARMS, 0, 0, 0)); + + // alarm warning should be null + assertNull(mController.computeAlarmWarningText(null)); + } + + @Test + public void testAlarmWarning() { + // setup alarm + long now = System.currentTimeMillis(); + doReturn(now + 1000000).when(mController).getNextAlarm(); + doReturn("").when(mController).getTime(anyLong(), anyLong()); + + // don't allow alarms to bypass dnd + when(mNotificationManager.getNotificationPolicy()).thenReturn( + new NotificationManager.Policy(0, 0, 0, 0)); + + // return a string if mResources is asked to retrieve a string + when(mResources.getString(anyInt(), anyString())).thenReturn(""); + + // alarm warning should NOT be null + assertNotNull(mController.computeAlarmWarningText(null)); + } }
\ No newline at end of file diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS index af6dd77224c4..7c97ca6103aa 100644 --- a/packages/SystemUI/OWNERS +++ b/packages/SystemUI/OWNERS @@ -2,19 +2,23 @@ set noparent dsandler@google.com +adamcohen@google.com asc@google.com ashaikh@google.com beverlyt@google.com cinek@google.com cwren@google.com +dupin@google.com evanlaird@google.com jmonk@google.com jaggies@google.com jjaggi@google.com juliacr@google.com -dupin@google.com madym@google.com +ngmatthew@google.com roosa@google.com shahrk@google.com +sunnygoyal@google.com +twickham@google.com winsonc@google.com diff --git a/packages/SystemUI/res/drawable/ic_lock_lockdown.xml b/packages/SystemUI/res/drawable/ic_lock_lockdown.xml new file mode 100644 index 000000000000..b517fc89e094 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_lock_lockdown.xml @@ -0,0 +1,25 @@ +<!-- +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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24.0dp" + android:height="24.0dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + + <path + android:fillColor="#757575" + android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/> +</vector> diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index 97472a49187a..cf88adee7a62 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -71,23 +71,19 @@ android:singleLine="true" /> </LinearLayout> - <FrameLayout + <View + android:id="@+id/qs_drag_handle_view" android:layout_width="24dp" - android:layout_height="match_parent" > - <View - android:id="@+id/qs_drag_handle_view" - android:layout_width="match_parent" - android:layout_height="4dp" - android:layout_marginTop="28dp" - android:background="@drawable/qs_footer_drag_handle" /> - </FrameLayout> + android:layout_height="4dp" + android:layout_gravity="center" + android:background="@drawable/qs_footer_drag_handle" /> - <LinearLayout + <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@+id/qs_footer_actions_container" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:gravity="end" > + android:gravity="center_vertical|end" > <com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch" android:layout_width="48dp" @@ -113,7 +109,7 @@ android:clipToPadding="false" android:contentDescription="@string/accessibility_quick_settings_edit" android:focusable="true" - android:padding="16dp" + android:padding="15dp" android:src="@drawable/ic_mode_edit" android:tint="?android:attr/colorForeground"/> @@ -131,6 +127,7 @@ android:layout_height="match_parent" android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_quick_settings_settings" + android:padding="15dp" android:src="@drawable/ic_settings_16dp" android:tint="?android:attr/colorForeground"/> @@ -145,7 +142,7 @@ android:visibility="invisible"/> </com.android.systemui.statusbar.AlphaOptimizedFrameLayout> - </LinearLayout> + </com.android.keyguard.AlphaOptimizedLinearLayout> </LinearLayout> </com.android.systemui.qs.QSFooterImpl> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a62f38b946ee..d11ab4298b82 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -230,7 +230,7 @@ <!-- The height of the quick settings footer that holds the user switcher, settings icon, etc. --> - <dimen name="qs_footer_height">48dp</dimen> + <dimen name="qs_footer_height">56dp</dimen> <!-- The padding between the notifications and the quick settings container --> <dimen name="qs_notification_padding">@dimen/notification_side_paddings</dimen> @@ -337,7 +337,7 @@ <dimen name="qs_footer_padding_end">24dp</dimen> <dimen name="qs_footer_icon_size">16dp</dimen> <!-- Difference between drag handle margin in QQS and expanded QS --> - <dimen name="qs_footer_drag_handle_offset">6dp</dimen> + <dimen name="qs_footer_drag_handle_offset">10dp</dimen> <dimen name="qs_notif_collapsed_space">64dp</dimen> @@ -513,7 +513,7 @@ <dimen name="multi_user_avatar_keyguard_size">22dp</dimen> <!-- The width of user avatar when expanded --> - <dimen name="multi_user_avatar_expanded_size">16dp</dimen> + <dimen name="multi_user_avatar_expanded_size">18dp</dimen> <!-- The font size of the time when collapsed in QS --> <dimen name="qs_time_collapsed_size">14sp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 1aea5e7f4a80..259bff28d458 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -688,7 +688,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } private Action getLockdownAction() { - return new SinglePressAction(R.drawable.ic_lock_lock, + return new SinglePressAction(com.android.systemui.R.drawable.ic_lock_lockdown, R.string.global_action_lockdown) { @Override diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index fe3ffb926305..b9919a3f5c12 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -174,7 +174,8 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, .addFloat(mDivider, "alpha", 0, 1) .addFloat(mCarrierText, "alpha", 0, 1) .addFloat(mActionsContainer, "alpha", 0, 1) - .addFloat(mDragHandle, "translationY", 0, -mDragHandleExpandOffset) + .addFloat(mDragHandle, "translationY", mDragHandleExpandOffset, 0) + .addFloat(mDragHandle, "alpha", 1, 0) .build(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java index bb2f59718ffb..f4da0c38338d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubController.java @@ -89,6 +89,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene private int mLightTrackColor; private int mDarkTrackColor; private float mDarkIntensity; + private View mHomeButtonView; private final Handler mHandler = new Handler(); private final Interpolator mQuickScrubEndInterpolator = new DecelerateInterpolator(); @@ -114,11 +115,10 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene if (!mQuickScrubActive) { pos = mDragPositive ? Math.min((int) mTranslation, pos) : Math.max((int) mTranslation, pos); } - final View homeView = mNavigationBarView.getHomeButton().getCurrentView(); if (mIsVertical) { - homeView.setTranslationY(pos); + mHomeButtonView.setTranslationY(pos); } else { - homeView.setTranslationX(pos); + mHomeButtonView.setTranslationX(pos); } }; @@ -126,6 +126,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene @Override public void onAnimationEnd(Animator animation) { mNavigationBarView.getHomeButton().setClickable(true); + mHomeButtonView = null; mQuickScrubActive = false; mTranslation = 0; } @@ -226,6 +227,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene case MotionEvent.ACTION_DOWN: { int x = (int) event.getX(); int y = (int) event.getY(); + mHomeButtonView = homeButton.getCurrentView(); if (isQuickScrubEnabled() && mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME) { mTouchDownX = x; @@ -305,9 +307,9 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene mTranslation /= SWITCH_STICKINESS; } if (mIsVertical) { - homeButton.getCurrentView().setTranslationY(mTranslation); + mHomeButtonView.setTranslationY(mTranslation); } else { - homeButton.getCurrentView().setTranslationX(mTranslation); + mHomeButtonView.setTranslationX(mTranslation); } } } @@ -315,7 +317,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene } case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - endQuickScrub(); + endQuickScrub(true /* animate */); break; } return mDraggingActive || mQuickScrubActive; @@ -357,6 +359,11 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene @Override public void setBarState(boolean isVertical, boolean isRTL) { + final boolean changed = (mIsVertical != isVertical) || (mIsRTL != isRTL); + if (changed) { + // End quickscrub if the state changes mid-transition + endQuickScrub(false /* animate */); + } mIsVertical = isVertical; mIsRTL = isRTL; try { @@ -392,7 +399,7 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene } } - private void endQuickScrub() { + private void endQuickScrub(boolean animate) { mHandler.removeCallbacks(mLongPressRunnable); if (mDraggingActive || mQuickScrubActive) { mButtonAnimator.setIntValues((int) mTranslation, 0); @@ -406,6 +413,9 @@ public class QuickScrubController extends GestureDetector.SimpleOnGestureListene } catch (RemoteException e) { Log.e(TAG, "Failed to send end of quick scrub.", e); } + if (!animate) { + mQuickScrubEndAnimator.end(); + } } mDraggingActive = false; } diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java index c36bb6d2e096..5b5d18f4aaf7 100644 --- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java @@ -446,8 +446,10 @@ class MagnificationController implements Handler.Callback { mMagnificationRegion.getBounds(viewport); final MagnificationSpec spec = mCurrentMagnificationSpec; final float oldScale = spec.scale; - final float oldCenterX = (viewport.width() / 2.0f - spec.offsetX) / oldScale; - final float oldCenterY = (viewport.height() / 2.0f - spec.offsetY) / oldScale; + final float oldCenterX + = (viewport.width() / 2.0f - spec.offsetX + viewport.left) / oldScale; + final float oldCenterY + = (viewport.height() / 2.0f - spec.offsetY + viewport.top) / oldScale; final float normPivotX = (pivotX - spec.offsetX) / oldScale; final float normPivotY = (pivotY - spec.offsetY) / oldScale; final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale); diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java index d5a722bba723..ebb5040a7073 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java @@ -580,7 +580,7 @@ public final class AutofillManagerService extends SystemService { @Override public int startSession(IBinder activityToken, IBinder appCallback, AutofillId autofillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, - ComponentName componentName) { + ComponentName componentName, boolean compatMode) { activityToken = Preconditions.checkNotNull(activityToken, "activityToken"); appCallback = Preconditions.checkNotNull(appCallback, "appCallback"); @@ -599,7 +599,7 @@ public final class AutofillManagerService extends SystemService { synchronized (mLock) { final AutofillManagerServiceImpl service = getServiceForUserLocked(userId); return service.startSessionLocked(activityToken, getCallingUid(), appCallback, - autofillId, bounds, value, hasCallback, flags, componentName); + autofillId, bounds, value, hasCallback, flags, componentName, compatMode); } } @@ -770,7 +770,7 @@ public final class AutofillManagerService extends SystemService { public int updateOrRestartSession(IBinder activityToken, IBinder appCallback, AutofillId autoFillId, Rect bounds, AutofillValue value, int userId, boolean hasCallback, int flags, ComponentName componentName, int sessionId, - int action) { + int action, boolean compatMode) { boolean restart = false; synchronized (mLock) { final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId); @@ -783,7 +783,7 @@ public final class AutofillManagerService extends SystemService { } if (restart) { return startSession(activityToken, appCallback, autoFillId, bounds, value, userId, - hasCallback, flags, componentName); + hasCallback, flags, componentName, compatMode); } // Nothing changed... diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java index 2dcc6da0be32..75ae2dc0bb4b 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -220,6 +220,17 @@ final class AutofillManagerServiceImpl { return mInfo.getServiceInfo().applicationInfo.uid; } + + @GuardedBy("mLock") + @Nullable + String getUrlBarResourceIdForCompatModeLocked(@NonNull String packageName) { + if (mInfo == null) { + Slog.w(TAG, "getUrlBarResourceIdForCompatModeLocked(): no mInfo"); + return null; + } + return mInfo.getUrlBarResourceId(packageName); + } + @Nullable String getServicePackageName() { final ComponentName serviceComponent = getServiceComponentName(); @@ -345,7 +356,7 @@ final class AutofillManagerServiceImpl { int startSessionLocked(@NonNull IBinder activityToken, int uid, @NonNull IBinder appCallbackToken, @NonNull AutofillId autofillId, @NonNull Rect virtualBounds, @Nullable AutofillValue value, boolean hasCallback, - int flags, @NonNull ComponentName componentName) { + int flags, @NonNull ComponentName componentName, boolean compatMode) { if (!isEnabledLocked()) { return 0; } @@ -375,7 +386,7 @@ final class AutofillManagerServiceImpl { pruneAbandonedSessionsLocked(); final Session newSession = createSessionByTokenLocked(activityToken, uid, appCallbackToken, - hasCallback, componentName, flags); + hasCallback, componentName, compatMode, flags); if (newSession == null) { return NO_SESSION; } @@ -481,7 +492,7 @@ final class AutofillManagerServiceImpl { @GuardedBy("mLock") private Session createSessionByTokenLocked(@NonNull IBinder activityToken, int uid, @NonNull IBinder appCallbackToken, boolean hasCallback, - @NonNull ComponentName componentName, int flags) { + @NonNull ComponentName componentName, boolean compatMode, int flags) { // use random ids so that one app cannot know that another app creates sessions int sessionId; int tries = 0; @@ -499,7 +510,8 @@ final class AutofillManagerServiceImpl { final Session newSession = new Session(this, mUi, mContext, mHandlerCaller, mUserId, mLock, sessionId, uid, activityToken, appCallbackToken, hasCallback, mUiLatencyHistory, - mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, flags); + mWtfHistory, mInfo.getServiceInfo().getComponentName(), componentName, compatMode, + flags); mSessions.put(newSession.id, newSession); return newSession; diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java index 02a62e10e111..5ef467d44e6a 100644 --- a/services/autofill/java/com/android/server/autofill/Helper.java +++ b/services/autofill/java/com/android/server/autofill/Helper.java @@ -18,11 +18,14 @@ package com.android.server.autofill; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.assist.AssistStructure; +import android.app.assist.AssistStructure.ViewNode; import android.metrics.LogMaker; import android.os.Bundle; import android.service.autofill.Dataset; import android.util.ArrayMap; import android.util.ArraySet; +import android.util.Slog; import android.view.autofill.AutofillId; import android.view.autofill.AutofillValue; @@ -31,11 +34,14 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedList; import java.util.Objects; import java.util.Set; public final class Helper { + private static final String TAG = "AutofillHelper"; + /** * Defines a logging flag that can be dynamically changed at runtime using * {@code cmd autofill set log_level debug}. @@ -121,4 +127,61 @@ public final class Helper { pw.print(text.length()); pw.println("_chars"); } } + + /** + * Finds the {@link ViewNode} that has the requested {@code autofillId}, if any. + */ + @Nullable + public static ViewNode findViewNodeByAutofillId(@NonNull AssistStructure structure, + @NonNull AutofillId autofillId) { + return findViewNode(structure, (node) -> { + return autofillId.equals(node.getAutofillId()); + }); + } + + private static ViewNode findViewNode(@NonNull AssistStructure structure, + @NonNull ViewNodeFilter filter) { + final LinkedList<ViewNode> nodesToProcess = new LinkedList<>(); + final int numWindowNodes = structure.getWindowNodeCount(); + for (int i = 0; i < numWindowNodes; i++) { + nodesToProcess.add(structure.getWindowNodeAt(i).getRootViewNode()); + } + while (!nodesToProcess.isEmpty()) { + final ViewNode node = nodesToProcess.removeFirst(); + if (filter.matches(node)) { + return node; + } + for (int i = 0; i < node.getChildCount(); i++) { + nodesToProcess.addLast(node.getChildAt(i)); + } + } + + return null; + } + + /** + * Sanitize the {@code webDomain} property of the URL bar node on compat mode. + */ + public static void sanitizeUrlBar(@NonNull AssistStructure structure, + @NonNull String urlBarId) { + final ViewNode urlBarNode = findViewNode(structure, (node) -> { + return urlBarId.equals(node.getIdEntry()); + }); + if (urlBarNode != null) { + final String domain = urlBarNode.getText().toString(); + if (domain.isEmpty()) { + if (sDebug) Slog.d(TAG, "sanitizeUrlBar(): empty on " + urlBarId); + return; + } + urlBarNode.setWebDomain(domain); + if (sDebug) { + Slog.d(TAG, "sanitizeUrlBar(): id=" + urlBarId + ", domain=" + + urlBarNode.getWebDomain()); + } + } + } + + private interface ViewNodeFilter { + boolean matches(ViewNode node); + } } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index 4a247049d395..55c36b072c96 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -140,6 +140,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState /** Component that's being auto-filled */ @NonNull private final ComponentName mComponentName; + /** Whether the app being autofilled is running in compat mode. */ + private final boolean mCompatMode; + @GuardedBy("mLock") private final ArrayMap<AutofillId, ViewState> mViewStates = new ArrayMap<>(); @@ -263,6 +266,15 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState componentNameFromApp == null ? "null" : componentNameFromApp.flattenToShortString())); } + if (mCompatMode) { + // Sanitize URL bar, if needed + final String urlBarId = mService.getUrlBarResourceIdForCompatModeLocked( + mComponentName.getPackageName()); + if (sDebug) Slog.d(TAG, "url_bar in compat mode: " + urlBarId); + if (urlBarId != null) { + Helper.sanitizeUrlBar(structure, urlBarId); + } + } structure.sanitizeForParceling(true); // Flags used to start the session. @@ -476,7 +488,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState @NonNull IBinder client, boolean hasCallback, @NonNull LocalLog uiLatencyHistory, @NonNull LocalLog wtfHistory, @NonNull ComponentName serviceComponentName, @NonNull ComponentName componentName, - int flags) { + boolean compatMode, int flags) { id = sessionId; mFlags = flags; this.uid = uid; @@ -491,6 +503,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mUiLatencyHistory = uiLatencyHistory; mWtfHistory = wtfHistory; mComponentName = componentName; + mCompatMode = compatMode; mClient = IAutoFillManagerClient.Stub.asInterface(client); mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED) @@ -1537,7 +1550,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState final int numContexts = mContexts.size(); for (int i = numContexts - 1; i >= 0; i--) { final FillContext context = mContexts.get(i); - final ViewNode node = context.findViewNodeByAutofillId(id); + final ViewNode node = Helper.findViewNodeByAutofillId(context.getStructure(), id); if (node != null) { final AutofillValue value = node.getAutofillValue(); if (sDebug) { @@ -1561,7 +1574,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState for (int i = numContexts - 1; i >= 0; i--) { final FillContext context = mContexts.get(i); - final ViewNode node = context.findViewNodeByAutofillId(id); + final ViewNode node = Helper.findViewNodeByAutofillId(context.getStructure(), id); if (node != null && node.getAutofillOptions() != null) { return node.getAutofillOptions(); } @@ -2288,6 +2301,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState pw.print(prefix); pw.print("mHasCallback: "); pw.println(mHasCallback); pw.print(prefix); pw.print("mClientState: "); pw.println( Helper.bundleToString(mClientState)); + pw.print(prefix); pw.print("mCompatMode: "); pw.println(mCompatMode); pw.print(prefix); pw.print("mSelectedDatasetIds: "); pw.println(mSelectedDatasetIds); mRemoteFillService.dump(prefix, pw); } diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java index ef82f36fa79f..fba03774e5d9 100644 --- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java +++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java @@ -43,7 +43,10 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** @@ -65,12 +68,13 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { // There is some accuracy error in wifi reports so allow some slop in the results. private static final long MAX_WIFI_STATS_SAMPLE_ERROR_MILLIS = 750; - private final ExecutorService mExecutorService = Executors.newSingleThreadExecutor( - (ThreadFactory) r -> { - Thread t = new Thread(r, "batterystats-worker"); - t.setPriority(Thread.NORM_PRIORITY); - return t; - }); + private final ScheduledExecutorService mExecutorService = + Executors.newSingleThreadScheduledExecutor( + (ThreadFactory) r -> { + Thread t = new Thread(r, "batterystats-worker"); + t.setPriority(Thread.NORM_PRIORITY); + return t; + }); private final Context mContext; private final BatteryStatsImpl mStats; @@ -85,8 +89,20 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { private String mCurrentReason = null; @GuardedBy("this") + private boolean mOnBattery; + + @GuardedBy("this") + private boolean mOnBatteryScreenOff; + + @GuardedBy("this") + private boolean mUseLatestStates = true; + + @GuardedBy("this") private final IntArray mUidsToRemove = new IntArray(); + @GuardedBy("this") + private Future<?> mWakelockChangesUpdate; + private final Object mWorkerLock = new Object(); @GuardedBy("mWorkerLock") @@ -157,6 +173,50 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { return null; } + @Override + public Future<?> scheduleCpuSyncDueToScreenStateChange( + boolean onBattery, boolean onBatteryScreenOff) { + synchronized (BatteryExternalStatsWorker.this) { + if (mCurrentFuture == null || (mUpdateFlags & UPDATE_CPU) == 0) { + mOnBattery = onBattery; + mOnBatteryScreenOff = onBatteryScreenOff; + mUseLatestStates = false; + } + return scheduleSyncLocked("screen-state", UPDATE_CPU); + } + } + + @Override + public Future<?> scheduleCpuSyncDueToWakelockChange(long delayMillis) { + if (mExecutorService.isShutdown()) { + return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); + } + + if (mWakelockChangesUpdate != null) { + // If there's already a scheduled task, leave it as is if we're trying to re-schedule + // it again with a delay, otherwise cancel and re-schedule it. + if (delayMillis == 0) { + mWakelockChangesUpdate.cancel(false); + } else { + return mWakelockChangesUpdate; + } + } + + mWakelockChangesUpdate = mExecutorService.schedule(() -> { + scheduleSync("wakelock-change", UPDATE_CPU); + scheduleRunnable(() -> mStats.postBatteryNeedsCpuUpdateMsg()); + mWakelockChangesUpdate = null; + }, delayMillis, TimeUnit.MILLISECONDS); + return mWakelockChangesUpdate; + } + + @Override + public void cancelCpuSyncDueToWakelockChange() { + if (mWakelockChangesUpdate != null) { + mWakelockChangesUpdate.cancel(false); + } + } + public synchronized Future<?> scheduleWrite() { if (mExecutorService.isShutdown()) { return CompletableFuture.failedFuture(new IllegalStateException("worker shutdown")); @@ -204,14 +264,21 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { final int updateFlags; final String reason; final int[] uidsToRemove; + final boolean onBattery; + final boolean onBatteryScreenOff; + final boolean useLatestStates; synchronized (BatteryExternalStatsWorker.this) { updateFlags = mUpdateFlags; reason = mCurrentReason; uidsToRemove = mUidsToRemove.size() > 0 ? mUidsToRemove.toArray() : EmptyArray.INT; + onBattery = mOnBattery; + onBatteryScreenOff = mOnBatteryScreenOff; + useLatestStates = mUseLatestStates; mUpdateFlags = 0; mCurrentReason = null; mUidsToRemove.clear(); mCurrentFuture = null; + mUseLatestStates = true; } synchronized (mWorkerLock) { @@ -219,7 +286,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason); } try { - updateExternalStatsLocked(reason, updateFlags); + updateExternalStatsLocked(reason, updateFlags, onBattery, + onBatteryScreenOff, useLatestStates); } finally { if (DEBUG) { Slog.d(TAG, "end updateExternalStatsSync"); @@ -250,7 +318,8 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { }; @GuardedBy("mWorkerLock") - private void updateExternalStatsLocked(final String reason, int updateFlags) { + private void updateExternalStatsLocked(final String reason, int updateFlags, + boolean onBattery, boolean onBatteryScreenOff, boolean useLatestStates) { // We will request data from external processes asynchronously, and wait on a timeout. SynchronousResultReceiver wifiReceiver = null; SynchronousResultReceiver bluetoothReceiver = null; @@ -306,7 +375,14 @@ class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStatsSync { reason, 0); if ((updateFlags & UPDATE_CPU) != 0) { - mStats.updateCpuTimeLocked(); + if (useLatestStates) { + onBattery = mStats.isOnBatteryLocked(); + onBatteryScreenOff = mStats.isOnBatteryScreenOffLocked(); + } + mStats.updateCpuTimeLocked(onBattery, onBatteryScreenOff); + } + + if ((updateFlags & UPDATE_ALL) != 0) { mStats.updateKernelWakelocksLocked(); mStats.updateKernelMemoryBandwidthLocked(); } diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index ea52782027ba..9d1adb23957b 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -1057,7 +1057,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub // to block such a low level service like BatteryService on external stats like WiFi. mWorker.scheduleRunnable(() -> { synchronized (mStats) { - final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE; + final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status); if (mStats.isOnBattery() == onBattery) { // The battery state has not changed, so we don't need to sync external // stats immediately. diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index fffe7dca7fc4..c5424b7ddbcf 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -551,8 +551,6 @@ public class AudioService extends IAudioService.Stub // Used to play ringtones outside system_server private volatile IRingtonePlayer mRingtonePlayer; - private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED; - // Request to override default use of A2DP for media. private boolean mBluetoothA2dpEnabled; private final Object mBluetoothA2dpEnabledLock = new Object(); @@ -571,8 +569,6 @@ public class AudioService extends IAudioService.Stub AudioSystem.DEVICE_OUT_AUX_LINE; int mFullVolumeDevices = 0; - // TODO merge orientation and rotation - private final boolean mMonitorOrientation; private final boolean mMonitorRotation; private boolean mDockAudioMediaEnabled = true; @@ -788,13 +784,6 @@ public class AudioService extends IAudioService.Stub intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - // TODO merge orientation and rotation - mMonitorOrientation = SystemProperties.getBoolean("ro.audio.monitorOrientation", false); - if (mMonitorOrientation) { - Log.v(TAG, "monitoring device orientation"); - // initialize orientation in AudioSystem - setOrientationForAudioSystem(); - } mMonitorRotation = SystemProperties.getBoolean("ro.audio.monitorRotation", false); if (mMonitorRotation) { RotationHelper.init(mContext, mAudioHandler); @@ -963,10 +952,7 @@ public class AudioService extends IAudioService.Stub // Restore ringer mode setRingerModeInt(getRingerModeInternal(), false); - // Reset device orientation (if monitored for this device) - if (mMonitorOrientation) { - setOrientationForAudioSystem(); - } + // Reset device rotation (if monitored for this device) if (mMonitorRotation) { RotationHelper.updateOrientation(); } @@ -6192,24 +6178,15 @@ public class AudioService extends IAudioService.Stub // Device orientation //========================================================================================== /** - * Handles device configuration changes that may map to a change in the orientation - * or orientation. - * Monitoring orientation and rotation is optional, and is defined by the definition and value - * of the "ro.audio.monitorOrientation" and "ro.audio.monitorRotation" system properties. + * Handles device configuration changes that may map to a change in rotation. + * Monitoring rotation is optional, and is defined by the definition and value + * of the "ro.audio.monitorRotation" system property. */ private void handleConfigurationChanged(Context context) { try { - // reading new orientation "safely" (i.e. under try catch) in case anything - // goes wrong when obtaining resources and configuration + // reading new configuration "safely" (i.e. under try catch) in case anything + // goes wrong. Configuration config = context.getResources().getConfiguration(); - // TODO merge rotation and orientation - if (mMonitorOrientation) { - int newOrientation = config.orientation; - if (newOrientation != mDeviceOrientation) { - mDeviceOrientation = newOrientation; - setOrientationForAudioSystem(); - } - } sendMsg(mAudioHandler, MSG_CONFIGURE_SAFE_MEDIA_VOLUME, SENDMSG_REPLACE, @@ -6261,30 +6238,6 @@ public class AudioService extends IAudioService.Stub } } - //TODO move to an external "orientation helper" class - private void setOrientationForAudioSystem() { - switch (mDeviceOrientation) { - case Configuration.ORIENTATION_LANDSCAPE: - //Log.i(TAG, "orientation is landscape"); - AudioSystem.setParameters("orientation=landscape"); - break; - case Configuration.ORIENTATION_PORTRAIT: - //Log.i(TAG, "orientation is portrait"); - AudioSystem.setParameters("orientation=portrait"); - break; - case Configuration.ORIENTATION_SQUARE: - //Log.i(TAG, "orientation is square"); - AudioSystem.setParameters("orientation=square"); - break; - case Configuration.ORIENTATION_UNDEFINED: - //Log.i(TAG, "orientation is undefined"); - AudioSystem.setParameters("orientation=undefined"); - break; - default: - Log.e(TAG, "Unknown orientation"); - } - } - // Handles request to override default use of A2DP for media. // Must be called synchronized on mConnectedDevices public void setBluetoothA2dpOnInt(boolean on, String eventSource) { diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java index 152c910e65b7..23a66baf4445 100644 --- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java +++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java @@ -170,11 +170,13 @@ public class RecoverableKeyStoreManager { certXml = CertXml.parse(recoveryServiceCertFile); } catch (CertParsingException e) { // TODO: Do not use raw key bytes anymore once the other components are updated - Log.d(TAG, "Failed to parse the cert file", e); + Log.d(TAG, "Failed to parse the input as a cert file: " + HexDump.toHexString( + recoveryServiceCertFile)); PublicKey publicKey = parseEcPublicKey(recoveryServiceCertFile); if (mDatabase.setRecoveryServicePublicKey(userId, uid, publicKey) > 0) { mDatabase.setShouldCreateSnapshot(userId, uid, true); } + Log.d(TAG, "Successfully set the input as the raw public key"); return; } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 44b83d8cf759..0a870978d160 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -1178,7 +1178,7 @@ public class ZenModeHelper { extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mContext.getResources().getString(R.string.global_action_settings)); return new Notification.Builder(mContext, SystemNotificationChannels.SYSTEM_CHANGES) - .setSmallIcon(R.drawable.ic_settings) + .setSmallIcon(R.drawable.ic_settings_24dp) .setContentTitle(mContext.getResources().getString( R.string.zen_upgrade_notification_title)) .setContentText(mContext.getResources().getString( diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index ce3f512deccf..8155656cd5f4 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1766,6 +1766,9 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree layer += Z_BOOST_BASE; } leash.setLayer(layer); + + final DisplayContent dc = getDisplayContent(); + dc.assignStackOrdering(t); } /** diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index f421bf46e84a..2d32c81d13a5 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3524,39 +3524,47 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo @Override void assignChildLayers(SurfaceControl.Transaction t) { + assignStackOrdering(t); + for (int i = 0; i < mChildren.size(); i++) { + final TaskStack s = mChildren.get(i); + s.assignChildLayers(t); + } + } + + void assignStackOrdering(SurfaceControl.Transaction t) { final int HOME_STACK_STATE = 0; final int NORMAL_STACK_STATE = 1; final int ALWAYS_ON_TOP_STATE = 2; int layer = 0; + int layerForAnimationLayer = 0; + for (int state = 0; state <= ALWAYS_ON_TOP_STATE; state++) { for (int i = 0; i < mChildren.size(); i++) { final TaskStack s = mChildren.get(i); - if (state == HOME_STACK_STATE && s.isActivityTypeHome()) { - s.assignLayer(t, layer++); - } else if (state == NORMAL_STACK_STATE && !s.isActivityTypeHome() - && !s.isAlwaysOnTop()) { - s.assignLayer(t, layer++); - if (s.inSplitScreenWindowingMode() && mSplitScreenDividerAnchor != null) { - t.setLayer(mSplitScreenDividerAnchor, layer++); - } - } else if (state == ALWAYS_ON_TOP_STATE && s.isAlwaysOnTop()) { - s.assignLayer(t, layer++); + if (state == HOME_STACK_STATE && !s.isActivityTypeHome()) { + continue; + } else if (state == NORMAL_STACK_STATE && (s.isActivityTypeHome() + || s.isAlwaysOnTop())) { + continue; + } else if (state == ALWAYS_ON_TOP_STATE && !s.isAlwaysOnTop()) { + continue; + } + s.assignLayer(t, layer++); + if (s.inSplitScreenWindowingMode() && mSplitScreenDividerAnchor != null) { + t.setLayer(mSplitScreenDividerAnchor, layer++); + } + if (s.isSelfOrChildAnimating()) { + // Ensure the animation layer ends up above the + // highest animating stack and no higher. + layerForAnimationLayer = layer++; } - } - // The appropriate place for App-Transitions to occur is right - // above all other animations but still below things in the Picture-and-Picture - // windowing mode. - if (state == NORMAL_STACK_STATE && mAppAnimationLayer != null) { - t.setLayer(mAppAnimationLayer, layer++); } } - for (int i = 0; i < mChildren.size(); i++) { - final TaskStack s = mChildren.get(i); - s.assignChildLayers(t); + if (mAppAnimationLayer != null) { + t.setLayer(mAppAnimationLayer, layerForAnimationLayer); } - } @Override @@ -3854,4 +3862,8 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo super.prepareSurfaces(); } + + void assignStackOrdering(SurfaceControl.Transaction t) { + mTaskStackContainers.assignStackOrdering(t); + } } diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 97a2954b2b16..e4edeb877b70 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -24,15 +24,15 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_W import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; -import android.app.ActivityManager; import android.app.ActivityManager.TaskSnapshot; import android.app.WindowConfiguration; -import android.graphics.GraphicBuffer; import android.graphics.Point; import android.graphics.Rect; import android.os.Binder; +import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; +import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.view.IRecentsAnimationController; @@ -41,6 +41,7 @@ import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; +import com.google.android.collect.Sets; import java.io.PrintWriter; import java.util.ArrayList; @@ -99,17 +100,13 @@ public class RecentsAnimationController { final TaskAnimationAdapter adapter = mPendingAnimations.get(i); final Task task = adapter.mTask; if (task.mTaskId == taskId) { - // TODO: Save this screenshot as the task snapshot? - final Rect taskFrame = new Rect(); - task.getBounds(taskFrame); - final GraphicBuffer buffer = SurfaceControl.captureLayers( - task.getSurfaceControl().getHandle(), taskFrame, 1f); - final AppWindowToken topChild = task.getTopChild(); - final WindowState mainWindow = topChild.findMainWindow(); - return new TaskSnapshot(buffer, topChild.getConfiguration().orientation, - mainWindow.mContentInsets, - ActivityManager.isLowRamDeviceStatic() /* reduced */, - 1.0f /* scale */); + final TaskSnapshotController snapshotController = + mService.mTaskSnapshotController; + final ArraySet<Task> tasks = Sets.newArraySet(task); + snapshotController.snapshotTasks(tasks); + snapshotController.addSkipClosingAppSnapshotTasks(tasks); + return snapshotController.getSnapshot(taskId, 0 /* userId */, + false /* restoreFromDisk */, false /* reducedResolution */); } } return null; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index a7a2b534131d..3d7b32ca1a9d 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -92,6 +92,7 @@ class TaskSnapshotController { private final TaskSnapshotPersister mPersister = new TaskSnapshotPersister( Environment::getDataSystemCeDirectory); private final TaskSnapshotLoader mLoader = new TaskSnapshotLoader(mPersister); + private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>(); private final ArraySet<Task> mTmpTasks = new ArraySet<>(); private final Handler mHandler = new Handler(); @@ -149,10 +150,20 @@ class TaskSnapshotController { // either closing or hidden. getClosingTasks(closingApps, mTmpTasks); snapshotTasks(mTmpTasks); + mSkipClosingAppSnapshotTasks.clear(); + } + /** + * Adds the given {@param tasks} to the list of tasks which should not have their snapshots + * taken upon the next processing of the set of closing apps. The caller is responsible for + * calling {@link #snapshotTasks} to ensure that the task has an up-to-date snapshot. + */ + @VisibleForTesting + void addSkipClosingAppSnapshotTasks(ArraySet<Task> tasks) { + mSkipClosingAppSnapshotTasks.addAll(tasks); } - private void snapshotTasks(ArraySet<Task> tasks) { + void snapshotTasks(ArraySet<Task> tasks) { for (int i = tasks.size() - 1; i >= 0; i--) { final Task task = tasks.valueAt(i); final int mode = getSnapshotMode(task); @@ -295,7 +306,7 @@ class TaskSnapshotController { // If the task of the app is not visible anymore, it means no other app in that task // is opening. Thus, the task is closing. - if (task != null && !task.isVisible()) { + if (task != null && !task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) { outClosingTasks.add(task); } } diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index fa4474ba3060..93e9137e322f 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -1129,7 +1129,7 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< scheduleAnimation(); } - private void reassignLayer(Transaction t) { + void reassignLayer(Transaction t) { final WindowContainer parent = getParent(); if (parent != null) { parent.assignChildLayers(t); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 72f95fb74f4f..0b032815f1fe 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -41,6 +41,7 @@ cc_library_static { "com_android_server_tv_TvUinputBridge.cpp", "com_android_server_tv_TvInputHal.cpp", "com_android_server_vr_VrManagerService.cpp", + "com_android_server_UsbAlsaJackDetector.cpp", "com_android_server_UsbDeviceManager.cpp", "com_android_server_UsbDescriptorParser.cpp", "com_android_server_UsbMidiDevice.cpp", @@ -97,6 +98,7 @@ cc_defaults { "libgui", "libusbhost", "libsuspend", + "libtinyalsa", "libEGL", "libGLESv2", "libnetutils", diff --git a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp new file mode 100644 index 000000000000..e9d448234e17 --- /dev/null +++ b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp @@ -0,0 +1,152 @@ +/* + * 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. + */ + +#define LOG_TAG "UsbAlsaJackDetectorJNI" +#include "utils/Log.h" + +#include "jni.h" +#include <nativehelper/JNIHelp.h> +#include "android_runtime/AndroidRuntime.h" +#include "android_runtime/Log.h" + +#include <stdio.h> +#include <string.h> +#include <asm/byteorder.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <tinyalsa/asoundlib.h> + +#define DRIVER_NAME "/dev/usb_accessory" + +#define USB_IN_JACK_NAME "USB in Jack" +#define USB_OUT_JACK_NAME "USB out Jack" + +namespace android +{ + +static jboolean is_jack_connected(jint card, const char* control) { + struct mixer* card_mixer = mixer_open(card); + if (card_mixer == NULL) { + return true; + } + struct mixer_ctl* ctl = mixer_get_ctl_by_name(card_mixer, control); + if (!ctl) { + return true; + } + mixer_ctl_update(ctl); + int val = mixer_ctl_get_value(ctl, 0); + ALOGI("JACK %s - value %d\n", control, val); + mixer_close(card_mixer); + + return val != 0; +} + +static jboolean android_server_UsbAlsaJackDetector_hasJackDetect(JNIEnv* /* env */, + jobject /* thiz */, + jint card) +{ + struct mixer* card_mixer = mixer_open(card); + if (card_mixer == NULL) { + return false; + } + + jboolean has_jack = false; + if ((mixer_get_ctl_by_name(card_mixer, USB_IN_JACK_NAME) != NULL) || + (mixer_get_ctl_by_name(card_mixer, USB_OUT_JACK_NAME) != NULL)) { + has_jack = true; + } + mixer_close(card_mixer); + return has_jack; +} + + +static jboolean android_server_UsbAlsaJackDetector_inputJackConnected(JNIEnv* /* env */, + jobject /* thiz */, + jint card) +{ + return is_jack_connected(card, USB_IN_JACK_NAME); +} + + +static jboolean android_server_UsbAlsaJackDetector_outputJackConnected(JNIEnv* /* env */, + jobject /* thiz */, + jint card) +{ + return is_jack_connected(card, USB_OUT_JACK_NAME); +} + +static void android_server_UsbAlsaJackDetector_jackDetect(JNIEnv* env, + jobject thiz, + jint card) { + jclass jdclass = env->GetObjectClass(thiz); + jmethodID method_jackDetectCallback = env->GetMethodID(jdclass, "jackDetectCallback", "()Z"); + if (method_jackDetectCallback == NULL) { + ALOGE("Can't find jackDetectCallback"); + return; + } + + struct mixer* m = mixer_open(card); + if (!m) { + ALOGE("Jack detect unable to open mixer\n"); + return; + } + mixer_subscribe_events(m, 1); + do { + + // Wait for a mixer event. Retry if interrupted, exit on error. + int retval; + do { + retval = mixer_wait_event(m, -1); + } while (retval == -EINTR); + if (retval < 0) { + break; + } + mixer_consume_event(m); + } while (env->CallBooleanMethod(thiz, method_jackDetectCallback)); + + mixer_close(m); + return; +} + +static const JNINativeMethod method_table[] = { + { "nativeHasJackDetect", "(I)Z", (void*)android_server_UsbAlsaJackDetector_hasJackDetect }, + { "nativeInputJackConnected", "(I)Z", + (void*)android_server_UsbAlsaJackDetector_inputJackConnected }, + { "nativeOutputJackConnected", "(I)Z", + (void*)android_server_UsbAlsaJackDetector_outputJackConnected }, + { "nativeJackDetect", "(I)Z", (void*)android_server_UsbAlsaJackDetector_jackDetect }, +}; + +int register_android_server_UsbAlsaJackDetector(JNIEnv *env) +{ + jclass clazz = env->FindClass("com/android/server/usb/UsbAlsaJackDetector"); + if (clazz == NULL) { + ALOGE("Can't find com/android/server/usb/UsbAlsaJackDetector"); + return -1; + } + + if (!jniRegisterNativeMethods(env, "com/android/server/usb/UsbAlsaJackDetector", + method_table, NELEM(method_table))) { + ALOGE("Can't register UsbAlsaJackDetector native methods"); + return -1; + } + + return 0; +} + +} diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp index bf2a637cf54e..0ebef37c1f2f 100644 --- a/services/core/jni/onload.cpp +++ b/services/core/jni/onload.cpp @@ -34,6 +34,7 @@ int register_android_server_PowerManagerService(JNIEnv* env); int register_android_server_storage_AppFuse(JNIEnv* env); int register_android_server_SerialService(JNIEnv* env); int register_android_server_SystemServer(JNIEnv* env); +int register_android_server_UsbAlsaJackDetector(JNIEnv* env); int register_android_server_UsbDeviceManager(JNIEnv* env); int register_android_server_UsbMidiDevice(JNIEnv* env); int register_android_server_UsbHostManager(JNIEnv* env); @@ -82,6 +83,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) register_android_server_AlarmManagerService(env); register_android_server_UsbDeviceManager(env); register_android_server_UsbMidiDevice(env); + register_android_server_UsbAlsaJackDetector(env); register_android_server_UsbHostManager(env); register_android_server_vr_VrManagerService(env); register_android_server_VibratorService(env); diff --git a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java index 6e1808ba1e87..28b54ef84a91 100644 --- a/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java +++ b/services/tests/servicestests/src/com/android/server/net/ConnOnActivityStartTest.java @@ -323,6 +323,7 @@ public class ConnOnActivityStartTest { private void turnBatteryOn() throws Exception { executeCommand("cmd battery unplug"); + executeCommand("cmd battery set status " + BatteryManager.BATTERY_STATUS_NOT_CHARGING); assertBatteryOn(); } @@ -336,6 +337,7 @@ public class ConnOnActivityStartTest { private void turnBatteryOff() throws Exception { executeCommand("cmd battery set ac " + BatteryManager.BATTERY_PLUGGED_AC); + executeCommand("cmd battery set status " + BatteryManager.BATTERY_STATUS_CHARGING); } private static void batteryReset() throws Exception { diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java index 78b6077dc1bd..cbbdca6b394f 100644 --- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java @@ -308,6 +308,7 @@ public class AppStandbyControllerTests { private void reportEvent(AppStandbyController controller, int eventType, long elapsedTime) { // Back to ACTIVE on event + mInjector.mElapsedRealtime = elapsedTime; UsageEvents.Event ev = new UsageEvents.Event(); ev.mPackage = PACKAGE_1; ev.mEventType = eventType; @@ -487,6 +488,89 @@ public class AppStandbyControllerTests { } @Test + public void testCascadingTimeouts() throws Exception { + setChargingState(mController, false); + + reportEvent(mController, USER_INTERACTION, 0); + assertBucket(STANDBY_BUCKET_ACTIVE); + + reportEvent(mController, NOTIFICATION_SEEN, 1000); + assertBucket(STANDBY_BUCKET_ACTIVE); + + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET, + REASON_PREDICTED, 1000); + assertBucket(STANDBY_BUCKET_ACTIVE); + + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT, + REASON_PREDICTED, 2000 + mController.mStrongUsageTimeoutMillis); + assertBucket(STANDBY_BUCKET_WORKING_SET); + + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT, + REASON_PREDICTED, 2000 + mController.mNotificationSeenTimeoutMillis); + assertBucket(STANDBY_BUCKET_FREQUENT); + } + + @Test + public void testOverlappingTimeouts() throws Exception { + setChargingState(mController, false); + + reportEvent(mController, USER_INTERACTION, 0); + assertBucket(STANDBY_BUCKET_ACTIVE); + + reportEvent(mController, NOTIFICATION_SEEN, 1000); + assertBucket(STANDBY_BUCKET_ACTIVE); + + // Overlapping USER_INTERACTION before previous one times out + reportEvent(mController, USER_INTERACTION, mController.mStrongUsageTimeoutMillis - 1000); + assertBucket(STANDBY_BUCKET_ACTIVE); + + // Still in ACTIVE after first USER_INTERACTION times out + mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis + 1000; + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT, + REASON_PREDICTED, mInjector.mElapsedRealtime); + assertBucket(STANDBY_BUCKET_ACTIVE); + + // Both timed out, so NOTIFICATION_SEEN timeout should be effective + mInjector.mElapsedRealtime = mController.mStrongUsageTimeoutMillis * 2 + 2000; + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT, + REASON_PREDICTED, mInjector.mElapsedRealtime); + assertBucket(STANDBY_BUCKET_WORKING_SET); + + mInjector.mElapsedRealtime = mController.mNotificationSeenTimeoutMillis + 2000; + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE, + REASON_PREDICTED, mInjector.mElapsedRealtime); + assertBucket(STANDBY_BUCKET_RARE); + } + + @Test + public void testPredictionNotOverridden() throws Exception { + setChargingState(mController, false); + + reportEvent(mController, USER_INTERACTION, 0); + assertBucket(STANDBY_BUCKET_ACTIVE); + + mInjector.mElapsedRealtime = WORKING_SET_THRESHOLD - 1000; + reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime); + assertBucket(STANDBY_BUCKET_ACTIVE); + + // Falls back to WORKING_SET + mInjector.mElapsedRealtime += 5000; + mController.checkIdleStates(USER_ID); + assertBucket(STANDBY_BUCKET_WORKING_SET); + + // Predict to ACTIVE + mInjector.mElapsedRealtime += 1000; + mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE, + REASON_PREDICTED, mInjector.mElapsedRealtime); + assertBucket(STANDBY_BUCKET_ACTIVE); + + // CheckIdleStates should not change the prediction + mInjector.mElapsedRealtime += 1000; + mController.checkIdleStates(USER_ID); + assertBucket(STANDBY_BUCKET_ACTIVE); + } + + @Test public void testAddActiveDeviceAdmin() { assertActiveAdmins(USER_ID, (String[]) null); assertActiveAdmins(USER_ID2, (String[]) null); diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java index 920796ed6a30..5650050f0420 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java @@ -29,6 +29,7 @@ import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.util.ArraySet; +import com.google.android.collect.Sets; import org.junit.Test; import org.junit.runner.RunWith; @@ -74,6 +75,21 @@ public class TaskSnapshotControllerTest extends WindowTestsBase { } @Test + public void testGetClosingApps_skipClosingAppsSnapshotTasks() throws Exception { + final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW, + "closingWindow"); + closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET, + true /* performLayout */, false /* isVoiceInteraction */); + final ArraySet<AppWindowToken> closingApps = new ArraySet<>(); + closingApps.add(closingWindow.mAppToken); + final ArraySet<Task> closingTasks = new ArraySet<>(); + sWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks( + Sets.newArraySet(closingWindow.mAppToken.getTask())); + sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks); + assertEquals(0, closingTasks.size()); + } + + @Test public void testGetSnapshotMode() throws Exception { final WindowState disabledWindow = createWindow(null, FIRST_APPLICATION_WINDOW, mDisplayContent, "disabledWindow"); diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java index b654a66f7d30..f26c2ae771f0 100644 --- a/services/usage/java/com/android/server/usage/AppIdleHistory.java +++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java @@ -23,6 +23,7 @@ import static android.app.usage.UsageStatsManager.REASON_USAGE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_NEVER; import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; +import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import android.app.usage.UsageStatsManager; import android.os.SystemClock; @@ -87,7 +88,9 @@ public class AppIdleHistory { // The last time a job was run for this app private static final String ATTR_LAST_RUN_JOB_TIME = "lastJobRunTime"; // The time when the forced active state can be overridden. - private static final String ATTR_BUCKET_TIMEOUT_TIME = "bucketTimeoutTime"; + private static final String ATTR_BUCKET_ACTIVE_TIMEOUT_TIME = "activeTimeoutTime"; + // The time when the forced working_set state can be overridden. + private static final String ATTR_BUCKET_WORKING_SET_TIMEOUT_TIME = "workingSetTimeoutTime"; // device on time = mElapsedDuration + (timeNow - mElapsedSnapshot) private long mElapsedSnapshot; // Elapsed time snapshot when last write of mDeviceOnDuration @@ -117,11 +120,15 @@ public class AppIdleHistory { int lastInformedBucket; // The last time a job was run for this app, using elapsed timebase long lastJobRunTime; - // When should the bucket state timeout, in elapsed timebase, if greater than + // When should the bucket active state timeout, in elapsed timebase, if greater than // lastUsedElapsedTime. // This is used to keep the app in a high bucket regardless of other timeouts and // predictions. - long bucketTimeoutTime; + long bucketActiveTimeoutTime; + // If there's a forced working_set state, this is when it times out. This can be sitting + // under any active state timeout, so that it becomes applicable after the active state + // timeout expires. + long bucketWorkingSetTimeoutTime; } AppIdleHistory(File storageDir, long elapsedRealtime) { @@ -208,11 +215,28 @@ public class AppIdleHistory { * @param packageName name of the app being updated, for logging purposes * @param newBucket the bucket to set the app to * @param elapsedRealtime mark as used time if non-zero - * @param timeout set the timeout of the specified bucket, if non-zero + * @param timeout set the timeout of the specified bucket, if non-zero. Can only be used + * with bucket values of ACTIVE and WORKING_SET. * @return */ public AppUsageHistory reportUsage(AppUsageHistory appUsageHistory, String packageName, int newBucket, long elapsedRealtime, long timeout) { + // Set the timeout if applicable + if (timeout > elapsedRealtime) { + // Convert to elapsed timebase + final long timeoutTime = mElapsedDuration + (timeout - mElapsedSnapshot); + if (newBucket == STANDBY_BUCKET_ACTIVE) { + appUsageHistory.bucketActiveTimeoutTime = Math.max(timeoutTime, + appUsageHistory.bucketActiveTimeoutTime); + } else if (newBucket == STANDBY_BUCKET_WORKING_SET) { + appUsageHistory.bucketWorkingSetTimeoutTime = Math.max(timeoutTime, + appUsageHistory.bucketWorkingSetTimeoutTime); + } else { + throw new IllegalArgumentException("Cannot set a timeout on bucket=" + + newBucket); + } + } + if (elapsedRealtime != 0) { appUsageHistory.lastUsedElapsedTime = mElapsedDuration + (elapsedRealtime - mElapsedSnapshot); @@ -226,12 +250,6 @@ public class AppIdleHistory { .currentBucket + ", reason=" + appUsageHistory.bucketingReason); } - if (timeout > elapsedRealtime) { - // Convert to elapsed timebase - appUsageHistory.bucketTimeoutTime = - Math.max(appUsageHistory.bucketTimeoutTime, - mElapsedDuration + (timeout - mElapsedSnapshot)); - } } appUsageHistory.bucketingReason = REASON_USAGE; @@ -247,7 +265,8 @@ public class AppIdleHistory { * @param userId * @param newBucket the bucket to set the app to * @param elapsedRealtime mark as used time if non-zero - * @param timeout set the timeout of the specified bucket, if non-zero + * @param timeout set the timeout of the specified bucket, if non-zero. Can only be used + * with bucket values of ACTIVE and WORKING_SET. * @return */ public AppUsageHistory reportUsage(String packageName, int userId, int newBucket, @@ -504,8 +523,10 @@ public class AppIdleHistory { parser.getAttributeValue(null, ATTR_BUCKETING_REASON); appUsageHistory.lastJobRunTime = getLongValue(parser, ATTR_LAST_RUN_JOB_TIME, Long.MIN_VALUE); - appUsageHistory.bucketTimeoutTime = getLongValue(parser, - ATTR_BUCKET_TIMEOUT_TIME, 0L); + appUsageHistory.bucketActiveTimeoutTime = getLongValue(parser, + ATTR_BUCKET_ACTIVE_TIMEOUT_TIME, 0L); + appUsageHistory.bucketWorkingSetTimeoutTime = getLongValue(parser, + ATTR_BUCKET_WORKING_SET_TIMEOUT_TIME, 0L); if (appUsageHistory.bucketingReason == null) { appUsageHistory.bucketingReason = REASON_DEFAULT; } @@ -557,9 +578,13 @@ public class AppIdleHistory { xml.attribute(null, ATTR_CURRENT_BUCKET, Integer.toString(history.currentBucket)); xml.attribute(null, ATTR_BUCKETING_REASON, history.bucketingReason); - if (history.bucketTimeoutTime > 0) { - xml.attribute(null, ATTR_BUCKET_TIMEOUT_TIME, Long.toString(history - .bucketTimeoutTime)); + if (history.bucketActiveTimeoutTime > 0) { + xml.attribute(null, ATTR_BUCKET_ACTIVE_TIMEOUT_TIME, Long.toString(history + .bucketActiveTimeoutTime)); + } + if (history.bucketWorkingSetTimeoutTime > 0) { + xml.attribute(null, ATTR_BUCKET_WORKING_SET_TIMEOUT_TIME, Long.toString(history + .bucketWorkingSetTimeoutTime)); } if (history.lastJobRunTime != Long.MIN_VALUE) { xml.attribute(null, ATTR_LAST_RUN_JOB_TIME, Long.toString(history @@ -593,14 +618,19 @@ public class AppIdleHistory { continue; } idpw.print("package=" + packageName); + idpw.print(" userId=" + userId); idpw.print(" lastUsedElapsed="); TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastUsedElapsedTime, idpw); idpw.print(" lastUsedScreenOn="); TimeUtils.formatDuration(screenOnTime - appUsageHistory.lastUsedScreenTime, idpw); idpw.print(" lastPredictedTime="); TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastPredictedTime, idpw); - idpw.print(" bucketTimeoutTime="); - TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.bucketTimeoutTime, idpw); + idpw.print(" bucketActiveTimeoutTime="); + TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.bucketActiveTimeoutTime, + idpw); + idpw.print(" bucketWorkingSetTimeoutTime="); + TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.bucketWorkingSetTimeoutTime, + idpw); idpw.print(" lastJobRunTime="); TimeUtils.formatDuration(totalElapsedTime - appUsageHistory.lastJobRunTime, idpw); idpw.print(" idle=" + (isIdle(packageName, userId, elapsedRealtime) ? "y" : "n")); diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java index 32db7526f3c0..c31809e913ad 100644 --- a/services/usage/java/com/android/server/usage/AppStandbyController.java +++ b/services/usage/java/com/android/server/usage/AppStandbyController.java @@ -30,6 +30,7 @@ import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; import static com.android.server.SystemService.PHASE_BOOT_COMPLETED; import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY; +import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.usage.UsageStatsManager.StandbyBuckets; @@ -171,6 +172,8 @@ public class AppStandbyController { static final int MSG_REPORT_CONTENT_PROVIDER_USAGE = 8; static final int MSG_PAROLE_STATE_CHANGED = 9; static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10; + /** Check the state of one app: arg1 = userId, arg2 = uid, obj = (String) packageName */ + static final int MSG_CHECK_PACKAGE_IDLE_STATE = 11; long mCheckIdleIntervalMillis; long mAppIdleParoleIntervalMillis; @@ -322,7 +325,7 @@ public class AppStandbyController { // Get sync adapters for the authority String[] packages = ContentResolver.getSyncAdapterPackagesForAuthorityAsUser( authority, userId); - final long elapsedRealtime = SystemClock.elapsedRealtime(); + final long elapsedRealtime = mInjector.elapsedRealtime(); for (String packageName: packages) { // Only force the sync adapters to active if the provider is not in the same package and // the sync adapter is a system package. @@ -460,53 +463,8 @@ public class AppStandbyController { for (int p = 0; p < packageCount; p++) { final PackageInfo pi = packages.get(p); final String packageName = pi.packageName; - final boolean isSpecial = isAppSpecial(packageName, - UserHandle.getAppId(pi.applicationInfo.uid), - userId); - if (DEBUG) { - Slog.d(TAG, " Checking idle state for " + packageName + " special=" + - isSpecial); - } - if (isSpecial) { - synchronized (mAppIdleLock) { - mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, - STANDBY_BUCKET_EXEMPTED, REASON_DEFAULT); - } - maybeInformListeners(packageName, userId, elapsedRealtime, - STANDBY_BUCKET_EXEMPTED, false); - } else { - synchronized (mAppIdleLock) { - AppIdleHistory.AppUsageHistory app = - mAppIdleHistory.getAppUsageHistory(packageName, - userId, elapsedRealtime); - // If the bucket was forced by the developer or the app is within the - // temporary active period, leave it alone. - if (REASON_FORCED.equals(app.bucketingReason) - || !hasBucketTimeoutPassed(app, elapsedRealtime)) { - continue; - } - boolean predictionLate = false; - // If the bucket was moved up due to usage, let the timeouts apply. - if (REASON_DEFAULT.equals(app.bucketingReason) - || REASON_USAGE.equals(app.bucketingReason) - || REASON_TIMEOUT.equals(app.bucketingReason) - || (predictionLate = predictionTimedOut(app, elapsedRealtime))) { - int oldBucket = app.currentBucket; - int newBucket = getBucketForLocked(packageName, userId, - elapsedRealtime); - if (DEBUG) { - Slog.d(TAG, " Old bucket=" + oldBucket - + ", newBucket=" + newBucket); - } - if (oldBucket < newBucket || predictionLate) { - mAppIdleHistory.setAppStandbyBucket(packageName, userId, - elapsedRealtime, newBucket, REASON_TIMEOUT); - maybeInformListeners(packageName, userId, elapsedRealtime, - newBucket, false); - } - } - } - } + checkAndUpdateStandbyState(packageName, userId, pi.applicationInfo.uid, + elapsedRealtime); } } if (DEBUG) { @@ -516,6 +474,90 @@ public class AppStandbyController { return true; } + /** Check if we need to update the standby state of a specific app. */ + private void checkAndUpdateStandbyState(String packageName, @UserIdInt int userId, + int uid, long elapsedRealtime) { + if (uid <= 0) { + try { + uid = mPackageManager.getPackageUidAsUser(packageName, userId); + } catch (PackageManager.NameNotFoundException e) { + // Not a valid package for this user, nothing to do + // TODO: Remove any history of removed packages + return; + } + } + final boolean isSpecial = isAppSpecial(packageName, + UserHandle.getAppId(uid), + userId); + if (DEBUG) { + Slog.d(TAG, " Checking idle state for " + packageName + " special=" + + isSpecial); + } + if (isSpecial) { + synchronized (mAppIdleLock) { + mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, + STANDBY_BUCKET_EXEMPTED, REASON_DEFAULT); + } + maybeInformListeners(packageName, userId, elapsedRealtime, + STANDBY_BUCKET_EXEMPTED, false); + } else { + synchronized (mAppIdleLock) { + final AppIdleHistory.AppUsageHistory app = + mAppIdleHistory.getAppUsageHistory(packageName, + userId, elapsedRealtime); + String reason = app.bucketingReason; + + // If the bucket was forced by the user/developer, leave it alone. + // A usage event will be the only way to bring it out of this forced state + if (REASON_FORCED.equals(app.bucketingReason)) { + return; + } + final int oldBucket = app.currentBucket; + int newBucket = Math.max(oldBucket, STANDBY_BUCKET_ACTIVE); // Undo EXEMPTED + boolean predictionLate = false; + // Compute age-based bucket + if (REASON_DEFAULT.equals(app.bucketingReason) + || REASON_USAGE.equals(app.bucketingReason) + || REASON_TIMEOUT.equals(app.bucketingReason) + || (predictionLate = predictionTimedOut(app, elapsedRealtime))) { + newBucket = getBucketForLocked(packageName, userId, + elapsedRealtime); + if (DEBUG) { + Slog.d(TAG, "Evaluated AOSP newBucket = " + newBucket); + } + reason = REASON_TIMEOUT; + } + // Check if the app is within one of the timeouts for forced bucket elevation + final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime); + if (newBucket >= STANDBY_BUCKET_ACTIVE + && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) { + newBucket = STANDBY_BUCKET_ACTIVE; + reason = REASON_USAGE; + if (DEBUG) { + Slog.d(TAG, " Keeping at ACTIVE due to min timeout"); + } + } else if (newBucket >= STANDBY_BUCKET_WORKING_SET + && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) { + newBucket = STANDBY_BUCKET_WORKING_SET; + reason = REASON_USAGE; + if (DEBUG) { + Slog.d(TAG, " Keeping at WORKING_SET due to min timeout"); + } + } + if (DEBUG) { + Slog.d(TAG, " Old bucket=" + oldBucket + + ", newBucket=" + newBucket); + } + if (oldBucket < newBucket || predictionLate) { + mAppIdleHistory.setAppStandbyBucket(packageName, userId, + elapsedRealtime, newBucket, reason); + maybeInformListeners(packageName, userId, elapsedRealtime, + newBucket, false); + } + } + } + } + private boolean predictionTimedOut(AppIdleHistory.AppUsageHistory app, long elapsedRealtime) { return app.bucketingReason != null && app.bucketingReason.startsWith(REASON_PREDICTED) @@ -526,7 +568,9 @@ public class AppStandbyController { private boolean hasBucketTimeoutPassed(AppIdleHistory.AppUsageHistory app, long elapsedRealtime) { - return app.bucketTimeoutTime < mAppIdleHistory.getElapsedTime(elapsedRealtime); + final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime); + return app.bucketActiveTimeoutTime < elapsedTimeAdjusted + && app.bucketWorkingSetTimeoutTime < elapsedTimeAdjusted; } private void maybeInformListeners(String packageName, int userId, @@ -631,16 +675,22 @@ public class AppStandbyController { event.mPackage, userId, elapsedRealtime); final int prevBucket = appHistory.currentBucket; final String prevBucketReason = appHistory.bucketingReason; + final long nextCheckTime; if (event.mEventType == UsageEvents.Event.NOTIFICATION_SEEN) { + // Mild usage elevates to WORKING_SET but doesn't change usage time. mAppIdleHistory.reportUsage(appHistory, event.mPackage, STANDBY_BUCKET_WORKING_SET, - elapsedRealtime, elapsedRealtime + mNotificationSeenTimeoutMillis); + 0, elapsedRealtime + mNotificationSeenTimeoutMillis); + nextCheckTime = mNotificationSeenTimeoutMillis; } else { - mAppIdleHistory.reportUsage(event.mPackage, userId, + mAppIdleHistory.reportUsage(appHistory, event.mPackage, STANDBY_BUCKET_ACTIVE, elapsedRealtime, elapsedRealtime + mStrongUsageTimeoutMillis); + nextCheckTime = mStrongUsageTimeoutMillis; } - + mHandler.sendMessageDelayed(mHandler.obtainMessage + (MSG_CHECK_PACKAGE_IDLE_STATE, userId, -1, event.mPackage), + nextCheckTime); final boolean userStartedInteracting = appHistory.currentBucket == STANDBY_BUCKET_ACTIVE && prevBucket != appHistory.currentBucket && @@ -932,9 +982,24 @@ public class AppStandbyController { // If the bucket is required to stay in a higher state for a specified duration, don't // override unless the duration has passed - if (predicted && app.currentBucket < newBucket - && !hasBucketTimeoutPassed(app, elapsedRealtime)) { - return; + if (predicted) { + // Check if the app is within one of the timeouts for forced bucket elevation + final long elapsedTimeAdjusted = mAppIdleHistory.getElapsedTime(elapsedRealtime); + if (newBucket > STANDBY_BUCKET_ACTIVE + && app.bucketActiveTimeoutTime > elapsedTimeAdjusted) { + newBucket = STANDBY_BUCKET_ACTIVE; + reason = REASON_USAGE; + if (DEBUG) { + Slog.d(TAG, " Keeping at ACTIVE due to min timeout"); + } + } else if (newBucket > STANDBY_BUCKET_WORKING_SET + && app.bucketWorkingSetTimeoutTime > elapsedTimeAdjusted) { + newBucket = STANDBY_BUCKET_WORKING_SET; + reason = REASON_USAGE; + if (DEBUG) { + Slog.d(TAG, " Keeping at WORKING_SET due to min timeout"); + } + } } mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket, @@ -1347,6 +1412,10 @@ public class AppStandbyController { + ", Charging state:" + mCharging); informParoleStateChanged(); break; + case MSG_CHECK_PACKAGE_IDLE_STATE: + checkAndUpdateStandbyState((String) msg.obj, msg.arg1, msg.arg2, + mInjector.elapsedRealtime()); + break; default: super.handleMessage(msg); break; diff --git a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java index 7480e5662d7a..9d4db003a297 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java @@ -17,9 +17,14 @@ package com.android.server.usb; import android.annotation.NonNull; +import android.media.AudioSystem; +import android.media.IAudioService; +import android.os.RemoteException; import android.service.usb.UsbAlsaDeviceProto; +import android.util.Slog; import com.android.internal.util.dump.DualDumpOutputStream; +import com.android.server.audio.AudioService; /** * Represents the ALSA specification, and attributes of an ALSA device. @@ -30,25 +35,31 @@ public final class UsbAlsaDevice { private final int mCardNum; private final int mDeviceNum; - private final boolean mHasPlayback; - private final boolean mHasCapture; + private final String mDeviceAddress; + private final boolean mHasOutput; + private final boolean mHasInput; private final boolean mIsInputHeadset; private final boolean mIsOutputHeadset; - private final String mDeviceAddress; + private boolean mSelected = false; + private int mOutputState; + private int mInputState; + private UsbAlsaJackDetector mJackDetector; + private IAudioService mAudioService; private String mDeviceName = ""; private String mDeviceDescription = ""; - public UsbAlsaDevice(int card, int device, String deviceAddress, - boolean hasPlayback, boolean hasCapture, + public UsbAlsaDevice(IAudioService audioService, int card, int device, String deviceAddress, + boolean hasOutput, boolean hasInput, boolean isInputHeadset, boolean isOutputHeadset) { + mAudioService = audioService; mCardNum = card; mDeviceNum = device; mDeviceAddress = deviceAddress; - mHasPlayback = hasPlayback; - mHasCapture = hasCapture; + mHasOutput = hasOutput; + mHasInput = hasInput; mIsInputHeadset = isInputHeadset; mIsOutputHeadset = isOutputHeadset; } @@ -75,71 +86,187 @@ public final class UsbAlsaDevice { } /** - * @returns true if the device supports playback. + * @returns the ALSA card/device address string. */ - public boolean hasPlayback() { - return mHasPlayback; + public String getAlsaCardDeviceString() { + if (mCardNum < 0 || mDeviceNum < 0) { + Slog.e(TAG, "Invalid alsa card or device alsaCard: " + mCardNum + + " alsaDevice: " + mDeviceNum); + return null; + } + return AudioService.makeAlsaAddressString(mCardNum, mDeviceNum); } /** - * @returns true if the device supports capture (recording). + * @returns true if the device supports output. */ - public boolean hasCapture() { - return mHasCapture; + public boolean hasOutput() { + return mHasOutput; } /** - * @returns true if the device is a headset for purposes of capture. + * @returns true if the device supports input (recording). + */ + public boolean hasInput() { + return mHasInput; + } + + /** + * @returns true if the device is a headset for purposes of input. */ public boolean isInputHeadset() { return mIsInputHeadset; } /** - * @returns true if the device is a headset for purposes of playback. + * @returns true if the device is a headset for purposes of output. */ public boolean isOutputHeadset() { return mIsOutputHeadset; } /** + * @returns true if input jack is detected or jack detection is not supported. + */ + private synchronized boolean isInputJackConnected() { + if (mJackDetector == null) { + return true; // If jack detect isn't supported, say it's connected. + } + return mJackDetector.isInputJackConnected(); + } + + /** + * @returns true if input jack is detected or jack detection is not supported. + */ + private synchronized boolean isOutputJackConnected() { + if (mJackDetector == null) { + return true; // if jack detect isn't supported, say it's connected. + } + return mJackDetector.isOutputJackConnected(); + } + + /** Begins a jack-detection thread. */ + private synchronized void startJackDetect() { + // If no jack detect capabilities exist, mJackDetector will be null. + mJackDetector = UsbAlsaJackDetector.startJackDetect(this); + } + + /** Stops a jack-detection thread. */ + private synchronized void stopJackDetect() { + if (mJackDetector != null) { + mJackDetector.pleaseStop(); + } + mJackDetector = null; + } + + /** Start using this device as the selected USB Audio Device. */ + public synchronized void start() { + mSelected = true; + mInputState = 0; + mOutputState = 0; + startJackDetect(); + updateWiredDeviceConnectionState(true); + } + + /** Stop using this device as the selected USB Audio Device. */ + public synchronized void stop() { + stopJackDetect(); + updateWiredDeviceConnectionState(false); + mSelected = false; + } + + /** Updates AudioService with the connection state of the alsaDevice. + * Checks ALSA Jack state for inputs and outputs before reporting. + */ + public synchronized void updateWiredDeviceConnectionState(boolean enable) { + if (!mSelected) { + Slog.e(TAG, "updateWiredDeviceConnectionState on unselected AlsaDevice!"); + return; + } + String alsaCardDeviceString = getAlsaCardDeviceString(); + if (alsaCardDeviceString == null) { + return; + } + try { + // Output Device + if (mHasOutput) { + int device = mIsOutputHeadset + ? AudioSystem.DEVICE_OUT_USB_HEADSET + : AudioSystem.DEVICE_OUT_USB_DEVICE; + if (DEBUG) { + Slog.d(TAG, "pre-call device:0x" + Integer.toHexString(device) + + " addr:" + alsaCardDeviceString + + " name:" + mDeviceName); + } + boolean connected = isOutputJackConnected(); + Slog.i(TAG, "OUTPUT JACK connected: " + connected); + int outputState = (enable && connected) ? 1 : 0; + if (outputState != mOutputState) { + mOutputState = outputState; + mAudioService.setWiredDeviceConnectionState(device, outputState, + alsaCardDeviceString, + mDeviceName, TAG); + } + } + + // Input Device + if (mHasInput) { + int device = mIsInputHeadset ? AudioSystem.DEVICE_IN_USB_HEADSET + : AudioSystem.DEVICE_IN_USB_DEVICE; + boolean connected = isInputJackConnected(); + Slog.i(TAG, "INPUT JACK connected: " + connected); + int inputState = (enable && connected) ? 1 : 0; + if (inputState != mInputState) { + mInputState = inputState; + mAudioService.setWiredDeviceConnectionState( + device, inputState, alsaCardDeviceString, + mDeviceName, TAG); + } + } + } catch (RemoteException e) { + Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState"); + } + } + + + /** * @Override * @returns a string representation of the object. */ - public String toString() { + public synchronized String toString() { return "UsbAlsaDevice: [card: " + mCardNum + ", device: " + mDeviceNum + ", name: " + mDeviceName - + ", hasPlayback: " + mHasPlayback - + ", hasCapture: " + mHasCapture + "]"; + + ", hasOutput: " + mHasOutput + + ", hasInput: " + mHasInput + "]"; } /** * Write a description of the device to a dump stream. */ - public void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { + public synchronized void dump(@NonNull DualDumpOutputStream dump, String idName, long id) { long token = dump.start(idName, id); dump.write("card", UsbAlsaDeviceProto.CARD, mCardNum); dump.write("device", UsbAlsaDeviceProto.DEVICE, mDeviceNum); dump.write("name", UsbAlsaDeviceProto.NAME, mDeviceName); - dump.write("has_playback", UsbAlsaDeviceProto.HAS_PLAYBACK, mHasPlayback); - dump.write("has_capture", UsbAlsaDeviceProto.HAS_CAPTURE, mHasCapture); + dump.write("has_output", UsbAlsaDeviceProto.HAS_PLAYBACK, mHasOutput); + dump.write("has_input", UsbAlsaDeviceProto.HAS_CAPTURE, mHasInput); dump.write("address", UsbAlsaDeviceProto.ADDRESS, mDeviceAddress); dump.end(token); } // called by logDevices - String toShortString() { + synchronized String toShortString() { return "[card:" + mCardNum + " device:" + mDeviceNum + " " + mDeviceName + "]"; } - String getDeviceName() { + synchronized String getDeviceName() { return mDeviceName; } - void setDeviceNameAndDescription(String deviceName, String deviceDescription) { + synchronized void setDeviceNameAndDescription(String deviceName, String deviceDescription) { mDeviceName = deviceName; mDeviceDescription = deviceDescription; } @@ -155,8 +282,8 @@ public final class UsbAlsaDevice { UsbAlsaDevice other = (UsbAlsaDevice) obj; return (mCardNum == other.mCardNum && mDeviceNum == other.mDeviceNum - && mHasPlayback == other.mHasPlayback - && mHasCapture == other.mHasCapture + && mHasOutput == other.mHasOutput + && mHasInput == other.mHasInput && mIsInputHeadset == other.mIsInputHeadset && mIsOutputHeadset == other.mIsOutputHeadset); } @@ -170,8 +297,8 @@ public final class UsbAlsaDevice { int result = 1; result = prime * result + mCardNum; result = prime * result + mDeviceNum; - result = prime * result + (mHasPlayback ? 0 : 1); - result = prime * result + (mHasCapture ? 0 : 1); + result = prime * result + (mHasOutput ? 0 : 1); + result = prime * result + (mHasInput ? 0 : 1); result = prime * result + (mIsInputHeadset ? 0 : 1); result = prime * result + (mIsOutputHeadset ? 0 : 1); diff --git a/services/usb/java/com/android/server/usb/UsbAlsaJackDetector.java b/services/usb/java/com/android/server/usb/UsbAlsaJackDetector.java new file mode 100644 index 000000000000..c4988478df71 --- /dev/null +++ b/services/usb/java/com/android/server/usb/UsbAlsaJackDetector.java @@ -0,0 +1,97 @@ +/* + * 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.usb; + +/** + * Detects and reports ALSA jack state and events. + */ +public final class UsbAlsaJackDetector implements Runnable { + private static final String TAG = "UsbAlsaJackDetector"; + + private static native boolean nativeHasJackDetect(int card); + private native boolean nativeJackDetect(int card); + private native boolean nativeOutputJackConnected(int card); + private native boolean nativeInputJackConnected(int card); + + private boolean mStopJackDetect = false; + private UsbAlsaDevice mAlsaDevice; + + /* use startJackDetect to create a UsbAlsaJackDetector */ + private UsbAlsaJackDetector(UsbAlsaDevice device) { + mAlsaDevice = device; + } + + /** If jack detection is detected on the given Alsa Device, + * create and return a UsbAlsaJackDetector which will update wired device state + * each time a jack detection event is registered. + * + * @returns UsbAlsaJackDetector if jack detect is supported, or null. + */ + public static UsbAlsaJackDetector startJackDetect(UsbAlsaDevice device) { + if (!nativeHasJackDetect(device.getCardNum())) { + return null; + } + UsbAlsaJackDetector jackDetector = new UsbAlsaJackDetector(device); + + // This thread will exit once the USB device disappears. + // It can also be convinced to stop with pleaseStop(). + new Thread(jackDetector, "USB jack detect thread").start(); + return jackDetector; + } + + public boolean isInputJackConnected() { + return nativeInputJackConnected(mAlsaDevice.getCardNum()); + } + + public boolean isOutputJackConnected() { + return nativeOutputJackConnected(mAlsaDevice.getCardNum()); + } + + /** + * Stop the jack detect thread from calling back into UsbAlsaDevice. + * This doesn't force the thread to stop (which is deprecated in java and dangerous due to + * locking issues), but will cause the thread to exit at the next safe opportunity. + */ + public void pleaseStop() { + synchronized (this) { + mStopJackDetect = true; + } + } + + /** + * Called by nativeJackDetect each time a jack detect event is reported. + * @return false when the jackDetect thread should stop. true otherwise. + */ + public boolean jackDetectCallback() { + synchronized (this) { + if (mStopJackDetect) { + return false; + } + mAlsaDevice.updateWiredDeviceConnectionState(true); + } + return true; + } + + /** + * This will call jackDetectCallback each time it detects a jack detect event. + * If jackDetectCallback returns false, this function will return. + */ + public void run() { + nativeJackDetect(mAlsaDevice.getCardNum()); + } +} + diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java index 0c5f8f113adc..2f1c5169362a 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java @@ -20,11 +20,9 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.hardware.usb.UsbDevice; -import android.media.AudioSystem; import android.media.IAudioService; import android.media.midi.MidiDeviceInfo; import android.os.Bundle; -import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.service.usb.UsbAlsaManagerProto; @@ -32,7 +30,6 @@ import android.util.Slog; import com.android.internal.alsa.AlsaCardsParser; import com.android.internal.util.dump.DualDumpOutputStream; -import com.android.server.audio.AudioService; import com.android.server.usb.descriptors.UsbDescriptorParser; import libcore.io.IoUtils; @@ -58,6 +55,7 @@ public final class UsbAlsaManager { // this is needed to map USB devices to ALSA Audio Devices, especially to remove an // ALSA device when we are notified that its associated USB device has been removed. private final ArrayList<UsbAlsaDevice> mAlsaDevices = new ArrayList<UsbAlsaDevice>(); + private UsbAlsaDevice mSelectedDevice; /** * List of connected MIDI devices @@ -78,17 +76,19 @@ public final class UsbAlsaManager { ServiceManager.getService(Context.AUDIO_SERVICE)); } - // Notifies AudioService when a device is added or removed - // audioDevice - the AudioDevice that was added or removed - // enabled - if true, we're connecting a device (it's arrived), else disconnecting - private void notifyDeviceState(UsbAlsaDevice alsaDevice, boolean enabled) { + /** + * Select the AlsaDevice to be used for AudioService. + * AlsaDevice.start() notifies AudioService of it's connected state. + * + * @param alsaDevice The selected UsbAlsaDevice for system USB audio. + */ + private synchronized void selectAlsaDevice(UsbAlsaDevice alsaDevice) { if (DEBUG) { - Slog.d(TAG, "notifyDeviceState " + enabled + " " + alsaDevice); + Slog.d(TAG, "selectAlsaDevice " + alsaDevice); } - if (mAudioService == null) { - Slog.e(TAG, "no AudioService"); - return; + if (mSelectedDevice != null) { + deselectAlsaDevice(); } // FIXME Does not yet handle the case where the setting is changed @@ -102,40 +102,14 @@ public final class UsbAlsaManager { return; } - int state = (enabled ? 1 : 0); - int cardNum = alsaDevice.getCardNum(); - int deviceNum = alsaDevice.getDeviceNum(); - if (cardNum < 0 || deviceNum < 0) { - Slog.e(TAG, "Invalid alsa card or device alsaCard: " + cardNum - + " alsaDevice: " + deviceNum); - return; - } - - String address = AudioService.makeAlsaAddressString(cardNum, deviceNum); - try { - // Playback Device - if (alsaDevice.hasPlayback()) { - int device = alsaDevice.isOutputHeadset() - ? AudioSystem.DEVICE_OUT_USB_HEADSET - : AudioSystem.DEVICE_OUT_USB_DEVICE; - if (DEBUG) { - Slog.i(TAG, "pre-call device:0x" + Integer.toHexString(device) + - " addr:" + address + " name:" + alsaDevice.getDeviceName()); - } - mAudioService.setWiredDeviceConnectionState( - device, state, address, alsaDevice.getDeviceName(), TAG); - } + mSelectedDevice = alsaDevice; + alsaDevice.start(); + } - // Capture Device - if (alsaDevice.hasCapture()) { - int device = alsaDevice.isInputHeadset() - ? AudioSystem.DEVICE_IN_USB_HEADSET - : AudioSystem.DEVICE_IN_USB_DEVICE; - mAudioService.setWiredDeviceConnectionState( - device, state, address, alsaDevice.getDeviceName(), TAG); - } - } catch (RemoteException e) { - Slog.e(TAG, "RemoteException in setWiredDeviceConnectionState"); + private synchronized void deselectAlsaDevice() { + if (mSelectedDevice != null) { + mSelectedDevice.stop(); + mSelectedDevice = null; } } @@ -168,7 +142,7 @@ public final class UsbAlsaManager { Slog.d(TAG, " alsaDevice:" + alsaDevice); } if (alsaDevice != null) { - notifyDeviceState(alsaDevice, true /*enabled*/); + selectAlsaDevice(alsaDevice); } return alsaDevice; } else { @@ -202,16 +176,21 @@ public final class UsbAlsaManager { if (hasInput || hasOutput) { boolean isInputHeadset = parser.isInputHeadset(); boolean isOutputHeadset = parser.isOutputHeadset(); - UsbAlsaDevice alsaDevice = - new UsbAlsaDevice(cardRec.getCardNum(), 0 /*device*/, deviceAddress, - hasOutput, hasInput, isInputHeadset, isOutputHeadset); - alsaDevice.setDeviceNameAndDescription( - cardRec.getCardName(), cardRec.getCardDescription()); - mAlsaDevices.add(0, alsaDevice); - // Select it + if (mAudioService == null) { + Slog.e(TAG, "no AudioService"); + return; + } + + UsbAlsaDevice alsaDevice = + new UsbAlsaDevice(mAudioService, cardRec.getCardNum(), 0 /*device*/, + deviceAddress, hasOutput, hasInput, + isInputHeadset, isOutputHeadset); if (alsaDevice != null) { - notifyDeviceState(alsaDevice, true /*enabled*/); + alsaDevice.setDeviceNameAndDescription( + cardRec.getCardName(), cardRec.getCardDescription()); + mAlsaDevices.add(0, alsaDevice); + selectAlsaDevice(alsaDevice); } } @@ -256,7 +235,7 @@ public final class UsbAlsaManager { } } - /* package */ void usbDeviceRemoved(String deviceAddress/*UsbDevice usbDevice*/) { + /* package */ synchronized void usbDeviceRemoved(String deviceAddress/*UsbDevice usbDevice*/) { if (DEBUG) { Slog.d(TAG, "deviceRemoved(" + deviceAddress + ")"); } @@ -264,13 +243,9 @@ public final class UsbAlsaManager { // Audio UsbAlsaDevice alsaDevice = removeAlsaDeviceFromList(deviceAddress); Slog.i(TAG, "USB Audio Device Removed: " + alsaDevice); - if (alsaDevice != null) { - if (alsaDevice.hasPlayback() || alsaDevice.hasCapture()) { - notifyDeviceState(alsaDevice, false /*enabled*/); - - // if there any external devices left, select one of them - selectDefaultDevice(); - } + if (alsaDevice != null && alsaDevice == mSelectedDevice) { + deselectAlsaDevice(); + selectDefaultDevice(); // if there any external devices left, select one of them } // MIDI |