diff options
53 files changed, 982 insertions, 1066 deletions
diff --git a/api/test-current.txt b/api/test-current.txt index 22b051bf8c8d..641767c7bccd 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -214,6 +214,7 @@ package android.app { field public static final String OPSTR_GPS = "android:gps"; field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground"; field public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage"; + field public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"; field public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels"; field public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone"; field public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells"; diff --git a/cmds/statsd/benchmark/filter_value_benchmark.cpp b/cmds/statsd/benchmark/filter_value_benchmark.cpp index 28bf21ae52bf..743ccc4ed451 100644 --- a/cmds/statsd/benchmark/filter_value_benchmark.cpp +++ b/cmds/statsd/benchmark/filter_value_benchmark.cpp @@ -14,12 +14,14 @@ * limitations under the License. */ #include <vector> -#include "benchmark/benchmark.h" + #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "benchmark/benchmark.h" #include "logd/LogEvent.h" -#include "stats_log_util.h" +#include "metric_util.h" #include "stats_event.h" +#include "stats_log_util.h" namespace android { namespace os { @@ -34,24 +36,13 @@ static void createLogEventAndMatcher(LogEvent* event, FieldMatcher* field_matche std::vector<int> attributionUids = {100, 100}; std::vector<string> attributionTags = {"LOCATION", "LOCATION"}; + writeAttribution(statsEvent, attributionUids, attributionTags); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); AStatsEvent_writeFloat(statsEvent, 3.2f); AStatsEvent_writeString(statsEvent, "LOCATION"); AStatsEvent_writeInt64(statsEvent, 990); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - event->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, event); field_matcher->set_field(1); auto child = field_matcher->add_child(); diff --git a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp b/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp index c7d01cc406fc..7a455650a31b 100644 --- a/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp +++ b/cmds/statsd/benchmark/get_dimensions_for_condition_benchmark.cpp @@ -14,12 +14,14 @@ * limitations under the License. */ #include <vector> -#include "benchmark/benchmark.h" + #include "FieldValue.h" #include "HashableDimensionKey.h" +#include "benchmark/benchmark.h" #include "logd/LogEvent.h" -#include "stats_log_util.h" +#include "metric_util.h" #include "stats_event.h" +#include "stats_log_util.h" namespace android { namespace os { @@ -34,24 +36,13 @@ static void createLogEventAndLink(LogEvent* event, Metric2Condition *link) { std::vector<int> attributionUids = {100, 100}; std::vector<string> attributionTags = {"LOCATION", "LOCATION"}; + writeAttribution(statsEvent, attributionUids, attributionTags); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); AStatsEvent_writeFloat(statsEvent, 3.2f); AStatsEvent_writeString(statsEvent, "LOCATION"); AStatsEvent_writeInt64(statsEvent, 990); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - event->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, event); link->conditionId = 1; diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp index 482d66fc7556..89fd3d9b29ab 100644 --- a/cmds/statsd/benchmark/metric_util.cpp +++ b/cmds/statsd/benchmark/metric_util.cpp @@ -247,21 +247,37 @@ FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields) return dimensions; } +void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids, + const vector<string>& attributionTags) { + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); +} + +void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) { + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -272,24 +288,12 @@ std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent( AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, jobName.c_str()); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -319,24 +323,12 @@ std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs, AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, name.c_str()); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/benchmark/metric_util.h b/cmds/statsd/benchmark/metric_util.h index c5fcf7c27440..3efaa850a921 100644 --- a/cmds/statsd/benchmark/metric_util.h +++ b/cmds/statsd/benchmark/metric_util.h @@ -18,6 +18,7 @@ #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "src/StatsLogProcessor.h" #include "src/logd/LogEvent.h" +#include "stats_event.h" #include "statslog.h" namespace android { @@ -92,6 +93,11 @@ FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId, FieldMatcher CreateAttributionUidDimensions(const int atomId, const std::vector<Position>& positions); +void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids, + const vector<string>& attributionTags); + +void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent); + // Create log event for screen state changed. std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( uint64_t timestampNs, const android::view::DisplayStateEnum state); diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp index 0bf24f1d3606..f5ba8fd0d60d 100644 --- a/cmds/statsd/tests/FieldValue_test.cpp +++ b/cmds/statsd/tests/FieldValue_test.cpp @@ -41,22 +41,10 @@ void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timest AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, name.c_str()); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -66,22 +54,10 @@ void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timest AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // anonymous namespace diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 6f4c8e48eff2..9cdf5827d1f8 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -48,15 +48,9 @@ void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t tim AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -64,15 +58,9 @@ void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t t AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - AStatsEvent_writeFloat(statsEvent, floatValue); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -80,15 +68,9 @@ void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - AStatsEvent_writeString(statsEvent, name.c_str()); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeIntStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -99,13 +81,8 @@ void makeIntStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64 AStatsEvent_writeInt32(statsEvent, value); AStatsEvent_writeString(statsEvent, name.c_str()); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -115,22 +92,10 @@ void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestamp); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, name.c_str()); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, @@ -141,13 +106,8 @@ void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t ti AStatsEvent_writeBool(statsEvent, bool1); AStatsEvent_writeBool(statsEvent, bool2); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // anonymous namespace diff --git a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp index 7febb35355a3..ba5b032b80d0 100644 --- a/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp +++ b/cmds/statsd/tests/condition/SimpleConditionTracker_test.cpp @@ -67,22 +67,12 @@ void makeWakeLockEvent(LogEvent* logEvent, uint32_t atomId, uint64_t timestamp, AStatsEvent_overwriteTimestamp(statsEvent, timestamp); vector<std::string> tags(uids.size()); // vector of empty strings - vector<const char*> cTags(uids.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = tags[i].c_str(); - } - AStatsEvent_writeAttributionChain(statsEvent, reinterpret_cast<const uint32_t*>(uids.data()), - cTags.data(), uids.size()); + writeAttribution(statsEvent, uids, tags); AStatsEvent_writeString(statsEvent, wl.c_str()); AStatsEvent_writeInt32(statsEvent, acquire); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // anonymous namespace diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp index 81e1c05c1cf4..60403f2a3e0f 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp @@ -84,14 +84,9 @@ std::unique_ptr<LogEvent> CreateAppStartOccurredEvent( AStatsEvent_writeString(statsEvent, calling_pkg_name.c_str()); AStatsEvent_writeInt32(statsEvent, is_instant_app); AStatsEvent_writeInt32(statsEvent, activity_start_msec); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/external/StatsPuller_test.cpp b/cmds/statsd/tests/external/StatsPuller_test.cpp index e8200d5c7f52..504335845cab 100644 --- a/cmds/statsd/tests/external/StatsPuller_test.cpp +++ b/cmds/statsd/tests/external/StatsPuller_test.cpp @@ -64,16 +64,10 @@ std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, pullTagId); AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); - AStatsEvent_writeInt64(statsEvent, value); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 15425d8810dc..3e1cc5e458ed 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -23,6 +23,7 @@ #include "../metrics/metrics_test_helper.h" #include "stats_event.h" #include "statslog_statsdtest.h" +#include "tests/statsd_test_util.h" #ifdef __ANDROID__ @@ -71,14 +72,9 @@ std::shared_ptr<LogEvent> makeUidLogEvent(uint64_t timestampNs, int uid, int dat AStatsEvent_writeInt32(statsEvent, uid); AStatsEvent_writeInt32(statsEvent, data1); AStatsEvent_writeInt32(statsEvent, data2); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -86,16 +82,10 @@ std::shared_ptr<LogEvent> makeNonUidAtomLogEvent(uint64_t timestampNs, int data1 AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, nonUidAtomTagId); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, data1); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::shared_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp index 6dc041f9fb6e..a15f95bef358 100644 --- a/cmds/statsd/tests/log_event/LogEventQueue_test.cpp +++ b/cmds/statsd/tests/log_event/LogEventQueue_test.cpp @@ -21,6 +21,7 @@ #include <thread> #include "stats_event.h" +#include "tests/statsd_test_util.h" namespace android { namespace os { @@ -37,14 +38,9 @@ std::unique_ptr<LogEvent> makeLogEvent(uint64_t timestampNs) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, 10); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp index d55996cb1b7a..65f8de69711d 100644 --- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp @@ -46,26 +46,17 @@ void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId, string uid) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeString(statsEvent, uid.c_str()); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // namespace diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp index 6143dc0dc5d1..30f815962160 100644 --- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp @@ -26,6 +26,7 @@ #include "src/condition/ConditionWizard.h" #include "src/stats_log_util.h" #include "stats_event.h" +#include "tests/statsd_test_util.h" using namespace android::os::statsd; using namespace testing; @@ -48,12 +49,8 @@ void makeLogEvent(LogEvent* logEvent, int64_t timestampNs, int atomId) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // namespace diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp index e58bbb7893d7..97647a7e0867 100644 --- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp @@ -43,14 +43,9 @@ void makeLogEvent(LogEvent* logEvent, int32_t atomId, int64_t timestampNs, strin AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeString(statsEvent, str.c_str()); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } } // anonymous namespace diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index 2fe05a4430c3..42d0d5d8c530 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -64,14 +64,9 @@ shared_ptr<LogEvent> makeLogEvent(int32_t atomId, int64_t timestampNs, int32_t v AStatsEvent_writeInt32(statsEvent, value1); AStatsEvent_writeString(statsEvent, str1.c_str()); AStatsEvent_writeInt32(statsEvent, value2); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); - + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } } // anonymous namespace diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index b623a0978f18..009e49a5523f 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -611,7 +611,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { vector<shared_ptr<LogEvent>> allData; allData.clear(); - allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 110)); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 110)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); assertPastBucketValuesSingleKey(valueProducer->mPastBuckets, {10}, {bucketSizeNs - 8}); @@ -656,7 +656,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -665,14 +665,14 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) { EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 1, 10); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 59 * NS_PER_SEC, 10); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs); // Next value should create a new bucket. LogEvent event3(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 1, 10); + CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 65 * NS_PER_SEC, 10); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size()); EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, valueProducer.mCurrentBucketStartTimeNs); @@ -812,10 +812,10 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice @@ -856,7 +856,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { valueProducer.mCondition = ConditionState::kFalse; LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has 1 slice EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size()); @@ -864,7 +864,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2); // has one slice @@ -875,7 +875,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { EXPECT_EQ(20, curInterval.value.long_value); LogEvent event3(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 1, 30); + CreateRepeatedValueLogEvent(&event3, tagId, bucketStartTimeNs + 30, 30); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); // has one slice @@ -886,7 +886,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35); LogEvent event4(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 1, 40); + CreateRepeatedValueLogEvent(&event4, tagId, bucketStartTimeNs + 40, 40); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4); // has one slice @@ -1195,10 +1195,10 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMin) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice @@ -1238,10 +1238,10 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 20); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 20); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice @@ -1283,10 +1283,10 @@ TEST(ValueMetricProducerTest, TestPushedAggregateAvg) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 15); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -1331,10 +1331,10 @@ TEST(ValueMetricProducerTest, TestPushedAggregateSum) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 1, 15); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 20, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -1374,10 +1374,10 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { valueProducer.prepareFirstBucket(); LogEvent event1(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 1, 10); + CreateRepeatedValueLogEvent(&event1, tagId, bucketStartTimeNs + 10, 10); LogEvent event2(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 1, 15); + CreateRepeatedValueLogEvent(&event2, tagId, bucketStartTimeNs + 15, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1); // has one slice EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); @@ -1398,7 +1398,7 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { // no change in data. LogEvent event3(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 1, 15); + CreateRepeatedValueLogEvent(&event3, tagId, bucket2StartTimeNs + 10, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event3); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -1408,7 +1408,7 @@ TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) { EXPECT_EQ(true, curInterval.hasValue); LogEvent event4(/*uid=*/0, /*pid=*/0); - CreateTwoValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 1, 15); + CreateRepeatedValueLogEvent(&event4, tagId, bucket2StartTimeNs + 15, 15); valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event4); EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size()); curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0]; @@ -2166,7 +2166,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) // Bucket start. vector<shared_ptr<LogEvent>> allData; allData.clear(); - allData.push_back(CreateTwoValueLogEvent(tagId, bucketStartTimeNs + 1, 1, 110)); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucketStartTimeNs + 1, 110)); valueProducer->onDataPulled(allData, /** succeed */ false, bucketStartTimeNs); valueProducer->onConditionChanged(false, bucketStartTimeNs + 2); @@ -2174,7 +2174,7 @@ TEST(ValueMetricProducerTest_BucketDrop, TestInvalidBucketWhenInitialPullFailed) // Bucket end. allData.clear(); - allData.push_back(CreateTwoValueLogEvent(tagId, bucket2StartTimeNs + 1, 1, 140)); + allData.push_back(CreateRepeatedValueLogEvent(tagId, bucket2StartTimeNs + 1, 140)); valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs); valueProducer->flushIfNeededLocked(bucket2StartTimeNs + 1); diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp index ac3ad690f81e..7b952d7a392e 100644 --- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp +++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp @@ -171,13 +171,9 @@ shared_ptr<LogEvent> makeCpuActiveTimeAtom(int32_t uid, int64_t timeMillis) { AStatsEvent_overwriteTimestamp(statsEvent, 1111L); AStatsEvent_writeInt32(statsEvent, uid); AStatsEvent_writeInt64(statsEvent, timeMillis); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp index a5b8e1c50c33..78c80bc8307c 100644 --- a/cmds/statsd/tests/state/StateTracker_test.cpp +++ b/cmds/statsd/tests/state/StateTracker_test.cpp @@ -62,7 +62,7 @@ int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& query // START: build event functions. // Incorrect event - missing fields -std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, +std::unique_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED); @@ -72,14 +72,9 @@ std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& AStatsEvent_writeString(statsEvent, packageName.c_str()); // Missing field 3 - using_alert_window. AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -93,14 +88,9 @@ std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::stri AStatsEvent_writeString(statsEvent, packageName.c_str()); AStatsEvent_writeInt32(statsEvent, true); // using_alert_window AStatsEvent_writeString(statsEvent, "string"); // exclusive state: string instead of int - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } // END: build event functions. diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 7d765d3fbbf5..ed3cf5b96b42 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -507,23 +507,26 @@ void getPartialWakelockKey(int uid, HashableDimensionKey* key) { } // END: get primary key functions -shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, - int32_t value2) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, atomId); - AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); +void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids, + const vector<string>& attributionTags) { + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } - AStatsEvent_writeInt32(statsEvent, value1); - AStatsEvent_writeInt32(statsEvent, value2); + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); +} + +void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent) { AStatsEvent_build(statsEvent); size_t size; uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); - return logEvent; + AStatsEvent_release(statsEvent); } void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, int32_t value1, @@ -534,31 +537,14 @@ void CreateTwoValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs, AStatsEvent_writeInt32(statsEvent, value1); AStatsEvent_writeInt32(statsEvent, value2); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } -shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, - int32_t value2, int32_t value3) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, atomId); - AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); - - AStatsEvent_writeInt32(statsEvent, value1); - AStatsEvent_writeInt32(statsEvent, value2); - AStatsEvent_writeInt32(statsEvent, value3); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); +shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, + int32_t value2) { shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); - + CreateTwoValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2); return logEvent; } @@ -571,29 +557,14 @@ void CreateThreeValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeN AStatsEvent_writeInt32(statsEvent, value1); AStatsEvent_writeInt32(statsEvent, value2); AStatsEvent_writeInt32(statsEvent, value3); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } -shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, atomId); - AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); - - AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); +shared_ptr<LogEvent> CreateThreeValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, + int32_t value2, int32_t value3) { shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); - + CreateThreeValueLogEvent(logEvent.get(), atomId, eventTimeNs, value1, value2, value3); return logEvent; } @@ -605,26 +576,13 @@ void CreateRepeatedValueLogEvent(LogEvent* logEvent, int atomId, int64_t eventTi AStatsEvent_writeInt32(statsEvent, value); AStatsEvent_writeInt32(statsEvent, value); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); } -shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) { - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, atomId); - AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); +shared_ptr<LogEvent> CreateRepeatedValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value) { shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); - + CreateRepeatedValueLogEvent(logEvent.get(), atomId, eventTimeNs, value); return logEvent; } @@ -632,12 +590,14 @@ void CreateNoValuesLogEvent(LogEvent* logEvent, int atomId, int64_t eventTimeNs) AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, atomId); AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent); +} + +shared_ptr<LogEvent> CreateNoValuesLogEvent(int atomId, int64_t eventTimeNs) { + shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); + CreateNoValuesLogEvent(logEvent.get(), atomId, eventTimeNs); + return logEvent; } std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( @@ -645,16 +605,10 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::SCREEN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -662,16 +616,10 @@ std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::ON); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -679,16 +627,10 @@ std::unique_ptr<LogEvent> CreateBatterySaverOffEvent(uint64_t timestampNs) { AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::BATTERY_SAVER_MODE_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, BatterySaverModeStateChanged::OFF); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -696,16 +638,10 @@ std::unique_ptr<LogEvent> CreateBatteryStateChangedEvent(const uint64_t timestam AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::PLUGGED_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -713,16 +649,10 @@ std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampN AStatsEvent* statsEvent = AStatsEvent_obtain(); AStatsEvent_setAtomId(statsEvent, util::SCREEN_BRIGHTNESS_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - AStatsEvent_writeInt32(statsEvent, level); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -733,24 +663,12 @@ std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent( AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, jobName.c_str()); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -780,25 +698,13 @@ std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs, AStatsEvent_setAtomId(statsEvent, util::WAKELOCK_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeInt32(statsEvent, android::os::WakeLockLevelEnum::PARTIAL_WAKE_LOCK); AStatsEvent_writeString(statsEvent, wakelockName.c_str()); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -828,14 +734,9 @@ std::unique_ptr<LogEvent> CreateActivityForegroundStateChangedEvent( AStatsEvent_writeString(statsEvent, "pkg_name"); AStatsEvent_writeString(statsEvent, "class_name"); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -858,24 +759,12 @@ std::unique_ptr<LogEvent> CreateSyncStateChangedEvent(uint64_t timestampNs, AStatsEvent_setAtomId(statsEvent, util::SYNC_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeString(statsEvent, name.c_str()); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -904,14 +793,9 @@ std::unique_ptr<LogEvent> CreateProcessLifeCycleStateChangedEvent( AStatsEvent_writeInt32(statsEvent, uid); AStatsEvent_writeString(statsEvent, ""); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -928,14 +812,9 @@ std::unique_ptr<LogEvent> CreateAppCrashOccurredEvent(uint64_t timestampNs, cons AStatsEvent_writeInt32(statsEvent, uid); AStatsEvent_writeString(statsEvent, "eventType"); AStatsEvent_writeString(statsEvent, "processName"); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -948,14 +827,9 @@ std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, in AStatsEvent_writeInt32(statsEvent, hostUid); AStatsEvent_writeInt32(statsEvent, isolatedUid); AStatsEvent_writeInt32(statsEvent, is_create); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -967,14 +841,9 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( AStatsEvent_writeInt32(statsEvent, uid); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -988,26 +857,14 @@ std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs, AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED); AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); - vector<const char*> cTags(attributionTags.size()); - for (int i = 0; i < cTags.size(); i++) { - cTags[i] = attributionTags[i].c_str(); - } - - AStatsEvent_writeAttributionChain(statsEvent, - reinterpret_cast<const uint32_t*>(attributionUids.data()), - cTags.data(), attributionUids.size()); + writeAttribution(statsEvent, attributionUids, attributionTags); AStatsEvent_writeInt32(statsEvent, state); AStatsEvent_writeInt32(statsEvent, filtered); // filtered AStatsEvent_writeInt32(statsEvent, firstMatch); // first match AStatsEvent_writeInt32(statsEvent, opportunistic); // opportunistic - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } @@ -1023,14 +880,9 @@ std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, co AStatsEvent_writeString(statsEvent, packageName.c_str()); AStatsEvent_writeInt32(statsEvent, usingAlertWindow); AStatsEvent_writeInt32(statsEvent, state); - AStatsEvent_build(statsEvent); - - size_t size; - uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buf, size); - AStatsEvent_release(statsEvent); + parseStatsEventToLogEvent(statsEvent, logEvent.get()); return logEvent; } diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index f24705a0c89f..d6ea77eb2c7d 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -25,6 +25,7 @@ #include "src/hash.h" #include "src/logd/LogEvent.h" #include "src/stats_log_util.h" +#include "stats_event.h" #include "statslog_statsdtest.h" namespace android { @@ -189,6 +190,12 @@ void getPartialWakelockKey(int uid, const std::string& tag, HashableDimensionKey void getPartialWakelockKey(int uid, HashableDimensionKey* key); // END: get primary key functions +void writeAttribution(AStatsEvent* statsEvent, const vector<int>& attributionUids, + const vector<string>& attributionTags); + +// Builds statsEvent to get buffer that is parsed into logEvent then releases statsEvent. +void parseStatsEventToLogEvent(AStatsEvent* statsEvent, LogEvent* logEvent); + shared_ptr<LogEvent> CreateTwoValueLogEvent(int atomId, int64_t eventTimeNs, int32_t value1, int32_t value2); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 46b06fb64b80..3a708a6f699b 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1395,6 +1395,7 @@ public class AppOpsManager { public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages"; /** @hide Access all external storage */ @SystemApi + @TestApi public static final String OPSTR_MANAGE_EXTERNAL_STORAGE = "android:manage_external_storage"; diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index fc48e7f18f5f..f216db6fc717 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -979,14 +979,17 @@ public final class BluetoothAdapter { 8, BLUETOOTH_GET_STATE_CACHE_PROPERTY) { @Override protected Integer recompute(Void query) { - // This function must be called while holding the - // mServiceLock, and with mService not null. The public - // getState() method makes this guarantee. try { - return mService.getState(); + mServiceLock.readLock().lock(); + if (mService != null) { + return mService.getState(); + } } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Log.e(TAG, "", e); + } finally { + mServiceLock.readLock().unlock(); } + return BluetoothAdapter.STATE_OFF; } }; @@ -1013,24 +1016,7 @@ public final class BluetoothAdapter { @RequiresPermission(Manifest.permission.BLUETOOTH) @AdapterState public int getState() { - int state = BluetoothAdapter.STATE_OFF; - - try { - mServiceLock.readLock().lock(); - // The test for mService must either be outside the cache, or - // the cache must be invalidated when mService changes. - if (mService != null) { - state = mBluetoothGetStateCache.query(null); - } - } catch (RuntimeException e) { - if (e.getCause() instanceof RemoteException) { - Log.e(TAG, "", e.getCause()); - } else { - throw e; - } - } finally { - mServiceLock.readLock().unlock(); - } + int state = mBluetoothGetStateCache.query(null); // Consider all internal states as OFF if (state == BluetoothAdapter.STATE_BLE_ON || state == BluetoothAdapter.STATE_BLE_TURNING_ON diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index ab65e3a5c849..1086774fc8ff 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -2888,7 +2888,8 @@ public final class SurfaceControl implements Parcelable { /** * Acquire a frame rate flexibility token, which allows surface flinger to freely switch display * frame rates. This is used by CTS tests to put the device in a consistent state. See - * ISurfaceComposer::acquireFrameRateFlexibilityToken(). + * ISurfaceComposer::acquireFrameRateFlexibilityToken(). The caller must have the + * ACCESS_SURFACE_FLINGER permission, or else the call will fail, returning 0. * @hide */ @TestApi diff --git a/core/java/android/view/textclassifier/ConversationActions.java b/core/java/android/view/textclassifier/ConversationActions.java index 842ba2975b3b..6ad5cb913553 100644 --- a/core/java/android/view/textclassifier/ConversationActions.java +++ b/core/java/android/view/textclassifier/ConversationActions.java @@ -27,8 +27,6 @@ import android.os.Parcel; import android.os.Parcelable; import android.text.SpannedString; -import com.android.internal.util.Preconditions; - import java.lang.annotation.Retention; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; @@ -491,7 +489,11 @@ public final class ConversationActions implements Parcelable { */ @NonNull public Builder setMaxSuggestions(@IntRange(from = -1) int maxSuggestions) { - mMaxSuggestions = Preconditions.checkArgumentNonnegative(maxSuggestions); + if (maxSuggestions < -1) { + throw new IllegalArgumentException("maxSuggestions has to be greater than or " + + "equal to -1."); + } + mMaxSuggestions = maxSuggestions; return this; } diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java index 4dd1a29d8595..5f0acc8f7647 100644 --- a/location/java/android/location/LocationRequest.java +++ b/location/java/android/location/LocationRequest.java @@ -264,8 +264,8 @@ public final class LocationRequest implements Parcelable { /* numUpdates= */ Integer.MAX_VALUE, /* smallestDisplacement= */ 0, /* hideFromAppOps= */ false, - /* lowPowerMode= */ false, /* locationSettingsIgnored= */ false, + /* lowPowerMode= */ false, /* workSource= */ null); } @@ -282,8 +282,8 @@ public final class LocationRequest implements Parcelable { src.mNumUpdates, src.mSmallestDisplacement, src.mHideFromAppOps, - src.mLowPowerMode, src.mLocationSettingsIgnored, + src.mLowPowerMode, src.mWorkSource); } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java index 8aa0aec28fb8..a53bc9f966d2 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiEntryPreference.java @@ -102,12 +102,11 @@ public class WifiEntryPreference extends Preference implements WifiEntry.WifiEnt // Turn off divider view.findViewById(R.id.two_target_divider).setVisibility(View.INVISIBLE); - // Enable the icon button when this Entry is a canManageSubscription entry. + // Enable the icon button when the help string in this WifiEntry is not null. final ImageButton imageButton = (ImageButton) view.findViewById(R.id.icon_button); final ImageView frictionImageView = (ImageView) view.findViewById( R.id.friction_icon); - if (mWifiEntry.canManageSubscription() && !mWifiEntry.isSaved() - && !mWifiEntry.isSubscription() + if (mWifiEntry.getHelpUriString() != null && mWifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_DISCONNECTED) { final Drawable drawablehelp = getDrawable(R.drawable.ic_help); drawablehelp.setTintList( diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java index a9f31ce12b42..46e699d3bed5 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/wifi/WifiEntryPreferenceTest.java @@ -64,7 +64,7 @@ public class WifiEntryPreferenceTest { private static final String MOCK_TITLE = "title"; private static final String MOCK_SUMMARY = "summary"; - + private static final String FAKE_URI_STRING = "fakeuri"; @Before public void setUp() { @@ -155,22 +155,23 @@ public class WifiEntryPreferenceTest { } @Test - public void canManageSubscription_shouldSetImageButtonVisible() { - when(mMockWifiEntry.canManageSubscription()).thenReturn(true); + public void notNull_whenGetHelpUriString_shouldSetImageButtonVisible() { + when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING); final WifiEntryPreference pref = new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); final LayoutInflater inflater = LayoutInflater.from(mContext); final View view = inflater.inflate(pref.getLayoutResource(), new LinearLayout(mContext), false); final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests(view); + pref.onBindViewHolder(holder); assertThat(view.findViewById(R.id.icon_button).getVisibility()).isEqualTo(View.VISIBLE); } @Test - public void helpButton_whenCanManageSubscription_shouldSetCorrectContentDescription() { - when(mMockWifiEntry.canManageSubscription()).thenReturn(true); + public void helpButton_whenGetHelpUriStringNotNull_shouldSetCorrectContentDescription() { + when(mMockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING); final WifiEntryPreference pref = new WifiEntryPreference(mContext, mMockWifiEntry, mMockIconInjector); final LayoutInflater inflater = LayoutInflater.from(mContext); diff --git a/packages/SystemUI/res/layout/qs_media_panel.xml b/packages/SystemUI/res/layout/qs_media_panel.xml index fc3bf941b27a..e5ac5f89cd25 100644 --- a/packages/SystemUI/res/layout/qs_media_panel.xml +++ b/packages/SystemUI/res/layout/qs_media_panel.xml @@ -23,7 +23,8 @@ android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal|fill_vertical" - android:padding="16dp" + android:paddingTop="@dimen/qs_media_panel_outer_padding" + android:paddingBottom="@dimen/qs_media_panel_outer_padding" android:background="@drawable/qs_media_background" > @@ -42,7 +43,9 @@ android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="16dp" + android:layout_marginBottom="@dimen/qs_media_panel_outer_padding" + android:paddingStart="@dimen/qs_media_panel_outer_padding" + android:paddingEnd="16dp" > <ImageView @@ -139,6 +142,7 @@ <!-- Seek Bar --> <SeekBar android:id="@+id/media_progress_bar" + style="@android:style/Widget.ProgressBar.Horizontal" android:clickable="true" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -154,6 +158,9 @@ android:id="@+id/notification_media_progress_time" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="@dimen/qs_media_panel_outer_padding" + android:paddingEnd="@dimen/qs_media_panel_outer_padding" + android:layout_marginBottom="10dp" android:layout_gravity="center" > <!-- width is set to "match_parent" to avoid extra layout calls --> @@ -184,6 +191,8 @@ android:layoutDirection="ltr" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="@dimen/qs_media_panel_outer_padding" + android:paddingEnd="@dimen/qs_media_panel_outer_padding" android:gravity="center" > <ImageButton diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index bce5fac76cfc..344479f371d7 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1211,6 +1211,7 @@ <!-- Size of media cards in the QSPanel carousel --> <dimen name="qs_media_width">350dp</dimen> <dimen name="qs_media_padding">8dp</dimen> + <dimen name="qs_media_panel_outer_padding">16dp</dimen> <dimen name="qs_media_corner_radius">10dp</dimen> <dimen name="qs_media_album_size">72dp</dimen> <dimen name="qs_seamless_icon_size">20dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 9d885fd3c207..99e5eb66a00f 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -719,13 +719,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** - * Tell the stack of bubbles to expand. - */ - public void expandStack() { - mBubbleData.setExpanded(true); - } - - /** * Tell the stack of bubbles to collapse. */ public void collapseStack() { @@ -753,12 +746,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi return (isSummary && isSuppressedSummary) || isBubbleAndSuppressed; } - @VisibleForTesting - void selectBubble(String key) { - Bubble bubble = mBubbleData.getBubbleWithKey(key); - mBubbleData.setSelectedBubble(bubble); - } - void promoteBubbleFromOverflow(Bubble bubble) { bubble.setInflateSynchronously(mInflateSynchronously); mBubbleData.promoteBubbleFromOverflow(bubble, mStackView, mBubbleIconFactory); @@ -778,13 +765,6 @@ public class BubbleController implements ConfigurationController.ConfigurationLi } /** - * Tell the stack of bubbles to be dismissed, this will remove all of the bubbles in the stack. - */ - void dismissStack(@DismissReason int reason) { - mBubbleData.dismissAll(reason); - } - - /** * Directs a back gesture at the bubble stack. When opened, the current expanded bubble * is forwarded a back key down/up pair. */ diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java index be9cd5f01c86..4c149ddd3939 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java @@ -28,6 +28,7 @@ import android.content.Context; import android.service.notification.NotificationListenerService; import android.util.Log; import android.util.Pair; +import android.view.View; import androidx.annotation.Nullable; @@ -751,6 +752,7 @@ public class BubbleData { } @VisibleForTesting(visibility = PRIVATE) + @Nullable Bubble getBubbleWithKey(String key) { for (int i = 0; i < mBubbles.size(); i++) { Bubble bubble = mBubbles.get(i); @@ -761,6 +763,17 @@ public class BubbleData { return null; } + @Nullable + Bubble getBubbleWithView(View view) { + for (int i = 0; i < mBubbles.size(); i++) { + Bubble bubble = mBubbles.get(i); + if (bubble.getIconView() != null && bubble.getIconView().equals(view)) { + return bubble; + } + } + return null; + } + @VisibleForTesting(visibility = PRIVATE) Bubble getOverflowBubbleWithKey(String key) { for (int i = 0; i < mOverflowBubbles.size(); i++) { diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java index 044feaa117c8..644e54fb82ae 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java @@ -30,6 +30,7 @@ import static com.android.systemui.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; +import android.annotation.SuppressLint; import android.app.Notification; import android.content.Context; import android.content.res.Configuration; @@ -43,6 +44,7 @@ import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; +import android.graphics.Region; import android.os.Bundle; import android.os.Vibrator; import android.util.Log; @@ -83,6 +85,7 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.SysUiStatsLog; import com.android.systemui.util.DismissCircleView; import com.android.systemui.util.FloatingContentCoordinator; +import com.android.systemui.util.RelativeTouchListener; import com.android.systemui.util.animation.PhysicsAnimator; import com.android.systemui.util.magnetictarget.MagnetizedObject; @@ -239,7 +242,6 @@ public class BubbleStackView extends FrameLayout { mExpandedAnimationController.dump(fd, pw, args); } - private BubbleTouchHandler mTouchHandler; private BubbleController.BubbleExpandListener mExpandListener; private SysUiState mSysUiState; @@ -296,7 +298,7 @@ public class BubbleStackView extends FrameLayout { @Override public void setValue(Object o, float v) { - onFlyoutDragged(v); + setFlyoutStateForDragLength(v); } }; @@ -337,13 +339,6 @@ public class BubbleStackView extends FrameLayout { private MagnetizedObject<?> mMagnetizedObject; /** - * The action to run when the magnetized object is released in the dismiss target. - * - * This will actually perform the dismissal of either the stack or an individual bubble. - */ - private Runnable mReleasedInDismissTargetAction; - - /** * The MagneticTarget instance for our circular dismiss view. This is added to the * MagnetizedObject instances for the stack and any dragged-out bubbles. */ @@ -377,7 +372,7 @@ public class BubbleStackView extends FrameLayout { public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) { mExpandedAnimationController.dismissDraggedOutBubble( mExpandedAnimationController.getDraggedOutBubble(), - mReleasedInDismissTargetAction); + BubbleStackView.this::dismissMagnetizedObject); hideDismissTarget(); } }; @@ -410,7 +405,7 @@ public class BubbleStackView extends FrameLayout { mStackAnimationController.implodeStack( () -> { resetDesaturationAndDarken(); - mReleasedInDismissTargetAction.run(); + dismissMagnetizedObject(); } ); @@ -418,6 +413,197 @@ public class BubbleStackView extends FrameLayout { } }; + /** + * Click listener set on each bubble view. When collapsed, clicking a bubble expands the stack. + * When expanded, clicking a bubble either expands that bubble, or collapses the stack. + */ + private OnClickListener mBubbleClickListener = new OnClickListener() { + @Override + public void onClick(View view) { + final Bubble clickedBubble = mBubbleData.getBubbleWithView(view); + + // If the bubble has since left us, ignore the click. + if (clickedBubble == null) { + return; + } + + final boolean clickedBubbleIsCurrentlyExpandedBubble = + clickedBubble.getKey().equals(mExpandedBubble.getKey()); + + if (isExpanded() && !clickedBubbleIsCurrentlyExpandedBubble) { + if (clickedBubble != mBubbleData.getSelectedBubble()) { + // Select the clicked bubble. + mBubbleData.setSelectedBubble(clickedBubble); + } else { + // If the clicked bubble is the selected bubble (but not the expanded bubble), + // that means overflow was previously expanded. Set the selected bubble + // internally without going through BubbleData (which would ignore it since it's + // already selected). + setSelectedBubble(clickedBubble); + + } + } else { + // Otherwise, we either tapped the stack (which means we're collapsed + // and should expand) or the currently selected bubble (we're expanded + // and should collapse). + if (!maybeShowStackUserEducation()) { + mBubbleData.setExpanded(!mBubbleData.isExpanded()); + } + } + } + }; + + /** + * Touch listener set on each bubble view. This enables dragging and dismissing the stack (when + * collapsed), or individual bubbles (when expanded). + */ + private RelativeTouchListener mBubbleTouchListener = new RelativeTouchListener() { + + @Override + public boolean onDown(@NonNull View v, @NonNull MotionEvent ev) { + // If we're expanding or collapsing, consume but ignore all touch events. + if (mIsExpansionAnimating) { + return true; + } + + if (mBubbleData.isExpanded()) { + maybeShowManageEducation(false /* show */); + + // If we're expanded, tell the animation controller to prepare to drag this bubble, + // dispatching to the individual bubble magnet listener. + mExpandedAnimationController.prepareForBubbleDrag( + v /* bubble */, + mMagneticTarget, + mIndividualBubbleMagnetListener); + + // Save the magnetized individual bubble so we can dispatch touch events to it. + mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut(); + } else { + // If we're collapsed, prepare to drag the stack. Cancel active animations, set the + // animation controller, and hide the flyout. + mStackAnimationController.cancelStackPositionAnimations(); + mBubbleContainer.setActiveController(mStackAnimationController); + hideFlyoutImmediate(); + + // Also, save the magnetized stack so we can dispatch touch events to it. + mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget); + mMagnetizedObject.setMagnetListener(mStackMagnetListener); + } + + passEventToMagnetizedObject(ev); + + // Bubbles are always interested in all touch events! + return true; + } + + @Override + public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy) { + // If we're expanding or collapsing, ignore all touch events. + if (mIsExpansionAnimating) { + return; + } + + // Show the dismiss target, if we haven't already. + springInDismissTargetMaybe(); + + // First, see if the magnetized object consumes the event - if so, we shouldn't move the + // bubble since it's stuck to the target. + if (!passEventToMagnetizedObject(ev)) { + if (mBubbleData.isExpanded()) { + mExpandedAnimationController.dragBubbleOut( + v, viewInitialX + dx, viewInitialY + dy); + } else { + hideStackUserEducation(false /* fromExpansion */); + mStackAnimationController.moveStackFromTouch( + viewInitialX + dx, viewInitialY + dy); + } + } + } + + @Override + public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy, float velX, float velY) { + // If we're expanding or collapsing, ignore all touch events. + if (mIsExpansionAnimating) { + return; + } + + // First, see if the magnetized object consumes the event - if so, the bubble was + // released in the target or flung out of it, and we should ignore the event. + if (!passEventToMagnetizedObject(ev)) { + if (mBubbleData.isExpanded()) { + mExpandedAnimationController.snapBubbleBack(v, velX, velY); + } else { + // Fling the stack to the edge, and save whether or not it's going to end up on + // the left side of the screen. + mStackOnLeftOrWillBe = + mStackAnimationController.flingStackThenSpringToEdge( + viewInitialX + dx, velX, velY) <= 0; + + updateBubbleZOrdersAndDotPosition(true /* animate */); + + logBubbleEvent(null /* no bubble associated with bubble stack move */, + SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED); + } + + hideDismissTarget(); + } + } + }; + + /** Click listener set on the flyout, which expands the stack when the flyout is tapped. */ + private OnClickListener mFlyoutClickListener = new OnClickListener() { + @Override + public void onClick(View view) { + if (maybeShowStackUserEducation()) { + // If we're showing user education, don't open the bubble show the education first + mBubbleToExpandAfterFlyoutCollapse = null; + } else { + mBubbleToExpandAfterFlyoutCollapse = mBubbleData.getSelectedBubble(); + } + + mFlyout.removeCallbacks(mHideFlyout); + mHideFlyout.run(); + } + }; + + /** Touch listener for the flyout. This enables the drag-to-dismiss gesture on the flyout. */ + private RelativeTouchListener mFlyoutTouchListener = new RelativeTouchListener() { + + @Override + public boolean onDown(@NonNull View v, @NonNull MotionEvent ev) { + mFlyout.removeCallbacks(mHideFlyout); + return true; + } + + @Override + public void onMove(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy) { + setFlyoutStateForDragLength(dx); + } + + @Override + public void onUp(@NonNull View v, @NonNull MotionEvent ev, float viewInitialX, + float viewInitialY, float dx, float dy, float velX, float velY) { + final boolean onLeft = mStackAnimationController.isStackOnLeftSide(); + final boolean metRequiredVelocity = + onLeft ? velX < -FLYOUT_DISMISS_VELOCITY : velX > FLYOUT_DISMISS_VELOCITY; + final boolean metRequiredDeltaX = + onLeft + ? dx < -mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS + : dx > mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS; + final boolean isCancelFling = onLeft ? velX > 0 : velX < 0; + final boolean shouldDismiss = metRequiredVelocity + || (metRequiredDeltaX && !isCancelFling); + + mFlyout.removeCallbacks(mHideFlyout); + animateFlyoutCollapsed(shouldDismiss, velX); + + maybeShowStackUserEducation(); + } + }; + private ViewGroup mDismissTargetContainer; private PhysicsAnimator<View> mDismissTargetAnimator; private PhysicsAnimator.SpringConfig mDismissTargetSpring = new PhysicsAnimator.SpringConfig( @@ -436,6 +622,7 @@ public class BubbleStackView extends FrameLayout { private BubbleManageEducationView mManageEducationView; private boolean mAnimatingManageEducationAway; + @SuppressLint("ClickableViewAccessibility") public BubbleStackView(Context context, BubbleData data, @Nullable SurfaceSynchronizer synchronizer, FloatingContentCoordinator floatingContentCoordinator, @@ -444,8 +631,6 @@ public class BubbleStackView extends FrameLayout { mBubbleData = data; mInflater = LayoutInflater.from(context); - mTouchHandler = new BubbleTouchHandler(this, data, context); - setOnTouchListener(mTouchHandler); mSysUiState = sysUiState; @@ -641,6 +826,18 @@ public class BubbleStackView extends FrameLayout { mDesaturateAndDarkenPaint.setColorFilter(new ColorMatrixColorFilter(animatedMatrix)); mDesaturateAndDarkenTargetView.setLayerPaint(mDesaturateAndDarkenPaint); }); + + // If the stack itself is touched, it means none of its touchable views (bubbles, flyouts, + // ActivityViews, etc.) were touched. Collapse the stack if it's expanded. + setOnTouchListener((view, ev) -> { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + if (mBubbleData.isExpanded()) { + mBubbleData.setExpanded(false); + } + } + + return false; + }); } private void setUpUserEducation() { @@ -690,6 +887,7 @@ public class BubbleStackView extends FrameLayout { } } + @SuppressLint("ClickableViewAccessibility") private void setUpFlyout() { if (mFlyout != null) { removeView(mFlyout); @@ -699,6 +897,8 @@ public class BubbleStackView extends FrameLayout { mFlyout.animate() .setDuration(FLYOUT_ALPHA_ANIMATION_DURATION) .setInterpolator(new AccelerateDecelerateInterpolator()); + mFlyout.setOnClickListener(mFlyoutClickListener); + mFlyout.setOnTouchListener(mFlyoutTouchListener); addView(mFlyout, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); } @@ -718,6 +918,7 @@ public class BubbleStackView extends FrameLayout { mBubbleContainer.addView(mBubbleOverflow.getBtn(), overflowBtnIndex, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + mBubbleOverflow.getBtn().setOnClickListener(v -> setSelectedBubble(mBubbleOverflow)); } /** * Handle theme changes. @@ -920,6 +1121,7 @@ public class BubbleStackView extends FrameLayout { } // via BubbleData.Listener + @SuppressLint("ClickableViewAccessibility") void addBubble(Bubble bubble) { if (DEBUG_BUBBLE_STACK_VIEW) { Log.d(TAG, "addBubble: " + bubble); @@ -944,6 +1146,9 @@ public class BubbleStackView extends FrameLayout { bubble.getIconView().setDotPositionOnLeft( !mStackOnLeftOrWillBe /* onLeft */, false /* animate */); + bubble.getIconView().setOnClickListener(mBubbleClickListener); + bubble.getIconView().setOnTouchListener(mBubbleTouchListener); + mBubbleContainer.addView(bubble.getIconView(), 0, new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); ViewClippingUtil.setClippingDeactivated(bubble.getIconView(), true, mClippingParameters); @@ -1009,10 +1214,6 @@ public class BubbleStackView extends FrameLayout { updatePointerPosition(); } - void showOverflow() { - setSelectedBubble(mBubbleOverflow); - } - /** * Changes the currently selected bubble. If the stack is already expanded, the newly selected * bubble will be shown immediately. This does not change the expanded state or change the @@ -1177,14 +1378,6 @@ public class BubbleStackView extends FrameLayout { } } - /* - * Sets the action to run to dismiss the currently dragging object (either the stack or an - * individual bubble). - */ - public void setReleasedInDismissTargetAction(Runnable action) { - mReleasedInDismissTargetAction = action; - } - /** * Dismiss the stack of bubbles. * @@ -1201,54 +1394,6 @@ public class BubbleStackView extends FrameLayout { } /** - * @return the view the touch event is on - */ - @Nullable - public View getTargetView(MotionEvent event) { - float x = event.getRawX(); - float y = event.getRawY(); - if (mIsExpanded) { - if (isIntersecting(mBubbleContainer, x, y)) { - if (BubbleExperimentConfig.allowBubbleOverflow(mContext) - && isIntersecting(mBubbleOverflow.getBtn(), x, y)) { - return mBubbleOverflow.getBtn(); - } - // Could be tapping or dragging a bubble while expanded - for (int i = 0; i < getBubbleCount(); i++) { - BadgedImageView view = (BadgedImageView) mBubbleContainer.getChildAt(i); - if (isIntersecting(view, x, y)) { - return view; - } - } - } - BubbleExpandedView bev = (BubbleExpandedView) mExpandedViewContainer.getChildAt(0); - if (bev.intersectingTouchableContent((int) x, (int) y)) { - return bev; - } - // Outside of the parts we care about. - return null; - } else if (mFlyout.getVisibility() == VISIBLE && isIntersecting(mFlyout, x, y)) { - return mFlyout; - } else if (mUserEducationView != null && mUserEducationView.getVisibility() == VISIBLE) { - View bubbleChild = mBubbleContainer.getChildAt(0); - if (isIntersecting(bubbleChild, x, y)) { - return this; - } else if (isIntersecting(mUserEducationView, x, y)) { - return mUserEducationView; - } else { - return null; - } - } - - // If it wasn't an individual bubble in the expanded state, or the flyout, it's the stack. - return this; - } - - View getFlyoutView() { - return mFlyout; - } - - /** * @deprecated use {@link #setExpanded(boolean)} and * {@link BubbleData#setSelectedBubble(Bubble)} */ @@ -1385,124 +1530,70 @@ public class BubbleStackView extends FrameLayout { } } - /** Called when the collapsed stack is tapped on. */ - void onStackTapped() { - if (!maybeShowStackUserEducation()) { - mBubbleData.setExpanded(true); - } - } - - /** Called when a drag operation on an individual bubble has started. */ - public void onBubbleDragStart(View bubble) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onBubbleDragStart: bubble=" + ((BadgedImageView) bubble).getKey()); - } - - if (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView())) { - return; - } - - mExpandedAnimationController.prepareForBubbleDrag(bubble, mMagneticTarget); - - // We're dragging an individual bubble, so set the magnetized object to the magnetized - // bubble. - mMagnetizedObject = mExpandedAnimationController.getMagnetizedBubbleDraggingOut(); - mMagnetizedObject.setMagnetListener(mIndividualBubbleMagnetListener); - - maybeShowManageEducation(false); - } - - /** Called with the coordinates to which an individual bubble has been dragged. */ - public void onBubbleDragged(View bubble, float x, float y) { - if (!mIsExpanded || mIsExpansionAnimating - || (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView()))) { - return; - } - - mExpandedAnimationController.dragBubbleOut(bubble, x, y); - springInDismissTarget(); - } - - /** Called when a drag operation on an individual bubble has finished. */ - public void onBubbleDragFinish( - View bubble, float x, float y, float velX, float velY) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onBubbleDragFinish: bubble=" + bubble); - } - - if (!mIsExpanded || mIsExpansionAnimating - || (mBubbleOverflow != null && bubble.equals(mBubbleOverflow.getIconView()))) { - return; - } - - mExpandedAnimationController.snapBubbleBack(bubble, velX, velY); - hideDismissTarget(); - } - - /** Expands the clicked bubble. */ - public void expandBubble(Bubble bubble) { - if (bubble != null && bubble.equals(mBubbleData.getSelectedBubble())) { - // If the bubble we're supposed to expand is the selected bubble, that means the - // overflow bubble is currently expanded. Don't tell BubbleData to set this bubble as - // selected, since it already is. Just call the stack's setSelectedBubble to expand it. - setSelectedBubble(bubble); - } else { - mBubbleData.setSelectedBubble(bubble); - } - } - - void onDragStart() { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onDragStart()"); - } - if (mIsExpanded || mIsExpansionAnimating) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "mIsExpanded or mIsExpansionAnimating"); - } - return; - } - mStackAnimationController.cancelStackPositionAnimations(); - mBubbleContainer.setActiveController(mStackAnimationController); - hideFlyoutImmediate(); + /** + * This method is called by {@link android.app.ActivityView} because the BubbleStackView has a + * higher Z-index than the ActivityView (so that dragged-out bubbles are visible over the AV). + * ActivityView is asking BubbleStackView to subtract the stack's bounds from the provided + * touchable region, so that the ActivityView doesn't consume events meant for the stack. Due to + * the special nature of ActivityView, it does not respect the standard + * {@link #dispatchTouchEvent} and {@link #onInterceptTouchEvent} methods typically used for + * this purpose. + * + * BubbleStackView is MATCH_PARENT, so that bubbles can be positioned via their translation + * properties for performance reasons. This means that the default implementation of this method + * subtracts the entirety of the screen from the ActivityView's touchable region, resulting in + * it not receiving any touch events. This was previously addressed by returning false in the + * stack's {@link View#canReceivePointerEvents()} method, but this precluded the use of any + * touch handlers in the stack or its child views. + * + * To support touch handlers, we're overriding this method to leave the ActivityView's touchable + * region alone. The only touchable part of the stack that can ever overlap the AV is a + * dragged-out bubble that is animating back into the row of bubbles. It's not worth continually + * updating the touchable region to allow users to grab a bubble while it completes its ~50ms + * animation back to the bubble row. + * + * NOTE: Any future additions to the stack that obscure the ActivityView region will need their + * bounds subtracted here in order to receive touch events. + */ + @Override + public void subtractObscuredTouchableRegion(Region touchableRegion, View view) { - // Since we're dragging the stack, set the magnetized object to the magnetized stack. - mMagnetizedObject = mStackAnimationController.getMagnetizedStack(mMagneticTarget); - mMagnetizedObject.setMagnetListener(mStackMagnetListener); } - void onDragged(float x, float y) { - if (mIsExpanded || mIsExpansionAnimating) { - return; - } - - hideStackUserEducation(false /* fromExpansion */); - springInDismissTarget(); - mStackAnimationController.moveStackFromTouch(x, y); + /** + * If you're here because you're not receiving touch events on a view that is a descendant of + * BubbleStackView, and you think BSV is intercepting them - it's not! You need to subtract the + * bounds of the view in question in {@link #subtractObscuredTouchableRegion}. The ActivityView + * consumes all touch events within its bounds, even for views like the BubbleStackView that are + * above it. It ignores typical view touch handling methods like this one and + * dispatchTouchEvent. + */ + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + return super.onInterceptTouchEvent(ev); } - void onDragFinish(float x, float y, float velX, float velY) { - if (DEBUG_BUBBLE_STACK_VIEW) { - Log.d(TAG, "onDragFinish"); - } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + boolean dispatched = super.dispatchTouchEvent(ev); - if (mIsExpanded || mIsExpansionAnimating) { - return; + // If a new bubble arrives while the collapsed stack is being dragged, it will be positioned + // at the front of the stack (under the touch position). Subsequent ACTION_MOVE events will + // then be passed to the new bubble, which will not consume them since it hasn't received an + // ACTION_DOWN yet. Work around this by passing MotionEvents directly to the touch handler + // until the current gesture ends with an ACTION_UP event. + if (!dispatched && !mIsExpanded && mIsGestureInProgress) { + dispatched = mBubbleTouchListener.onTouch(this /* view */, ev); } - final float newStackX = mStackAnimationController.flingStackThenSpringToEdge(x, velX, velY); - logBubbleEvent(null /* no bubble associated with bubble stack move */, - SysUiStatsLog.BUBBLE_UICHANGED__ACTION__STACK_MOVED); - - mStackOnLeftOrWillBe = newStackX <= 0; - updateBubbleZOrdersAndDotPosition(true /* animate */); - hideDismissTarget(); - } + mIsGestureInProgress = + ev.getAction() != MotionEvent.ACTION_UP + && ev.getAction() != MotionEvent.ACTION_CANCEL; - void onFlyoutDragStart() { - mFlyout.removeCallbacks(mHideFlyout); + return dispatched; } - void onFlyoutDragged(float deltaX) { + void setFlyoutStateForDragLength(float deltaX) { // This shouldn't happen, but if it does, just wait until the flyout lays out. This method // is continually called. if (mFlyout.getWidth() <= 0) { @@ -1538,59 +1629,27 @@ public class BubbleStackView extends FrameLayout { mFlyout.setTranslationX(mFlyout.getRestingTranslationX() + overscrollTranslation); } - void onFlyoutTapped() { - if (maybeShowStackUserEducation()) { - // If we're showing user education, don't open the bubble show the education first - mBubbleToExpandAfterFlyoutCollapse = null; - } else { - mBubbleToExpandAfterFlyoutCollapse = mBubbleData.getSelectedBubble(); - } - - mFlyout.removeCallbacks(mHideFlyout); - mHideFlyout.run(); - } - - /** - * Called when the flyout drag has finished, and returns true if the gesture successfully - * dismissed the flyout. - */ - void onFlyoutDragFinished(float deltaX, float velX) { - final boolean onLeft = mStackAnimationController.isStackOnLeftSide(); - final boolean metRequiredVelocity = - onLeft ? velX < -FLYOUT_DISMISS_VELOCITY : velX > FLYOUT_DISMISS_VELOCITY; - final boolean metRequiredDeltaX = - onLeft - ? deltaX < -mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS - : deltaX > mFlyout.getWidth() * FLYOUT_DRAG_PERCENT_DISMISS; - final boolean isCancelFling = onLeft ? velX > 0 : velX < 0; - final boolean shouldDismiss = metRequiredVelocity || (metRequiredDeltaX && !isCancelFling); - - mFlyout.removeCallbacks(mHideFlyout); - animateFlyoutCollapsed(shouldDismiss, velX); - - maybeShowStackUserEducation(); + /** Passes the MotionEvent to the magnetized object and returns true if it was consumed. */ + private boolean passEventToMagnetizedObject(MotionEvent event) { + return mMagnetizedObject != null && mMagnetizedObject.maybeConsumeMotionEvent(event); } /** - * Called when the first touch event of a gesture (stack drag, bubble drag, flyout drag, etc.) - * is received. + * Dismisses the magnetized object - either an individual bubble, if we're expanded, or the + * stack, if we're collapsed. */ - void onGestureStart() { - mIsGestureInProgress = true; - } - - /** Called when a gesture is completed or cancelled. */ - void onGestureFinished() { - mIsGestureInProgress = false; - + private void dismissMagnetizedObject() { if (mIsExpanded) { - mExpandedAnimationController.onGestureFinished(); - } - } + final View draggedOutBubbleView = (View) mMagnetizedObject.getUnderlyingObject(); + final Bubble draggedOutBubble = mBubbleData.getBubbleWithView(draggedOutBubbleView); - /** Passes the MotionEvent to the magnetized object and returns true if it was consumed. */ - boolean passEventToMagnetizedObject(MotionEvent event) { - return mMagnetizedObject != null && mMagnetizedObject.maybeConsumeMotionEvent(event); + if (mBubbleData.hasBubbleWithKey(draggedOutBubble.getKey())) { + mBubbleData.notificationEntryRemoved( + draggedOutBubble.getEntry(), BubbleController.DISMISS_USER_GESTURE); + } + } else { + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); + } } /** Prepares and starts the desaturate/darken animation on the bubble stack. */ @@ -1624,7 +1683,7 @@ public class BubbleStackView extends FrameLayout { } /** Animates in the dismiss target. */ - private void springInDismissTarget() { + private void springInDismissTargetMaybe() { if (mShowingDismiss) { return; } @@ -1827,13 +1886,6 @@ public class BubbleStackView extends FrameLayout { return 0; } - private boolean isIntersecting(View view, float x, float y) { - mTempLoc = view.getLocationOnScreen(); - mTempRect.set(mTempLoc[0], mTempLoc[1], mTempLoc[0] + view.getWidth(), - mTempLoc[1] + view.getHeight()); - return mTempRect.contains(x, y); - } - private void requestUpdate() { if (mViewUpdatedRequested || mIsExpansionAnimating) { return; diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java deleted file mode 100644 index 132c45fab3d2..000000000000 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleTouchHandler.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2012 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.systemui.bubbles; - -import android.content.Context; -import android.graphics.PointF; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.View; -import android.view.ViewConfiguration; - -import com.android.systemui.Dependency; - -/** - * Handles interpreting touches on a {@link BubbleStackView}. This includes expanding, collapsing, - * dismissing, and flings. - */ -class BubbleTouchHandler implements View.OnTouchListener { - - private final PointF mTouchDown = new PointF(); - private final PointF mViewPositionOnTouchDown = new PointF(); - private final BubbleStackView mStack; - private final BubbleData mBubbleData; - - private BubbleController mController = Dependency.get(BubbleController.class); - - private boolean mMovedEnough; - private int mTouchSlopSquared; - private VelocityTracker mVelocityTracker; - - /** View that was initially touched, when we received the first ACTION_DOWN event. */ - private View mTouchedView; - - BubbleTouchHandler(BubbleStackView stackView, - BubbleData bubbleData, Context context) { - final int touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - mTouchSlopSquared = touchSlop * touchSlop; - mBubbleData = bubbleData; - mStack = stackView; - } - - @Override - public boolean onTouch(View v, MotionEvent event) { - final int action = event.getActionMasked(); - - // If we aren't currently in the process of touching a view, figure out what we're touching. - // It'll be the stack, an individual bubble, or nothing. - if (mTouchedView == null) { - mTouchedView = mStack.getTargetView(event); - } - - // If this is an ACTION_OUTSIDE event, or the stack reported that we aren't touching - // anything, collapse the stack. - if (action == MotionEvent.ACTION_OUTSIDE || mTouchedView == null) { - mBubbleData.setExpanded(false); - mStack.hideStackUserEducation(false /* fromExpansion */); - resetForNextGesture(); - return false; - } - - if (!(mTouchedView instanceof BadgedImageView) - && !(mTouchedView instanceof BubbleStackView) - && !(mTouchedView instanceof BubbleFlyoutView)) { - - // Not touching anything touchable, but we shouldn't collapse (e.g. touching edge - // of expanded view). - mStack.maybeShowManageEducation(false); - resetForNextGesture(); - return false; - } - - final boolean isStack = mStack.equals(mTouchedView); - final boolean isFlyout = mStack.getFlyoutView().equals(mTouchedView); - final float rawX = event.getRawX(); - final float rawY = event.getRawY(); - - // The coordinates of the touch event, in terms of the touched view's position. - final float viewX = mViewPositionOnTouchDown.x + rawX - mTouchDown.x; - final float viewY = mViewPositionOnTouchDown.y + rawY - mTouchDown.y; - switch (action) { - case MotionEvent.ACTION_DOWN: - trackMovement(event); - - mTouchDown.set(rawX, rawY); - mStack.onGestureStart(); - - if (isStack) { - mViewPositionOnTouchDown.set(mStack.getStackPosition()); - - // Dismiss the entire stack if it's released in the dismiss target. - mStack.setReleasedInDismissTargetAction( - () -> mController.dismissStack(BubbleController.DISMISS_USER_GESTURE)); - mStack.onDragStart(); - mStack.passEventToMagnetizedObject(event); - } else if (isFlyout) { - mStack.onFlyoutDragStart(); - } else { - mViewPositionOnTouchDown.set( - mTouchedView.getTranslationX(), mTouchedView.getTranslationY()); - - // Dismiss only the dragged-out bubble if it's released in the target. - final String individualBubbleKey = ((BadgedImageView) mTouchedView).getKey(); - mStack.setReleasedInDismissTargetAction(() -> { - final Bubble bubble = - mBubbleData.getBubbleWithKey(individualBubbleKey); - // bubble can be null if the user is in the middle of - // dismissing the bubble, but the app also sent a cancel - if (bubble != null) { - mController.removeBubble(bubble.getEntry(), - BubbleController.DISMISS_USER_GESTURE); - } - }); - - mStack.onBubbleDragStart(mTouchedView); - mStack.passEventToMagnetizedObject(event); - } - - break; - case MotionEvent.ACTION_MOVE: - trackMovement(event); - final float deltaX = rawX - mTouchDown.x; - final float deltaY = rawY - mTouchDown.y; - - if ((deltaX * deltaX) + (deltaY * deltaY) > mTouchSlopSquared && !mMovedEnough) { - mMovedEnough = true; - } - - if (mMovedEnough) { - if (isFlyout) { - mStack.onFlyoutDragged(deltaX); - } else if (!mStack.passEventToMagnetizedObject(event)) { - // If the magnetic target doesn't consume the event, drag the stack or - // bubble. - if (isStack) { - mStack.onDragged(viewX, viewY); - } else { - mStack.onBubbleDragged(mTouchedView, viewX, viewY); - } - } - } - break; - - case MotionEvent.ACTION_CANCEL: - resetForNextGesture(); - break; - - case MotionEvent.ACTION_UP: - trackMovement(event); - mVelocityTracker.computeCurrentVelocity(/* maxVelocity */ 1000); - final float velX = mVelocityTracker.getXVelocity(); - final float velY = mVelocityTracker.getYVelocity(); - - if (isFlyout && mMovedEnough) { - mStack.onFlyoutDragFinished(rawX - mTouchDown.x /* deltaX */, velX); - } else if (isFlyout) { - if (!mBubbleData.isExpanded() && !mMovedEnough) { - mStack.onFlyoutTapped(); - } - } else if (mMovedEnough) { - if (!mStack.passEventToMagnetizedObject(event)) { - // If the magnetic target didn't consume the event, tell the stack to finish - // the drag. - if (isStack) { - mStack.onDragFinish(viewX, viewY, velX, velY); - } else { - mStack.onBubbleDragFinish(mTouchedView, viewX, viewY, velX, velY); - } - } - } else if (mTouchedView == mStack.getExpandedBubbleView()) { - mBubbleData.setExpanded(false); - } else if (isStack) { - mStack.onStackTapped(); - } else { - final String key = ((BadgedImageView) mTouchedView).getKey(); - if (key == BubbleOverflow.KEY) { - mStack.showOverflow(); - } else { - mStack.expandBubble(mBubbleData.getBubbleWithKey(key)); - } - } - resetForNextGesture(); - break; - } - - return true; - } - - /** Clears all touch-related state. */ - private void resetForNextGesture() { - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - - mTouchedView = null; - mMovedEnough = false; - - mStack.onGestureFinished(); - } - - private void trackMovement(MotionEvent event) { - if (mVelocityTracker == null) { - mVelocityTracker = VelocityTracker.obtain(); - } - mVelocityTracker.addMovement(event); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java index a0b49384d49f..d974adc34ee0 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java @@ -252,8 +252,14 @@ public class ExpandedAnimationController mSpringToTouchOnNextMotionEvent = true; } - /** Prepares the given bubble to be dragged out. */ - public void prepareForBubbleDrag(View bubble, MagnetizedObject.MagneticTarget target) { + /** + * Prepares the given bubble view to be dragged out, using the provided magnetic target and + * listener. + */ + public void prepareForBubbleDrag( + View bubble, + MagnetizedObject.MagneticTarget target, + MagnetizedObject.MagnetListener listener) { mLayout.cancelAnimationsOnView(bubble); bubble.setTranslationZ(Short.MAX_VALUE); @@ -277,6 +283,7 @@ public class ExpandedAnimationController } }; mMagnetizedBubbleDraggingOut.addTarget(target); + mMagnetizedBubbleDraggingOut.setMagnetListener(listener); mMagnetizedBubbleDraggingOut.setHapticsEnabled(true); mMagnetizedBubbleDraggingOut.setFlingToTargetMinVelocity(FLING_TO_DISMISS_MIN_VELOCITY); } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java index c292769f1066..b1bbafc1ed8f 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java @@ -1117,9 +1117,4 @@ public class PhysicsAnimationLayout extends FrameLayout { mAssociatedController = controller; } } - - @Override - protected boolean canReceivePointerEvents() { - return false; - } } diff --git a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt index aa5ebaa22f2d..b7658a9f178d 100644 --- a/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt +++ b/packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt @@ -46,19 +46,6 @@ class SeekBarObserver(view: View) : Observer<SeekBarViewModel.Progress> { /** Updates seek bar views when the data model changes. */ @UiThread override fun onChanged(data: SeekBarViewModel.Progress) { - if (data.enabled && seekBarView.visibility == View.GONE) { - seekBarView.visibility = View.VISIBLE - elapsedTimeView.visibility = View.VISIBLE - totalTimeView.visibility = View.VISIBLE - } else if (!data.enabled && seekBarView.visibility == View.VISIBLE) { - seekBarView.visibility = View.GONE - elapsedTimeView.visibility = View.GONE - totalTimeView.visibility = View.GONE - return - } - - // TODO: update the style of the disabled progress bar - seekBarView.setEnabled(data.seekAvailable) data.color?.let { var tintList = ColorStateList.valueOf(it) @@ -71,6 +58,17 @@ class SeekBarObserver(view: View) : Observer<SeekBarViewModel.Progress> { totalTimeView.setTextColor(it) } + if (!data.enabled) { + seekBarView.setEnabled(false) + seekBarView.getThumb().setAlpha(0) + elapsedTimeView.setText("") + totalTimeView.setText("") + return + } + + seekBarView.getThumb().setAlpha(if (data.seekAvailable) 255 else 0) + seekBarView.setEnabled(data.seekAvailable) + data.elapsedTime?.let { seekBarView.setProgress(it) elapsedTimeView.setText(DateUtils.formatElapsedTime( diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index b10dd93fa695..d2994aebeb33 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -103,6 +103,7 @@ public class PipTaskOrganizer extends TaskOrganizer { @Override public void onPipAnimationEnd(SurfaceControl.Transaction tx, PipAnimationController.PipTransitionAnimator animator) { + finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection()); mMainHandler.post(() -> { for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) { final PipTransitionCallback callback = mPipTransitionCallbacks.get(i); @@ -110,7 +111,6 @@ public class PipTaskOrganizer extends TaskOrganizer { animator.getTransitionDirection()); } }); - finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java index a192afceddb9..a8a5d896537f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -16,12 +16,10 @@ package com.android.systemui.pip.phone; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.ActivityManager.StackInfo; import android.app.IActivityTaskManager; import android.content.Context; import android.graphics.Rect; @@ -169,15 +167,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, */ void synchronizePinnedStackBounds() { cancelAnimations(); - try { - StackInfo stackInfo = mActivityTaskManager.getStackInfo( - WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED); - if (stackInfo != null) { - mBounds.set(stackInfo.bounds); - } - } catch (RemoteException e) { - Log.w(TAG, "Failed to get pinned stack bounds"); - } + mBounds.set(mPipTaskOrganizer.getLastReportedBounds()); } /** diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 52c8960d1ccf..99a01d3f6a7f 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -289,7 +289,6 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mMediaSessionManager = (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE); - mPipTaskOrganizer.registerPipTransitionCallback(this); try { WindowManagerWrapper.getInstance().addPinnedStackListener(mPinnedStackListener); @@ -334,6 +333,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * Shows the picture-in-picture menu if an activity is in picture-in-picture mode. */ public void showPictureInPictureMenu() { + if (DEBUG) Log.d(TAG, "showPictureInPictureMenu(), current state=" + getStateDescription()); + if (getState() == STATE_PIP) { resizePinnedStack(STATE_PIP_MENU); } @@ -343,10 +344,18 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * Closes PIP (PIPed activity and PIP system UI). */ public void closePip() { + if (DEBUG) Log.d(TAG, "closePip(), current state=" + getStateDescription()); + closePipInternal(true); } private void closePipInternal(boolean removePipStack) { + if (DEBUG) { + Log.d(TAG, + "closePipInternal() removePipStack=" + removePipStack + ", current state=" + + getStateDescription()); + } + mState = STATE_NO_PIP; mPipTaskId = TASK_ID_NO_PIP; mPipMediaController = null; @@ -371,6 +380,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * Moves the PIPed activity to the fullscreen and closes PIP system UI. */ void movePipToFullscreen() { + if (DEBUG) Log.d(TAG, "movePipToFullscreen(), current state=" + getStateDescription()); + mPipTaskId = TASK_ID_NO_PIP; for (int i = mListeners.size() - 1; i >= 0; --i) { mListeners.get(i).onMoveToFullscreen(); @@ -386,6 +397,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio public void suspendPipResizing(int reason) { if (DEBUG) Log.d(TAG, "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2)); + mSuspendPipResizingReason |= reason; } @@ -408,7 +420,11 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * @param state In Pip state also used to determine the new size for the Pip. */ void resizePinnedStack(int state) { - if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state, new Exception()); + if (DEBUG) { + Log.d(TAG, "resizePinnedStack() state=" + stateToName(state) + ", current state=" + + getStateDescription(), new Exception()); + } + boolean wasStateNoPip = (mState == STATE_NO_PIP); for (int i = mListeners.size() - 1; i >= 0; --i) { mListeners.get(i).onPipResizeAboutToStart(); @@ -418,7 +434,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio if (DEBUG) Log.d(TAG, "resizePinnedStack() deferring" + " mSuspendPipResizingReason=" + mSuspendPipResizingReason + " mResumeResizePinnedStackRunnableState=" - + mResumeResizePinnedStackRunnableState); + + stateToName(mResumeResizePinnedStackRunnableState)); return; } mState = state; @@ -458,7 +474,8 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio * stack to the centered PIP bound {@link R.config_centeredPictureInPictureBounds}. */ private void showPipMenu() { - if (DEBUG) Log.d(TAG, "showPipMenu()"); + if (DEBUG) Log.d(TAG, "showPipMenu(), current state=" + getStateDescription()); + mState = STATE_PIP_MENU; for (int i = mListeners.size() - 1; i >= 0; --i) { mListeners.get(i).onShowPipMenu(); @@ -712,6 +729,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private void onPipTransitionFinishedOrCanceled() { if (DEBUG) Log.d(TAG, "onPipTransitionFinishedOrCanceled()"); + if (getState() == STATE_PIP_MENU) { showPipMenu(); } @@ -753,4 +771,28 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio WindowManagerWrapper.getInstance().setPipVisibility(visible); }); } + + private String getStateDescription() { + if (mSuspendPipResizingReason == 0) { + return stateToName(mState); + } + return stateToName(mResumeResizePinnedStackRunnableState) + " (while " + stateToName(mState) + + " is suspended)"; + } + + private static String stateToName(int state) { + switch (state) { + case STATE_NO_PIP: + return "NO_PIP"; + + case STATE_PIP: + return "PIP"; + + case STATE_PIP_MENU: + return "PIP_MENU"; + + default: + return "UNKNOWN(" + state + ")"; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java index f43f8e795fe6..c7e77ccfa488 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipMenuActivity.java @@ -22,6 +22,7 @@ import android.app.Activity; import android.content.Intent; import android.content.pm.ParceledListSlice; import android.os.Bundle; +import android.util.Log; import com.android.systemui.R; import com.android.systemui.pip.tv.dagger.TvPipComponent; @@ -34,6 +35,7 @@ import javax.inject.Inject; * Activity to show the PIP menu to control PIP. */ public class PipMenuActivity extends Activity implements PipManager.Listener { + private static final boolean DEBUG = false; private static final String TAG = "PipMenuActivity"; static final String EXTRA_CUSTOM_ACTIONS = "custom_actions"; @@ -47,7 +49,6 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { private boolean mRestorePipSizeWhenClose; private PipControlsViewController mPipControlsViewController; - @Inject public PipMenuActivity(TvPipComponent.Builder pipComponentBuilder, PipManager pipManager) { super(); @@ -57,6 +58,8 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override protected void onCreate(Bundle bundle) { + if (DEBUG) Log.d(TAG, "onCreate()"); + super.onCreate(bundle); if (!mPipManager.isPipShown()) { finish(); @@ -81,13 +84,18 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override protected void onNewIntent(Intent intent) { + if (DEBUG) Log.d(TAG, "onNewIntent(), intent=" + intent); super.onNewIntent(intent); onPipMenuActionsChanged(getIntent().getParcelableExtra(EXTRA_CUSTOM_ACTIONS)); } private void restorePipAndFinish() { + if (DEBUG) Log.d(TAG, "restorePipAndFinish()"); + if (mRestorePipSizeWhenClose) { + if (DEBUG) Log.d(TAG, " > restoring to the default position"); + // When PIP menu activity is closed, restore to the default position. mPipManager.resizePinnedStack(PipManager.STATE_PIP); } @@ -96,12 +104,16 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void onResume() { + if (DEBUG) Log.d(TAG, "onResume()"); + super.onResume(); mFadeInAnimation.start(); } @Override public void onPause() { + if (DEBUG) Log.d(TAG, "onPause()"); + super.onPause(); mFadeOutAnimation.start(); restorePipAndFinish(); @@ -109,6 +121,8 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override protected void onDestroy() { + if (DEBUG) Log.d(TAG, "onDestroy()"); + super.onDestroy(); mPipManager.removeListener(this); mPipManager.resumePipResizing( @@ -117,29 +131,41 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void onBackPressed() { + if (DEBUG) Log.d(TAG, "onBackPressed()"); + restorePipAndFinish(); } @Override - public void onPipEntered() { } + public void onPipEntered() { + if (DEBUG) Log.d(TAG, "onPipEntered()"); + } @Override public void onPipActivityClosed() { + if (DEBUG) Log.d(TAG, "onPipActivityClosed()"); + finish(); } @Override public void onPipMenuActionsChanged(ParceledListSlice actions) { + if (DEBUG) Log.d(TAG, "onPipMenuActionsChanged()"); + boolean hasCustomActions = actions != null && !actions.getList().isEmpty(); mPipControlsViewController.setActions( hasCustomActions ? actions.getList() : Collections.EMPTY_LIST); } @Override - public void onShowPipMenu() { } + public void onShowPipMenu() { + if (DEBUG) Log.d(TAG, "onShowPipMenu()"); + } @Override public void onMoveToFullscreen() { + if (DEBUG) Log.d(TAG, "onMoveToFullscreen()"); + // Moving PIP to fullscreen is implemented by resizing PINNED_STACK with null bounds. // This conflicts with restoring PIP position, so disable it. mRestorePipSizeWhenClose = false; @@ -148,8 +174,17 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void onPipResizeAboutToStart() { + if (DEBUG) Log.d(TAG, "onPipResizeAboutToStart()"); + finish(); mPipManager.suspendPipResizing( PipManager.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH); } + + @Override + public void finish() { + if (DEBUG) Log.d(TAG, "finish()", new RuntimeException()); + + super.finish(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt b/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt new file mode 100644 index 000000000000..d65b285adb0c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/util/RelativeTouchListener.kt @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2020 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.systemui.util + +import android.graphics.PointF +import android.os.Handler +import android.view.MotionEvent +import android.view.VelocityTracker +import android.view.View +import android.view.ViewConfiguration +import kotlin.math.hypot + +/** + * Listener which receives [onDown], [onMove], and [onUp] events, with relevant information about + * the coordinates of the touch and the view relative to the initial ACTION_DOWN event and the + * view's initial position. + */ +abstract class RelativeTouchListener : View.OnTouchListener { + + /** + * Called when an ACTION_DOWN event is received for the given view. + * + * @return False if the object is not interested in MotionEvents at this time, or true if we + * should consume this event and subsequent events, and begin calling [onMove]. + */ + abstract fun onDown(v: View, ev: MotionEvent): Boolean + + /** + * Called when an ACTION_MOVE event is received for the given view. This signals that the view + * is being dragged. + * + * @param viewInitialX The view's translationX value when this touch gesture started. + * @param viewInitialY The view's translationY value when this touch gesture started. + * @param dx Horizontal distance covered since the initial ACTION_DOWN event, in pixels. + * @param dy Vertical distance covered since the initial ACTION_DOWN event, in pixels. + */ + abstract fun onMove( + v: View, + ev: MotionEvent, + viewInitialX: Float, + viewInitialY: Float, + dx: Float, + dy: Float + ) + + /** + * Called when an ACTION_UP event is received for the given view. This signals that a drag or + * fling gesture has completed. + * + * @param viewInitialX The view's translationX value when this touch gesture started. + * @param viewInitialY The view's translationY value when this touch gesture started. + * @param dx Horizontal distance covered, in pixels. + * @param dy Vertical distance covered, in pixels. + * @param velX The final horizontal velocity of the gesture, in pixels/second. + * @param velY The final vertical velocity of the gesture, in pixels/second. + */ + abstract fun onUp( + v: View, + ev: MotionEvent, + viewInitialX: Float, + viewInitialY: Float, + dx: Float, + dy: Float, + velX: Float, + velY: Float + ) + + /** The raw coordinates of the last ACTION_DOWN event. */ + private val touchDown = PointF() + + /** The coordinates of the view, at the time of the last ACTION_DOWN event. */ + private val viewPositionOnTouchDown = PointF() + + private val velocityTracker = VelocityTracker.obtain() + + private var touchSlop: Int = -1 + private var movedEnough = false + + private val handler = Handler() + private var performedLongClick = false + + @Suppress("UNCHECKED_CAST") + override fun onTouch(v: View, ev: MotionEvent): Boolean { + addMovement(ev) + + val dx = ev.rawX - touchDown.x + val dy = ev.rawY - touchDown.y + + when (ev.action) { + MotionEvent.ACTION_DOWN -> { + if (!onDown(v, ev)) { + return false + } + + // Grab the touch slop, it might have changed if the config changed since the + // last gesture. + touchSlop = ViewConfiguration.get(v.context).scaledTouchSlop + + touchDown.set(ev.rawX, ev.rawY) + viewPositionOnTouchDown.set(v.translationX, v.translationY) + + performedLongClick = false + handler.postDelayed({ + performedLongClick = v.performLongClick() + }, ViewConfiguration.getLongPressTimeout().toLong()) + } + + MotionEvent.ACTION_MOVE -> { + if (!movedEnough && hypot(dx, dy) > touchSlop && !performedLongClick) { + movedEnough = true + handler.removeCallbacksAndMessages(null) + } + + if (movedEnough) { + onMove(v, ev, viewPositionOnTouchDown.x, viewPositionOnTouchDown.y, dx, dy) + } + } + + MotionEvent.ACTION_UP -> { + if (movedEnough) { + velocityTracker.computeCurrentVelocity(1000 /* units */) + onUp(v, ev, viewPositionOnTouchDown.x, viewPositionOnTouchDown.y, dx, dy, + velocityTracker.xVelocity, velocityTracker.yVelocity) + } else if (!performedLongClick) { + v.performClick() + } else { + handler.removeCallbacksAndMessages(null) + } + + velocityTracker.clear() + movedEnough = false + } + } + + return true + } + + /** + * Adds a movement to the velocity tracker using raw screen coordinates. + */ + private fun addMovement(event: MotionEvent) { + val deltaX = event.rawX - event.x + val deltaY = event.rawY - event.y + event.offsetLocation(deltaX, deltaY) + velocityTracker.addMovement(event) + event.offsetLocation(-deltaX, -deltaY) + } +}
\ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java index 037f04ec1d7c..e472de349466 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java @@ -374,7 +374,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); assertFalse(mNotificationShadeWindowController.getBubblesShowing()); verify(mNotificationEntryManager, times(3)).updateNotifications(any()); assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); @@ -399,7 +399,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); assertTrue(mNotificationShadeWindowController.getBubbleExpanded()); @@ -436,7 +436,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -448,7 +448,7 @@ public class BubbleControllerTest extends SysuiTestCase { mRow2.getEntry())); // Switch which bubble is expanded - mBubbleController.selectBubble(mRow.getEntry().getKey()); + mBubbleData.setSelectedBubble(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); mBubbleData.setExpanded(true); assertEquals(mRow.getEntry(), mBubbleData.getBubbleWithKey(stackView.getExpandedBubble().getKey()).getEntry()); @@ -482,7 +482,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -510,7 +510,7 @@ public class BubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -544,7 +544,7 @@ public class BubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mSysUiStateBubblesExpanded); @@ -726,7 +726,7 @@ public class BubbleControllerTest extends SysuiTestCase { public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { mBubbleController.updateBubble(mRow.getEntry()); mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java index 545de210d5b5..5f4f2ef04c1d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/NewNotifPipelineBubbleControllerTest.java @@ -321,7 +321,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertNotNull(mBubbleData.getBubbleWithKey(mRow2.getEntry().getKey())); assertTrue(mBubbleController.hasBubbles()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); assertFalse(mNotificationShadeWindowController.getBubblesShowing()); verify(mNotifCallback, times(3)).invalidateNotifications(anyString()); assertNull(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); @@ -344,7 +344,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand the stack BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); assertTrue(mNotificationShadeWindowController.getBubbleExpanded()); @@ -376,7 +376,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -385,7 +385,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleController.isBubbleNotificationSuppressedFromShade(mRow2.getEntry())); // Switch which bubble is expanded - mBubbleController.selectBubble(mRow.getEntry().getKey()); + mBubbleData.setSelectedBubble(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey())); mBubbleData.setExpanded(true); assertEquals(mRow.getEntry(), mBubbleData.getBubbleWithKey(stackView.getExpandedBubble().getKey()).getEntry()); @@ -416,7 +416,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -442,7 +442,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { assertTrue(mBubbleData.getBubbleWithKey(mRow.getEntry().getKey()).showDot()); // Expand - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().getKey()); @@ -474,7 +474,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { // Expand BubbleStackView stackView = mBubbleController.getStackView(); - mBubbleController.expandStack(); + mBubbleData.setExpanded(true); assertTrue(mBubbleController.isStackExpanded()); verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow2.getEntry().getKey()); @@ -628,7 +628,7 @@ public class NewNotifPipelineBubbleControllerTest extends SysuiTestCase { public void testDeleteIntent_dismissStack() throws PendingIntent.CanceledException { mBubbleController.updateBubble(mRow.getEntry()); mBubbleController.updateBubble(mRow2.getEntry()); - mBubbleController.dismissStack(BubbleController.DISMISS_USER_GESTURE); + mBubbleData.dismissAll(BubbleController.DISMISS_USER_GESTURE); verify(mDeleteIntent, times(2)).send(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt index 260f52070a70..d407b8a1e449 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt @@ -67,10 +67,11 @@ public class SeekBarObserverTest : SysuiTestCase() { val isEnabled = false val data = SeekBarViewModel.Progress(isEnabled, false, null, null, null) observer.onChanged(data) - // THEN seek bar visibility is set to GONE - assertThat(seekBarView.getVisibility()).isEqualTo(View.GONE) - assertThat(elapsedTimeView.getVisibility()).isEqualTo(View.GONE) - assertThat(totalTimeView.getVisibility()).isEqualTo(View.GONE) + // THEN seek bar shows just a line with no text + assertThat(seekBarView.isEnabled()).isFalse() + assertThat(seekBarView.getThumb().getAlpha()).isEqualTo(0) + assertThat(elapsedTimeView.getText()).isEqualTo("") + assertThat(totalTimeView.getText()).isEqualTo("") } @Test diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java index ff59c24a7ca2..20a11bd9acd3 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityShellCommand.java @@ -17,6 +17,7 @@ package com.android.server.accessibility; import android.annotation.NonNull; +import android.app.ActivityManager; import android.os.ShellCommand; import android.os.UserHandle; @@ -83,7 +84,7 @@ final class AccessibilityShellCommand extends ShellCommand { return null; } } - return UserHandle.USER_SYSTEM; + return ActivityManager.getCurrentUser(); } @Override diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java index 193107996d1e..c3413e8d2934 100644 --- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java +++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java @@ -98,18 +98,26 @@ class MediaRouter2ServiceImpl { public List<MediaRoute2Info> getSystemRoutes() { final int uid = Binder.getCallingUid(); final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier(); + final boolean hasModifyAudioRoutingPermission = mContext.checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_AUDIO_ROUTING) + == PackageManager.PERMISSION_GRANTED; final long token = Binder.clearCallingIdentity(); try { Collection<MediaRoute2Info> systemRoutes; synchronized (mLock) { UserRecord userRecord = getOrCreateUserRecordLocked(userId); - MediaRoute2ProviderInfo providerInfo = - userRecord.mHandler.mSystemProvider.getProviderInfo(); - if (providerInfo != null) { - systemRoutes = providerInfo.getRoutes(); + if (hasModifyAudioRoutingPermission) { + MediaRoute2ProviderInfo providerInfo = + userRecord.mHandler.mSystemProvider.getProviderInfo(); + if (providerInfo != null) { + systemRoutes = providerInfo.getRoutes(); + } else { + systemRoutes = Collections.emptyList(); + } } else { - systemRoutes = Collections.emptyList(); + systemRoutes = new ArrayList<>(); + systemRoutes.add(userRecord.mHandler.mSystemProvider.getDefaultRoute()); } } return new ArrayList<>(systemRoutes); @@ -122,18 +130,25 @@ class MediaRouter2ServiceImpl { public RoutingSessionInfo getSystemSessionInfo() { final int uid = Binder.getCallingUid(); final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier(); + final boolean hasModifyAudioRoutingPermission = mContext.checkCallingOrSelfPermission( + android.Manifest.permission.MODIFY_AUDIO_ROUTING) + == PackageManager.PERMISSION_GRANTED; final long token = Binder.clearCallingIdentity(); try { RoutingSessionInfo systemSessionInfo = null; synchronized (mLock) { UserRecord userRecord = getOrCreateUserRecordLocked(userId); - List<RoutingSessionInfo> sessionInfos = - userRecord.mHandler.mSystemProvider.getSessionInfos(); - if (sessionInfos != null && !sessionInfos.isEmpty()) { - systemSessionInfo = sessionInfos.get(0); + List<RoutingSessionInfo> sessionInfos; + if (hasModifyAudioRoutingPermission) { + sessionInfos = userRecord.mHandler.mSystemProvider.getSessionInfos(); + if (sessionInfos != null && !sessionInfos.isEmpty()) { + systemSessionInfo = sessionInfos.get(0); + } else { + Slog.w(TAG, "System provider does not have any session info."); + } } else { - Slog.w(TAG, "System provider does not have any session info."); + systemSessionInfo = userRecord.mHandler.mSystemProvider.getDefaultSessionInfo(); } } return systemSessionInfo; @@ -654,10 +669,20 @@ class MediaRouter2ServiceImpl { return; } - routerRecord.mUserRecord.mHandler.sendMessage( - obtainMessage(UserHandler::transferToRouteOnHandler, - routerRecord.mUserRecord.mHandler, - DUMMY_REQUEST_ID, routerRecord, uniqueSessionId, route)); + String defaultRouteId = + routerRecord.mUserRecord.mHandler.mSystemProvider.getDefaultRoute().getId(); + if (route.isSystemRoute() && !routerRecord.mHasModifyAudioRoutingPermission + && !TextUtils.equals(route.getId(), defaultRouteId)) { + routerRecord.mUserRecord.mHandler.sendMessage( + obtainMessage(UserHandler::notifySessionCreationFailedToRouter, + routerRecord.mUserRecord.mHandler, + routerRecord, toOriginalRequestId(DUMMY_REQUEST_ID))); + } else { + routerRecord.mUserRecord.mHandler.sendMessage( + obtainMessage(UserHandler::transferToRouteOnHandler, + routerRecord.mUserRecord.mHandler, + DUMMY_REQUEST_ID, routerRecord, uniqueSessionId, route)); + } } private void setSessionVolumeWithRouter2Locked(@NonNull IMediaRouter2 router, @@ -1185,18 +1210,42 @@ class MediaRouter2ServiceImpl { } } - List<IMediaRouter2> routers = getRouters(); + List<IMediaRouter2> routersWithModifyAudioRoutingPermission = getRouters(true); + List<IMediaRouter2> routersWithoutModifyAudioRoutingPermission = getRouters(false); List<IMediaRouter2Manager> managers = getManagers(); + List<MediaRoute2Info> defaultRoute = new ArrayList<>(); + defaultRoute.add(mSystemProvider.getDefaultRoute()); + if (addedRoutes.size() > 0) { - notifyRoutesAddedToRouters(routers, addedRoutes); + notifyRoutesAddedToRouters(routersWithModifyAudioRoutingPermission, addedRoutes); + if (!provider.mIsSystemRouteProvider) { + notifyRoutesAddedToRouters(routersWithoutModifyAudioRoutingPermission, + addedRoutes); + } else if (prevInfo == null) { + notifyRoutesAddedToRouters(routersWithoutModifyAudioRoutingPermission, + defaultRoute); + } // 'else' is handled as changed routes notifyRoutesAddedToManagers(managers, addedRoutes); } if (removedRoutes.size() > 0) { - notifyRoutesRemovedToRouters(routers, removedRoutes); + notifyRoutesRemovedToRouters(routersWithModifyAudioRoutingPermission, + removedRoutes); + if (!provider.mIsSystemRouteProvider) { + notifyRoutesRemovedToRouters(routersWithoutModifyAudioRoutingPermission, + removedRoutes); + } notifyRoutesRemovedToManagers(managers, removedRoutes); } if (changedRoutes.size() > 0) { - notifyRoutesChangedToRouters(routers, changedRoutes); + notifyRoutesChangedToRouters(routersWithModifyAudioRoutingPermission, + changedRoutes); + if (!provider.mIsSystemRouteProvider) { + notifyRoutesChangedToRouters(routersWithoutModifyAudioRoutingPermission, + changedRoutes); + } else if (prevInfo != null) { + notifyRoutesChangedToRouters(routersWithoutModifyAudioRoutingPermission, + defaultRoute); + } // 'else' is handled as added routes notifyRoutesChangedToManagers(managers, changedRoutes); } } @@ -1223,6 +1272,15 @@ class MediaRouter2ServiceImpl { toOriginalRequestId(uniqueRequestId)); return; } + if (route.isSystemRoute() && !routerRecord.mHasModifyAudioRoutingPermission + && !TextUtils.equals(route.getId(), + mSystemProvider.getDefaultRoute().getId())) { + Slog.w(TAG, "MODIFY_AUDIO_ROUTING permission is required to transfer to" + + route); + notifySessionCreationFailedToRouter(routerRecord, + toOriginalRequestId(uniqueRequestId)); + return; + } SessionCreationRequest request = new SessionCreationRequest(routerRecord, uniqueRequestId, route, managerRecord); @@ -1444,7 +1502,9 @@ class MediaRouter2ServiceImpl { if (service == null) { return; } - notifySessionInfoChangedToRouters(getRouters(), sessionInfo); + notifySessionInfoChangedToRouters(getRouters(true), sessionInfo); + notifySessionInfoChangedToRouters(getRouters(false), + mSystemProvider.getDefaultSessionInfo()); return; } @@ -1565,7 +1625,7 @@ class MediaRouter2ServiceImpl { } } - private List<IMediaRouter2> getRouters() { + private List<IMediaRouter2> getAllRouters() { final List<IMediaRouter2> routers = new ArrayList<>(); MediaRouter2ServiceImpl service = mServiceRef.get(); if (service == null) { @@ -1579,6 +1639,23 @@ class MediaRouter2ServiceImpl { return routers; } + private List<IMediaRouter2> getRouters(boolean hasModifyAudioRoutingPermission) { + final List<IMediaRouter2> routers = new ArrayList<>(); + MediaRouter2ServiceImpl service = mServiceRef.get(); + if (service == null) { + return routers; + } + synchronized (service.mLock) { + for (RouterRecord routerRecord : mUserRecord.mRouterRecords) { + if (hasModifyAudioRoutingPermission + == routerRecord.mHasModifyAudioRoutingPermission) { + routers.add(routerRecord.mRouter); + } + } + } + return routers; + } + private List<IMediaRouter2Manager> getManagers() { final List<IMediaRouter2Manager> managers = new ArrayList<>(); MediaRouter2ServiceImpl service = mServiceRef.get(); diff --git a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java index 5b16d686e04c..6e2feeb15e21 100644 --- a/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java +++ b/services/core/java/com/android/server/media/SystemMediaRoute2Provider.java @@ -72,6 +72,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { // This should be the currently selected route. MediaRoute2Info mDefaultRoute; MediaRoute2Info mDeviceRoute; + RoutingSessionInfo mDefaultSessionInfo; final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo(); final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() { @@ -114,6 +115,7 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } }); updateSessionInfosIfNeeded(); + mContext.registerReceiver(new VolumeChangeReceiver(), new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION)); @@ -156,6 +158,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { @Override public void transferToRoute(long requestId, String sessionId, String routeId) { + if (TextUtils.equals(routeId, DEFAULT_ROUTE_ID)) { + // The currently selected route is the default route. + return; + } if (mBtRouteProvider != null) { if (TextUtils.equals(routeId, mDeviceRoute.getId())) { mBtRouteProvider.transferTo(null); @@ -182,6 +188,10 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { return mDefaultRoute; } + public RoutingSessionInfo getDefaultSessionInfo() { + return mDefaultSessionInfo; + } + private void updateDeviceRoute(AudioRoutesInfo newRoutes) { int name = R.string.default_audio_route_name; if (newRoutes != null) { @@ -229,8 +239,6 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { */ boolean updateSessionInfosIfNeeded() { synchronized (mLock) { - // Prevent to execute this method before mBtRouteProvider is created. - if (mBtRouteProvider == null) return false; RoutingSessionInfo oldSessionInfo = mSessionInfos.isEmpty() ? null : mSessionInfos.get( 0); @@ -238,14 +246,19 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { SYSTEM_SESSION_ID, "" /* clientPackageName */) .setSystemSession(true); - MediaRoute2Info selectedRoute = mBtRouteProvider.getSelectedRoute(); - if (selectedRoute == null) { - selectedRoute = mDeviceRoute; - } else { - builder.addTransferableRoute(mDeviceRoute.getId()); + MediaRoute2Info selectedRoute = mDeviceRoute; + if (mBtRouteProvider != null) { + MediaRoute2Info selectedBtRoute = mBtRouteProvider.getSelectedRoute(); + if (selectedBtRoute != null) { + selectedRoute = selectedBtRoute; + builder.addTransferableRoute(mDeviceRoute.getId()); + } } mSelectedRouteId = selectedRoute.getId(); - mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute).build(); + mDefaultRoute = new MediaRoute2Info.Builder(DEFAULT_ROUTE_ID, selectedRoute) + .setSystemRoute(true) + .setProviderId(mUniqueId) + .build(); builder.addSelectedRoute(mSelectedRouteId); for (MediaRoute2Info route : mBtRouteProvider.getTransferableRoutes()) { @@ -258,6 +271,12 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } else { mSessionInfos.clear(); mSessionInfos.add(newSessionInfo); + mDefaultSessionInfo = new RoutingSessionInfo.Builder( + SYSTEM_SESSION_ID, "" /* clientPackageName */) + .setProviderId(mUniqueId) + .setSystemSession(true) + .addSelectedRoute(DEFAULT_ROUTE_ID) + .build(); return true; } } @@ -302,6 +321,9 @@ class SystemMediaRoute2Provider extends MediaRoute2Provider { } else if (mBtRouteProvider != null) { mBtRouteProvider.setSelectedRouteVolume(newVolume); } + mDefaultRoute = new MediaRoute2Info.Builder(mDefaultRoute) + .setVolume(newVolume) + .build(); publishProviderState(); } } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 98d4b55d0c18..40243e8bbedf 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3421,7 +3421,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo private void setInputMethodTarget(WindowState target, boolean targetWaitingAnim) { // Always update control target. This is needed to handle rotation. - updateImeControlTarget(target); + // We cannot set target as the control target, because mInputMethodTarget can only help + // decide the z-order of IME, but cannot control IME. Only the IME target reported from + // updateInputMethodTargetWindow can control IME. + updateImeControlTarget(mInputMethodControlTarget); if (target == mInputMethodTarget && mInputMethodTargetWaitingAnim == targetWaitingAnim) { return; } diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp index 0635ae169281..18ae4b5af435 100644 --- a/services/incremental/test/IncrementalServiceTest.cpp +++ b/services/incremental/test/IncrementalServiceTest.cpp @@ -137,6 +137,7 @@ public: bool* _aidl_return) { mId = mountId; mListener = listener; + mServiceConnector = control.service; *_aidl_return = true; return binder::Status::ok(); } @@ -166,9 +167,17 @@ public: mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED); } + int32_t setStorageParams(bool enableReadLogs) { + int32_t result = -1; + EXPECT_NE(mServiceConnector.get(), nullptr); + EXPECT_TRUE(mServiceConnector->setStorageParams(enableReadLogs, &result).isOk()); + return result; + } + private: int mId; sp<IDataLoaderStatusListener> mListener; + sp<IIncrementalServiceConnector> mServiceConnector; sp<IDataLoader> mDataLoader = sp<IDataLoader>(new FakeDataLoader()); }; @@ -453,7 +462,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccess) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_GE(mIncrementalService->setStorageParams(storageId, true), 0); + ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChanged) { @@ -480,7 +489,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsSuccessAndPermissionChang mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_GE(mIncrementalService->setStorageParams(storageId, true), 0); + ASSERT_GE(mDataLoaderManager->setStorageParams(true), 0); ASSERT_NE(nullptr, mAppOpsManager->mStoredCallback.get()); mAppOpsManager->mStoredCallback->opChanged(0, {}); } @@ -503,7 +512,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsCheckPermissionFails) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_LT(mIncrementalService->setStorageParams(storageId, true), 0); + ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { @@ -526,7 +535,7 @@ TEST_F(IncrementalServiceTest, testSetIncFsMountOptionsFails) { mIncrementalService->createStorage(tempDir.path, std::move(mDataLoaderParcel), {}, IncrementalService::CreateOptions::CreateNew); ASSERT_GE(storageId, 0); - ASSERT_LT(mIncrementalService->setStorageParams(storageId, true), 0); + ASSERT_LT(mDataLoaderManager->setStorageParams(true), 0); } TEST_F(IncrementalServiceTest, testMakeDirectory) { diff --git a/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java b/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java index c225d3feb063..1aab6722dfee 100644 --- a/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java +++ b/services/systemcaptions/java/com/android/server/systemcaptions/RemoteSystemCaptionsManagerService.java @@ -16,6 +16,8 @@ package com.android.server.systemcaptions; +import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; + import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; @@ -37,6 +39,8 @@ final class RemoteSystemCaptionsManagerService { private static final String SERVICE_INTERFACE = "android.service.systemcaptions.SystemCaptionsManagerService"; + private static final int MSG_BIND = 1; + private final Object mLock = new Object(); private final Context mContext; @@ -71,18 +75,26 @@ final class RemoteSystemCaptionsManagerService { if (mVerbose) { Slog.v(TAG, "initialize()"); } - ensureBound(); + scheduleBind(); + } + + /** + * Destroys this service. + */ + public void destroy() { + mHandler.sendMessage( + obtainMessage(RemoteSystemCaptionsManagerService::handleDestroy, this)); } - void destroy() { + void handleDestroy() { if (mVerbose) { - Slog.v(TAG, "destroy()"); + Slog.v(TAG, "handleDestroy()"); } synchronized (mLock) { if (mDestroyed) { if (mVerbose) { - Slog.v(TAG, "destroy(): Already destroyed"); + Slog.v(TAG, "handleDestroy(): Already destroyed"); } return; } @@ -97,14 +109,24 @@ final class RemoteSystemCaptionsManagerService { } } - private void ensureBound() { + private void scheduleBind() { + if (mHandler.hasMessages(MSG_BIND)) { + if (mVerbose) Slog.v(TAG, "scheduleBind(): already scheduled"); + return; + } + mHandler.sendMessage( + obtainMessage(RemoteSystemCaptionsManagerService::handleEnsureBound, this) + .setWhat(MSG_BIND)); + } + + private void handleEnsureBound() { synchronized (mLock) { if (mService != null || mBinding) { return; } if (mVerbose) { - Slog.v(TAG, "ensureBound(): binding"); + Slog.v(TAG, "handleEnsureBound(): binding"); } mBinding = true; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 1a4b9d735977..56f3c3ec0622 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1178,6 +1178,25 @@ public class CarrierConfigManager { "support_ims_conference_call_bool"; /** + * Determines whether the device will locally disconnect an IMS conference when the participant + * count drops to zero. When {@code true}, it is assumed the carrier does NOT disconnect a + * conference when the participant count drops to zero and that the device must do this by + * disconnecting the conference locally. When {@code false}, it is assumed that the carrier + * is responsible for disconnecting the conference when there are no longer any participants + * present. + * <p> + * Note: both {@link #KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL} and + * {@link #KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL} must be true for this configuration to + * have any effect. + * <p> + * Defaults to {@code false}, meaning the carrier network is responsible for disconnecting an + * empty IMS conference. + * @hide + */ + public static final String KEY_LOCAL_DISCONNECT_EMPTY_IMS_CONFERENCE_BOOL = + "local_disconnect_empty_ims_conference_bool"; + + /** * Determines whether video conference calls are supported by a carrier. When {@code true}, * video calls can be merged into conference calls, {@code false} otherwiwse. * <p> @@ -3793,6 +3812,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_ADD_CONFERENCE_PARTICIPANTS_BOOL, false); sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_CALL_BOOL, true); + sDefaults.putBoolean(KEY_LOCAL_DISCONNECT_EMPTY_IMS_CONFERENCE_BOOL, false); sDefaults.putBoolean(KEY_SUPPORT_MANAGE_IMS_CONFERENCE_CALL_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_ON_PEER_BOOL, true); diff --git a/wifi/jarjar-rules.txt b/wifi/jarjar-rules.txt index eeb006ee6ab2..cf11f4347503 100644 --- a/wifi/jarjar-rules.txt +++ b/wifi/jarjar-rules.txt @@ -53,6 +53,9 @@ rule com.google.protobuf.** com.android.server.x.wifi.protobuf.@1 rule com.android.internal.messages.SystemMessageProto* com.android.server.x.wifi.messages.SystemMessageProto@1 # Use our statically linked PlatformProperties library rule android.sysprop.** com.android.server.x.wifi.sysprop.@1 +# Use our statically linked HIDL stubs +rule android.hardware.** com.android.server.x.wifi.hardware.@1 +rule android.hidl.** com.android.server.x.wifi.hidl.@1 # used by both framework-wifi and wifi-service rule android.content.pm.BaseParceledListSlice* android.x.net.wifi.util.BaseParceledListSlice@1 |