diff options
54 files changed, 1352 insertions, 440 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index 21d3e841b7e0..f2ec2970f9ce 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -307,6 +307,7 @@ package android { field public static final int config_helpPackageNameValue = 17039388; // 0x104001c field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } public static final class R.style { diff --git a/api/test-current.txt b/api/test-current.txt index 68d28233ade0..576cbacb1290 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -45,6 +45,7 @@ package android { field public static final int config_defaultDialer = 17039395; // 0x1040023 field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } } diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index 3dbb6ed47ff8..a8ef54a335c4 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -24,6 +24,7 @@ #include <stdlib.h> #include "guardrail/StatsdStats.h" +#include "metrics/parsing_utils/metrics_manager_util.h" #include "stats_log_util.h" #include "stats_util.h" @@ -122,6 +123,47 @@ CountMetricProducer::~CountMetricProducer() { VLOG("~CountMetricProducer() called"); } +bool CountMetricProducer::onConfigUpdatedLocked( + const StatsdConfig& config, const int configIndex, const int metricIndex, + const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, + const unordered_map<int64_t, int>& newAtomMatchingTrackerMap, + const sp<EventMatcherWizard>& matcherWizard, + const vector<sp<ConditionTracker>>& allConditionTrackers, + const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard, + const unordered_map<int64_t, int>& metricToActivationMap, + unordered_map<int, vector<int>>& trackerToMetricMap, + unordered_map<int, vector<int>>& conditionToMetricMap, + unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, + unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap, + vector<int>& metricsWithActivation) { + if (!MetricProducer::onConfigUpdatedLocked( + config, configIndex, metricIndex, allAtomMatchingTrackers, + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard, + allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap, + trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation)) { + return false; + } + + const CountMetric& metric = config.count_metric(configIndex); + int trackerIndex; + // Update appropriate indices, specifically mConditionIndex and MetricsManager maps. + if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false, + allAtomMatchingTrackers, newAtomMatchingTrackerMap, + trackerToMetricMap, trackerIndex)) { + return false; + } + + if (metric.has_condition() && + !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, + metric.links(), allConditionTrackers, mConditionTrackerIndex, + conditionToMetricMap)) { + return false; + } + return true; +} + void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId, const HashableDimensionKey& primaryKey, const FieldValue& oldState, const FieldValue& newState) { diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h index 6b2f2ca61ecc..0769ac459b8c 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.h +++ b/cmds/statsd/src/metrics/CountMetricProducer.h @@ -97,6 +97,22 @@ private: void flushCurrentBucketLocked(const int64_t& eventTimeNs, const int64_t& nextBucketStartTimeNs) override; + bool onConfigUpdatedLocked( + const StatsdConfig& config, const int configIndex, const int metricIndex, + const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, + const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap, + const sp<EventMatcherWizard>& matcherWizard, + const std::vector<sp<ConditionTracker>>& allConditionTrackers, + const std::unordered_map<int64_t, int>& conditionTrackerMap, + const sp<ConditionWizard>& wizard, + const std::unordered_map<int64_t, int>& metricToActivationMap, + std::unordered_map<int, std::vector<int>>& trackerToMetricMap, + std::unordered_map<int, std::vector<int>>& conditionToMetricMap, + std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, + std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, + std::vector<int>& metricsWithActivation) override; + std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets; // The current bucket (may be a partial bucket). diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h index 320b28581a38..4360010746ae 100644 --- a/cmds/statsd/src/metrics/MetricProducer.h +++ b/cmds/statsd/src/metrics/MetricProducer.h @@ -566,7 +566,9 @@ protected: FRIEND_TEST(MetricsManagerTest, TestInitialConditions); FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricActivations); + FRIEND_TEST(ConfigUpdateTest, TestUpdateCountMetrics); FRIEND_TEST(ConfigUpdateTest, TestUpdateEventMetrics); + FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricsMultipleTypes); }; } // namespace statsd diff --git a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp index 12d3b9487635..5ff69753a4a3 100644 --- a/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp @@ -587,6 +587,51 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 // Now, perform the update. Must iterate the metric types in the same order int metricIndex = 0; + for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) { + newMetricProducerMap[config.count_metric(i).id()] = metricIndex; + const CountMetric& metric = config.count_metric(i); + switch (metricsToUpdate[metricIndex]) { + case UPDATE_PRESERVE: { + const auto& oldMetricProducerIt = oldMetricProducerMap.find(metric.id()); + if (oldMetricProducerIt == oldMetricProducerMap.end()) { + ALOGE("Could not find Metric %lld in the previous config, but expected it " + "to be there", + (long long)metric.id()); + return false; + } + const int oldIndex = oldMetricProducerIt->second; + sp<MetricProducer> producer = oldMetricProducers[oldIndex]; + producer->onConfigUpdated( + config, i, metricIndex, allAtomMatchingTrackers, oldAtomMatchingTrackerMap, + newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers, + conditionTrackerMap, wizard, metricToActivationMap, trackerToMetricMap, + conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation); + newMetricProducers.push_back(producer); + break; + } + case UPDATE_REPLACE: + case UPDATE_NEW: { + sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata( + key, config, timeBaseNs, currentTimeNs, metric, metricIndex, + allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers, + conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap, + allStateGroupMaps, metricToActivationMap, trackerToMetricMap, + conditionToMetricMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation); + if (producer == nullptr) { + return false; + } + newMetricProducers.push_back(producer); + break; + } + default: { + ALOGE("Metric \"%lld\" update state is unknown. This should never happen", + (long long)metric.id()); + return false; + } + } + } for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) { newMetricProducerMap[config.event_metric(i).id()] = metricIndex; const EventMetric& metric = config.event_metric(i); diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp index 51df7df5174e..98c6222c4326 100644 --- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp @@ -348,6 +348,81 @@ bool handleMetricActivationOnConfigUpdate( return true; } +sp<MetricProducer> createCountMetricProducerAndUpdateMetadata( + const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex, + const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const unordered_map<int64_t, int>& atomMatchingTrackerMap, + vector<sp<ConditionTracker>>& allConditionTrackers, + const unordered_map<int64_t, int>& conditionTrackerMap, + const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, + const unordered_map<int64_t, int>& stateAtomIdMap, + const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps, + const unordered_map<int64_t, int>& metricToActivationMap, + unordered_map<int, vector<int>>& trackerToMetricMap, + unordered_map<int, vector<int>>& conditionToMetricMap, + unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap, + unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap, + vector<int>& metricsWithActivation) { + if (!metric.has_id() || !metric.has_what()) { + ALOGW("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id()); + return nullptr; + } + int trackerIndex; + if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, + metric.has_dimensions_in_what(), + allAtomMatchingTrackers, atomMatchingTrackerMap, + trackerToMetricMap, trackerIndex)) { + return nullptr; + } + + int conditionIndex = -1; + if (metric.has_condition()) { + if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, + metric.links(), allConditionTrackers, conditionIndex, + conditionToMetricMap)) { + return nullptr; + } + } else { + if (metric.links_size() > 0) { + ALOGW("metrics has a MetricConditionLink but doesn't have a condition"); + return nullptr; + } + } + + std::vector<int> slicedStateAtoms; + unordered_map<int, unordered_map<int, int64_t>> stateGroupMap; + if (metric.slice_by_state_size() > 0) { + if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap, + allStateGroupMaps, slicedStateAtoms, stateGroupMap)) { + return nullptr; + } + } else { + if (metric.state_link_size() > 0) { + ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state"); + return nullptr; + } + } + + unordered_map<int, shared_ptr<Activation>> eventActivationMap; + unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; + if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap, + atomMatchingTrackerMap, activationAtomTrackerToMetricMap, + deactivationAtomTrackerToMetricMap, metricsWithActivation, + eventActivationMap, eventDeactivationMap)) { + return nullptr; + } + + uint64_t metricHash; + if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { + return nullptr; + } + + return new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, + metricHash, timeBaseNs, currentTimeNs, eventActivationMap, + eventDeactivationMap, slicedStateAtoms, stateGroupMap); +} + sp<MetricProducer> createEventMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const EventMetric& metric, const int metricIndex, @@ -550,68 +625,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t // Build MetricProducers for each metric defined in config. // build CountMetricProducer for (int i = 0; i < config.count_metric_size(); i++) { - const CountMetric& metric = config.count_metric(i); - if (!metric.has_what()) { - ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id()); - return false; - } - int metricIndex = allMetricProducers.size(); + const CountMetric& metric = config.count_metric(i); metricMap.insert({metric.id(), metricIndex}); - int trackerIndex; - if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, - metric.has_dimensions_in_what(), - allAtomMatchingTrackers, atomMatchingTrackerMap, - trackerToMetricMap, trackerIndex)) { - return false; - } - - int conditionIndex = -1; - if (metric.has_condition()) { - if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, - metric.links(), allConditionTrackers, conditionIndex, - conditionToMetricMap)) { - return false; - } - } else { - if (metric.links_size() > 0) { - ALOGW("metrics has a MetricConditionLink but doesn't have a condition"); - return false; - } - } - - std::vector<int> slicedStateAtoms; - unordered_map<int, unordered_map<int, int64_t>> stateGroupMap; - if (metric.slice_by_state_size() > 0) { - if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap, - allStateGroupMaps, slicedStateAtoms, stateGroupMap)) { - return false; - } - } else { - if (metric.state_link_size() > 0) { - ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state"); - return false; - } - } - - unordered_map<int, shared_ptr<Activation>> eventActivationMap; - unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap; - bool success = handleMetricActivation( - config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap, + sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata( + key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex, + allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers, + conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap, + allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, - metricsWithActivation, eventActivationMap, eventDeactivationMap); - if (!success) return false; - - uint64_t metricHash; - if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { + metricsWithActivation); + if (producer == nullptr) { return false; } - - sp<MetricProducer> countProducer = new CountMetricProducer( - key, metric, conditionIndex, initialConditionCache, wizard, metricHash, - timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap, - slicedStateAtoms, stateGroupMap); - allMetricProducers.push_back(countProducer); + allMetricProducers.push_back(producer); } // build DurationMetricProducer diff --git a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h index fdfe5cfa6491..f6b2b7d1602c 100644 --- a/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h @@ -93,6 +93,27 @@ bool handleMetricActivationOnConfigUpdate( std::unordered_map<int, shared_ptr<Activation>>& newEventActivationMap, std::unordered_map<int, std::vector<shared_ptr<Activation>>>& newEventDeactivationMap); +// Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with +// the appropriate indices. Returns an sp to the producer, or null if there was an error. +sp<MetricProducer> createCountMetricProducerAndUpdateMetadata( + const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex, + const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, + const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, + std::vector<sp<ConditionTracker>>& allConditionTrackers, + const std::unordered_map<int64_t, int>& conditionTrackerMap, + const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, + const std::unordered_map<int64_t, int>& stateAtomIdMap, + const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps, + const std::unordered_map<int64_t, int>& metricToActivationMap, + std::unordered_map<int, std::vector<int>>& trackerToMetricMap, + std::unordered_map<int, std::vector<int>>& conditionToMetricMap, + std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, + std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, + std::vector<int>& metricsWithActivation); + +// Creates an EventMetricProducer and updates the vectors/maps used by MetricsManager with +// the appropriate indices. Returns an sp to the producer, or null if there was an error. sp<MetricProducer> createEventMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const EventMetric& metric, const int metricIndex, diff --git a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp index 3b346c11e831..9e6758785911 100644 --- a/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp +++ b/cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp @@ -97,6 +97,7 @@ public: metricsWithActivation.clear(); oldStateHashes.clear(); noReportMetricIds.clear(); + StateManager::getInstance().clear(); } }; @@ -121,6 +122,21 @@ EventMetric createEventMetric(string name, int64_t what, optional<int64_t> condi return metric; } +CountMetric createCountMetric(string name, int64_t what, optional<int64_t> condition, + vector<int64_t> states) { + CountMetric metric; + metric.set_id(StringToId(name)); + metric.set_what(what); + metric.set_bucket(TEN_MINUTES); + if (condition) { + metric.set_condition(condition.value()); + } + for (const int64_t state : states) { + metric.add_slice_by_state(state); + } + return metric; +} + } // anonymous namespace TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) { @@ -1419,7 +1435,7 @@ TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) { EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(event1Id)], newMetricProducers[newMetricProducerMap.at(event1Id)]); - // Make sure replaced conditions are different and included in replacedConditions. + // Make sure replaced metrics are different. EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event2Id)], newMetricProducers[newMetricProducerMap.at(event2Id)]); EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event3Id)], @@ -1478,6 +1494,239 @@ TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) { EXPECT_EQ(oldConditionWizard->getStrongCount(), 1); } +TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) { + StatsdConfig config; + + // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig. + AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher(); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher(); + int64_t matcher2Id = matcher2.id(); + *config.add_atom_matcher() = matcher2; + + AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher(); + int64_t matcher3Id = matcher3.id(); + *config.add_atom_matcher() = matcher3; + + AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher(); + int64_t matcher4Id = matcher4.id(); + *config.add_atom_matcher() = matcher4; + + AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher(); + int64_t matcher5Id = matcher5.id(); + *config.add_atom_matcher() = matcher5; + + Predicate predicate1 = CreateScreenIsOnPredicate(); + int64_t predicate1Id = predicate1.id(); + *config.add_predicate() = predicate1; + + State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321); + int64_t state1Id = state1.id(); + *config.add_state() = state1; + + State state2 = CreateScreenState(); + int64_t state2Id = state2.id(); + *config.add_state() = state2; + + // Add a few count metrics. + // Will be preserved. + CountMetric count1 = createCountMetric("COUNT1", matcher1Id, predicate1Id, {state1Id}); + int64_t count1Id = count1.id(); + *config.add_count_metric() = count1; + + // Will be replaced. + CountMetric count2 = createCountMetric("COUNT2", matcher2Id, nullopt, {}); + int64_t count2Id = count2.id(); + *config.add_count_metric() = count2; + + // Will be replaced. + CountMetric count3 = createCountMetric("COUNT3", matcher3Id, nullopt, {}); + int64_t count3Id = count3.id(); + *config.add_count_metric() = count3; + + // Will be replaced. + CountMetric count4 = createCountMetric("COUNT4", matcher4Id, nullopt, {state2Id}); + int64_t count4Id = count4.id(); + *config.add_count_metric() = count4; + + // Will be deleted. + CountMetric count5 = createCountMetric("COUNT5", matcher5Id, nullopt, {}); + int64_t count5Id = count5.id(); + *config.add_count_metric() = count5; + + EXPECT_TRUE(initConfig(config)); + + // Change bucket size of count2, causing it to be replaced. + count2.set_bucket(ONE_HOUR); + + // Mark matcher 3 as replaced. Causes count3 to be replaced. + set<int64_t> replacedMatchers; + replacedMatchers.insert(matcher3Id); + + // Mark state 2 as replaced and change the state to be about a different atom. + // Causes count4 to be replaced. + set<int64_t> replacedStates; + replacedStates.insert(state2Id); + state2.set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED); + + // Fake that predicate 1 is true for count metric 1. + ASSERT_EQ(oldMetricProducers[0]->getMetricId(), count1Id); + oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0); + EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue); + + EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 1); + // Tell the StateManager that the screen is on. + unique_ptr<LogEvent> event = + CreateScreenStateChangedEvent(0, android::view::DisplayStateEnum::DISPLAY_STATE_ON); + StateManager::getInstance().onLogEvent(*event); + + // New count metric. Should have an initial condition of true since it depends on predicate1. + CountMetric count6 = createCountMetric("EVENT6", matcher2Id, predicate1Id, {state1Id}); + int64_t count6Id = count6.id(); + + // Map the matchers and predicates in reverse order to force the indices to change. + std::unordered_map<int64_t, int> newAtomMatchingTrackerMap; + const int matcher5Index = 0; + newAtomMatchingTrackerMap[matcher5Id] = 0; + const int matcher4Index = 1; + newAtomMatchingTrackerMap[matcher4Id] = 1; + const int matcher3Index = 2; + newAtomMatchingTrackerMap[matcher3Id] = 2; + const int matcher2Index = 3; + newAtomMatchingTrackerMap[matcher2Id] = 3; + const int matcher1Index = 4; + newAtomMatchingTrackerMap[matcher1Id] = 4; + // Use the existing matchers. A bit hacky, but saves code and we don't rely on them. + vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5); + std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(), + newAtomMatchingTrackers.begin()); + + std::unordered_map<int64_t, int> newConditionTrackerMap; + const int predicate1Index = 0; + newConditionTrackerMap[predicate1Id] = 0; + // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them. + vector<sp<ConditionTracker>> newConditionTrackers(1); + std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(), + newConditionTrackers.begin()); + // Fake that predicate1 is true for all new metrics. + vector<ConditionState> conditionCache = {ConditionState::kTrue}; + + StatsdConfig newConfig; + *newConfig.add_count_metric() = count6; + const int count6Index = 0; + *newConfig.add_count_metric() = count3; + const int count3Index = 1; + *newConfig.add_count_metric() = count1; + const int count1Index = 2; + *newConfig.add_count_metric() = count4; + const int count4Index = 3; + *newConfig.add_count_metric() = count2; + const int count2Index = 4; + + *newConfig.add_state() = state1; + *newConfig.add_state() = state2; + + unordered_map<int64_t, int> stateAtomIdMap; + unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps; + map<int64_t, uint64_t> stateProtoHashes; + EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes)); + EXPECT_EQ(stateAtomIdMap[state2Id], util::BATTERY_SAVER_MODE_STATE_CHANGED); + + // Output data structures to validate. + unordered_map<int64_t, int> newMetricProducerMap; + vector<sp<MetricProducer>> newMetricProducers; + unordered_map<int, vector<int>> conditionToMetricMap; + unordered_map<int, vector<int>> trackerToMetricMap; + set<int64_t> noReportMetricIds; + unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; + vector<int> metricsWithActivation; + EXPECT_TRUE(updateMetrics( + key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, + newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{}, + newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates, + oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers, + conditionToMetricMap, trackerToMetricMap, noReportMetricIds, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation)); + + unordered_map<int64_t, int> expectedMetricProducerMap = { + {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index}, + {count4Id, count4Index}, {count6Id, count6Index}, + }; + EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + + // Make sure preserved metrics are the same. + ASSERT_EQ(newMetricProducers.size(), 5); + EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(count1Id)], + newMetricProducers[newMetricProducerMap.at(count1Id)]); + + // Make sure replaced metrics are different. + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count2Id)], + newMetricProducers[newMetricProducerMap.at(count2Id)]); + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count3Id)], + newMetricProducers[newMetricProducerMap.at(count3Id)]); + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count4Id)], + newMetricProducers[newMetricProducerMap.at(count4Id)]); + + // Verify the conditionToMetricMap. + ASSERT_EQ(conditionToMetricMap.size(), 1); + const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index]; + EXPECT_THAT(condition1Metrics, UnorderedElementsAre(count1Index, count6Index)); + + // Verify the trackerToMetricMap. + ASSERT_EQ(trackerToMetricMap.size(), 4); + const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index]; + EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(count1Index)); + const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index]; + EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(count2Index, count6Index)); + const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index]; + EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(count3Index)); + const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index]; + EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(count4Index)); + + // Verify event activation/deactivation maps. + ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(metricsWithActivation.size(), 0); + + // Verify tracker indices/ids/conditions/states are correct. + EXPECT_EQ(newMetricProducers[count1Index]->getMetricId(), count1Id); + EXPECT_EQ(newMetricProducers[count1Index]->mConditionTrackerIndex, predicate1Index); + EXPECT_EQ(newMetricProducers[count1Index]->mCondition, ConditionState::kTrue); + EXPECT_THAT(newMetricProducers[count1Index]->getSlicedStateAtoms(), + UnorderedElementsAre(util::SCREEN_STATE_CHANGED)); + EXPECT_EQ(newMetricProducers[count2Index]->getMetricId(), count2Id); + EXPECT_EQ(newMetricProducers[count2Index]->mConditionTrackerIndex, -1); + EXPECT_EQ(newMetricProducers[count2Index]->mCondition, ConditionState::kTrue); + EXPECT_TRUE(newMetricProducers[count2Index]->getSlicedStateAtoms().empty()); + EXPECT_EQ(newMetricProducers[count3Index]->getMetricId(), count3Id); + EXPECT_EQ(newMetricProducers[count3Index]->mConditionTrackerIndex, -1); + EXPECT_EQ(newMetricProducers[count3Index]->mCondition, ConditionState::kTrue); + EXPECT_TRUE(newMetricProducers[count3Index]->getSlicedStateAtoms().empty()); + EXPECT_EQ(newMetricProducers[count4Index]->getMetricId(), count4Id); + EXPECT_EQ(newMetricProducers[count4Index]->mConditionTrackerIndex, -1); + EXPECT_EQ(newMetricProducers[count4Index]->mCondition, ConditionState::kTrue); + EXPECT_THAT(newMetricProducers[count4Index]->getSlicedStateAtoms(), + UnorderedElementsAre(util::BATTERY_SAVER_MODE_STATE_CHANGED)); + EXPECT_EQ(newMetricProducers[count6Index]->getMetricId(), count6Id); + EXPECT_EQ(newMetricProducers[count6Index]->mConditionTrackerIndex, predicate1Index); + EXPECT_EQ(newMetricProducers[count6Index]->mCondition, ConditionState::kTrue); + EXPECT_THAT(newMetricProducers[count6Index]->getSlicedStateAtoms(), + UnorderedElementsAre(util::SCREEN_STATE_CHANGED)); + + oldMetricProducers.clear(); + // Ensure that the screen state StateTracker did not get deleted and replaced. + EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 2); + FieldValue screenState; + StateManager::getInstance().getStateValue(util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY, + &screenState); + EXPECT_EQ(screenState.mValue.int_value, android::view::DisplayStateEnum::DISPLAY_STATE_ON); +} + TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) { StatsdConfig config; // Add atom matchers @@ -1605,6 +1854,135 @@ TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) { EXPECT_THAT(producer->mEventDeactivationMap[matcher2Index], UnorderedElementsAre(matcher4Activation)); } + +TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) { + StatsdConfig config; + // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig + AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher(); + int64_t matcher1Id = matcher1.id(); + *config.add_atom_matcher() = matcher1; + + AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher(); + int64_t matcher2Id = matcher2.id(); + *config.add_atom_matcher() = matcher2; + + Predicate predicate1 = CreateScreenIsOnPredicate(); + int64_t predicate1Id = predicate1.id(); + *config.add_predicate() = predicate1; + + // Add a few count metrics. + // Will be preserved. + CountMetric countMetric = createCountMetric("COUNT1", matcher1Id, predicate1Id, {}); + int64_t countMetricId = countMetric.id(); + *config.add_count_metric() = countMetric; + + // Will be replaced since matcher2 is replaced. + EventMetric eventMetric = createEventMetric("EVENT1", matcher2Id, nullopt); + int64_t eventMetricId = eventMetric.id(); + *config.add_event_metric() = eventMetric; + + EXPECT_TRUE(initConfig(config)); + + // Used later to ensure the condition wizard is replaced. Get it before doing the update. + sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard; + EXPECT_EQ(oldConditionWizard->getStrongCount(), 3); + + // Mark matcher 2 as replaced. Causes eventMetric to be replaced. + set<int64_t> replacedMatchers; + replacedMatchers.insert(matcher2Id); + + // Map the matchers and predicates in reverse order to force the indices to change. + std::unordered_map<int64_t, int> newAtomMatchingTrackerMap; + const int matcher2Index = 0; + newAtomMatchingTrackerMap[matcher2Id] = 0; + const int matcher1Index = 1; + newAtomMatchingTrackerMap[matcher1Id] = 1; + // Use the existing matchers. A bit hacky, but saves code and we don't rely on them. + vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(2); + std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(), + newAtomMatchingTrackers.begin()); + + std::unordered_map<int64_t, int> newConditionTrackerMap; + const int predicate1Index = 0; + newConditionTrackerMap[predicate1Id] = 0; + // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them. + vector<sp<ConditionTracker>> newConditionTrackers(1); + std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(), + newConditionTrackers.begin()); + vector<ConditionState> conditionCache = {ConditionState::kUnknown}; + + StatsdConfig newConfig; + *newConfig.add_count_metric() = countMetric; + const int countMetricIndex = 0; + *newConfig.add_event_metric() = eventMetric; + const int eventMetricIndex = 1; + + // Output data structures to validate. + unordered_map<int64_t, int> newMetricProducerMap; + vector<sp<MetricProducer>> newMetricProducers; + unordered_map<int, vector<int>> conditionToMetricMap; + unordered_map<int, vector<int>> trackerToMetricMap; + set<int64_t> noReportMetricIds; + unordered_map<int, vector<int>> activationAtomTrackerToMetricMap; + unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap; + vector<int> metricsWithActivation; + EXPECT_TRUE(updateMetrics( + key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(), + oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers, + newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{}, + newConditionTrackers, conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{}, + /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, + newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds, + activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, + metricsWithActivation)); + + unordered_map<int64_t, int> expectedMetricProducerMap = { + {countMetricId, countMetricIndex}, + {eventMetricId, eventMetricIndex}, + }; + EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap)); + + // Make sure preserved metrics are the same. + ASSERT_EQ(newMetricProducers.size(), 2); + EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)], + newMetricProducers[newMetricProducerMap.at(countMetricId)]); + + // Make sure replaced metrics are different. + EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)], + newMetricProducers[newMetricProducerMap.at(eventMetricId)]); + + // Verify the conditionToMetricMap. + ASSERT_EQ(conditionToMetricMap.size(), 1); + const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index]; + EXPECT_THAT(condition1Metrics, UnorderedElementsAre(countMetricIndex)); + + // Verify the trackerToMetricMap. + ASSERT_EQ(trackerToMetricMap.size(), 2); + const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index]; + EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(countMetricIndex)); + const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index]; + EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex)); + + // Verify event activation/deactivation maps. + ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0); + ASSERT_EQ(metricsWithActivation.size(), 0); + + // Verify tracker indices/ids/conditions are correct. + EXPECT_EQ(newMetricProducers[countMetricIndex]->getMetricId(), countMetricId); + EXPECT_EQ(newMetricProducers[countMetricIndex]->mConditionTrackerIndex, predicate1Index); + EXPECT_EQ(newMetricProducers[countMetricIndex]->mCondition, ConditionState::kUnknown); + EXPECT_EQ(newMetricProducers[eventMetricIndex]->getMetricId(), eventMetricId); + EXPECT_EQ(newMetricProducers[eventMetricIndex]->mConditionTrackerIndex, -1); + EXPECT_EQ(newMetricProducers[eventMetricIndex]->mCondition, ConditionState::kTrue); + + sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard; + EXPECT_NE(newConditionWizard, oldConditionWizard); + EXPECT_EQ(newConditionWizard->getStrongCount(), 3); + oldMetricProducers.clear(); + // Only reference to the old wizard should be the one in the test. + EXPECT_EQ(oldConditionWizard->getStrongCount(), 1); +} } // namespace statsd } // namespace os } // namespace android diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 6a6879626c9c..573892bcf014 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -2563,7 +2563,7 @@ public final class BluetoothAdapter { * Create a listening, insecure RFCOMM Bluetooth socket with Service Record. * <p>The link key is not required to be authenticated, i.e the communication may be * vulnerable to Person In the Middle attacks. For Bluetooth 2.1 devices, - * the link will be encrypted, as encryption is mandartory. + * the link will be encrypted, as encryption is mandatory. * For legacy devices (pre Bluetooth 2.1 devices) the link will not * be encrypted. Use {@link #listenUsingRfcommWithServiceRecord}, if an * encrypted and authenticated communication channel is desired. @@ -2602,7 +2602,7 @@ public final class BluetoothAdapter { * an input and output capability or just has the ability to display a numeric key, * a secure socket connection is not possible and this socket can be used. * Use {@link #listenUsingInsecureRfcommWithServiceRecord}, if encryption is not required. - * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandartory. + * For Bluetooth 2.1 devices, the link will be encrypted, as encryption is mandatory. * For more details, refer to the Security Model section 5.2 (vol 3) of * Bluetooth Core Specification version 2.1 + EDR. * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming diff --git a/core/java/android/content/pm/IncrementalStatesInfo.aidl b/core/java/android/content/pm/IncrementalStatesInfo.aidl index b5aad1269c60..7064fbfa8b6a 100644 --- a/core/java/android/content/pm/IncrementalStatesInfo.aidl +++ b/core/java/android/content/pm/IncrementalStatesInfo.aidl @@ -15,6 +15,6 @@ ** limitations under the License. */ -package com.android.server.pm; +package android.content.pm; -parcelable IncrementalStatesInfo;
\ No newline at end of file +parcelable IncrementalStatesInfo; diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java index a79a1cfcd64f..4379ce1055ef 100644 --- a/core/java/android/os/storage/StorageManagerInternal.java +++ b/core/java/android/os/storage/StorageManagerInternal.java @@ -70,13 +70,6 @@ public abstract class StorageManagerInternal { public abstract void addExternalStoragePolicy(ExternalStorageMountPolicy policy); /** - * Notify the mount service that the mount policy for a UID changed. - * @param uid The UID for which policy changed. - * @param packageName The package in the UID for making the call. - */ - public abstract void onExternalStoragePolicyChanged(int uid, String packageName); - - /** * Gets the mount mode to use for a given UID as determined by consultin all * policies. * diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 70224f94d556..e520d7ccaa7a 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -673,8 +673,6 @@ public final class Choreographer { ThreadedRenderer.setFPSDivisor(divisor); } - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "#postFrameCallback} instead") void doFrame(long frameTimeNanos, int frame, long frameTimelineVsyncId) { final long startNanos; synchronized (mLock) { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 430e2cf2bf21..51474d3c39c8 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -17,7 +17,6 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; -import android.os.Build; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -158,8 +157,6 @@ public abstract class DisplayEventReceiver { * @param frameTimelineVsyncId The frame timeline vsync id, used to correlate a frame * produced by HWUI with the timeline data stored in Surface Flinger. */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "Choreographer#postFrameCallback} instead") public void onVsync(long timestampNanos, long physicalDisplayId, int frame, long frameTimelineVsyncId) { } @@ -203,8 +200,6 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@link " - + "Choreographer#postFrameCallback} instead") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, long frameTimelineVsyncId) { onVsync(timestampNanos, physicalDisplayId, frame, frameTimelineVsyncId); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index b653d219b90a..e00ff7e00888 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -78,6 +78,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static android.view.WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY; +import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.IME_FOCUS_CONTROLLER; import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodEditorProto.ClientSideProto.INSETS_CONTROLLER; @@ -2707,7 +2708,13 @@ public final class ViewRootImpl implements ViewParent, updateColorModeIfNeeded(lp.getColorMode()); surfaceCreated = !hadSurface && mSurface.isValid(); surfaceDestroyed = hadSurface && !mSurface.isValid(); - surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId()) + // When using Blast, the surface generation id may not change when there's a new + // SurfaceControl. In that case, we also check relayout flag + // RELAYOUT_RES_SURFACE_CHANGED since it should indicate that WMS created a new + // SurfaceControl. + surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId() + || (relayoutResult & RELAYOUT_RES_SURFACE_CHANGED) + == RELAYOUT_RES_SURFACE_CHANGED) && mSurface.isValid(); if (cutoutChanged) { diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java index d8f2bb248fd1..a7cb642b83f9 100644 --- a/core/java/android/window/TaskOrganizer.java +++ b/core/java/android/window/TaskOrganizer.java @@ -39,13 +39,14 @@ public class TaskOrganizer extends WindowOrganizer { private ITaskOrganizerController mTaskOrganizerController; public TaskOrganizer() { - mTaskOrganizerController = getController(); + this(null); } /** @hide */ @VisibleForTesting public TaskOrganizer(ITaskOrganizerController taskOrganizerController) { - mTaskOrganizerController = taskOrganizerController; + mTaskOrganizerController = taskOrganizerController != null + ? taskOrganizerController : getController(); } /** diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 0892b70b9651..355ef0cd6b3f 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -612,50 +612,77 @@ static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) return ret; } +// String tries to allocate itself on the stack, within a known size, but will +// make a heap allocation if not. +template <size_t StackReserve> +class StackString { +public: + StackString(JNIEnv* env, jstring str) : mEnv(env), mJStr(str) { + LOG_ALWAYS_FATAL_IF(str == nullptr); + mSize = env->GetStringLength(str); + if (mSize > StackReserve) { + mStr = new jchar[mSize]; + } else { + mStr = &mBuffer[0]; + } + mEnv->GetStringRegion(str, 0, mSize, mStr); + } + ~StackString() { + if (mStr != &mBuffer[0]) { + delete[] mStr; + } + } + const jchar* str() { return mStr; } + jsize size() { return mSize; } + +private: + JNIEnv* mEnv; + jstring mJStr; + + jchar mBuffer[StackReserve]; + // pointer to &mBuffer[0] if string fits in mBuffer, otherwise owned + jchar* mStr; + jsize mSize; +}; + +// This size is chosen to be longer than most interface descriptors. +// Ones longer than this will be allocated on the heap. +typedef StackString<64> InterfaceDescriptorString; + static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - // In the current implementation, the token is just the serialized interface name that - // the caller expects to be invoking - const jchar* str = env->GetStringCritical(name, 0); - if (str != NULL) { - parcel->writeInterfaceToken(String16( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name))); - env->ReleaseStringCritical(name, str); - } + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + parcel->writeInterfaceToken(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size()); } } static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); - if (parcel != NULL) { - const jchar* str = env->GetStringCritical(name, 0); - if (str) { - IPCThreadState* threadState = IPCThreadState::self(); - const int32_t oldPolicy = threadState->getStrictModePolicy(); - const bool isValid = parcel->enforceInterface( - reinterpret_cast<const char16_t*>(str), - env->GetStringLength(name), - threadState); - env->ReleaseStringCritical(name, str); - if (isValid) { - const int32_t newPolicy = threadState->getStrictModePolicy(); - if (oldPolicy != newPolicy) { - // Need to keep the Java-level thread-local strict - // mode policy in sync for the libcore - // enforcements, which involves an upcall back - // into Java. (We can't modify the - // Parcel.enforceInterface signature, as it's - // pseudo-public, and used via AIDL - // auto-generation...) - set_dalvik_blockguard_policy(env, newPolicy); - } - return; // everything was correct -> return silently + if (parcel != nullptr) { + InterfaceDescriptorString descriptor(env, name); + IPCThreadState* threadState = IPCThreadState::self(); + const int32_t oldPolicy = threadState->getStrictModePolicy(); + const bool isValid = + parcel->enforceInterface(reinterpret_cast<const char16_t*>(descriptor.str()), + descriptor.size(), threadState); + if (isValid) { + const int32_t newPolicy = threadState->getStrictModePolicy(); + if (oldPolicy != newPolicy) { + // Need to keep the Java-level thread-local strict + // mode policy in sync for the libcore + // enforcements, which involves an upcall back + // into Java. (We can't modify the + // Parcel.enforceInterface signature, as it's + // pseudo-public, and used via AIDL + // auto-generation...) + set_dalvik_blockguard_policy(env, newPolicy); } + return; // everything was correct -> return silently } } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 71e9ed7bee58..f55114c94eed 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1831,6 +1831,8 @@ <string name="config_systemGallery" translatable="false">com.android.gallery3d</string> <!-- The name of the package that will hold the system cluster service role. --> <string name="config_systemAutomotiveCluster" translatable="false"></string> + <!-- The name of the package that will hold the system video call role. --> + <string name="config_systemVideoCall" translatable="false"></string> <!-- The name of the package that will be allowed to change its components' label/icon. --> <string name="config_overrideComponentUiPackage" translatable="false"></string> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 1e2d554a088b..fe17eca35545 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3071,6 +3071,8 @@ <public-group type="string" first-id="0x01040028"> <!-- @hide @SystemApi @TestApi --> <public name="config_systemAutomotiveCluster" /> + <!-- @hide @SystemApi @TestApi --> + <public name="config_systemVideoCall" /> </public-group> <public-group type="id" first-id="0x01020055"> diff --git a/core/xsd/vts/Android.bp b/core/xsd/vts/Android.bp index 4b43b4136076..ca655f18149c 100644 --- a/core/xsd/vts/Android.bp +++ b/core/xsd/vts/Android.bp @@ -40,7 +40,3 @@ cc_test { ], test_config: "vts_permission_validate_test.xml", } - -vts_config { - name: "VtsValidatePermission", -} diff --git a/core/xsd/vts/AndroidTest.xml b/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index e5cc9a0f74ee..000000000000 --- a/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidatePermission."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/permission.xsd->/data/local/tmp/permission.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidatePermission"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_permission_validate_test/vts_permission_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java index 4f1af3e9bea2..3a1bc1eeb9ae 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java @@ -18,6 +18,7 @@ package com.google.errorprone.bugpatterns.android; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static com.google.errorprone.bugpatterns.android.UidChecker.getFlavor; +import static com.google.errorprone.matchers.Matchers.anyOf; import static com.google.errorprone.matchers.Matchers.enclosingClass; import static com.google.errorprone.matchers.Matchers.hasAnnotation; import static com.google.errorprone.matchers.Matchers.instanceMethod; @@ -60,8 +61,13 @@ public final class ContextUserIdChecker extends BugChecker implements MethodInvo private static final Matcher<ExpressionTree> BINDER_CALL = methodInvocation( instanceMethod().onDescendantOf("android.os.IInterface").withAnyName()); - private static final Matcher<ExpressionTree> GET_USER_ID_CALL = methodInvocation( - instanceMethod().onDescendantOf("android.content.Context").named("getUserId")); + private static final Matcher<ExpressionTree> GET_USER_ID_CALL = methodInvocation(anyOf( + instanceMethod().onExactClass("android.app.admin.DevicePolicyManager") + .named("myUserId"), + instanceMethod().onExactClass("android.content.pm.ShortcutManager") + .named("injectMyUserId"), + instanceMethod().onDescendantOf("android.content.Context") + .named("getUserId"))); private static final Matcher<ExpressionTree> USER_ID_FIELD = new Matcher<ExpressionTree>() { @Override diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java index 48123abd26cb..130b256e6622 100644 --- a/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java +++ b/errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java @@ -17,11 +17,14 @@ package com.google.errorprone.bugpatterns.android; import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; +import static com.google.errorprone.matchers.Matchers.allOf; +import static com.google.errorprone.matchers.Matchers.contains; import static com.google.errorprone.matchers.Matchers.enclosingClass; import static com.google.errorprone.matchers.Matchers.hasAnnotation; import static com.google.errorprone.matchers.Matchers.instanceMethod; import static com.google.errorprone.matchers.Matchers.isSameType; import static com.google.errorprone.matchers.Matchers.methodInvocation; +import static com.google.errorprone.matchers.Matchers.not; import static com.google.errorprone.matchers.Matchers.throwStatement; import static com.google.errorprone.matchers.Matchers.variableType; @@ -29,13 +32,17 @@ import com.google.auto.service.AutoService; import com.google.errorprone.BugPattern; import com.google.errorprone.VisitorState; import com.google.errorprone.bugpatterns.BugChecker; -import com.google.errorprone.bugpatterns.BugChecker.CatchTreeMatcher; +import com.google.errorprone.bugpatterns.BugChecker.TryTreeMatcher; import com.google.errorprone.matchers.Description; import com.google.errorprone.matchers.Matcher; +import com.google.errorprone.predicates.TypePredicate; import com.sun.source.tree.CatchTree; +import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.StatementTree; import com.sun.source.tree.Tree; +import com.sun.source.tree.TryTree; import com.sun.source.tree.VariableTree; +import com.sun.tools.javac.code.Type; import java.util.List; @@ -54,9 +61,17 @@ import java.util.List; name = "AndroidFrameworkRethrowFromSystem", summary = "Verifies that system_server calls use rethrowFromSystemServer()", severity = WARNING) -public final class RethrowFromSystemChecker extends BugChecker implements CatchTreeMatcher { +public final class RethrowFromSystemChecker extends BugChecker implements TryTreeMatcher { private static final Matcher<Tree> INSIDE_MANAGER = enclosingClass(hasAnnotation("android.annotation.SystemService")); + + // Purposefully exclude telephony Binder interfaces, since we know they + // always run under the separate AID_RADIO + private static final Matcher<ExpressionTree> SYSTEM_BINDER_CALL = methodInvocation(allOf( + instanceMethod().onDescendantOf("android.os.IInterface").withAnyName(), + not(instanceMethod().onClass(inPackage("com.android.internal.telephony"))), + not(instanceMethod().onClass(inPackage("com.android.internal.telecom"))))); + private static final Matcher<VariableTree> REMOTE_EXCEPTION = variableType( isSameType("android.os.RemoteException")); private static final Matcher<StatementTree> RETHROW_FROM_SYSTEM = throwStatement( @@ -64,17 +79,33 @@ public final class RethrowFromSystemChecker extends BugChecker implements CatchT .named("rethrowFromSystemServer"))); @Override - public Description matchCatch(CatchTree tree, VisitorState state) { + public Description matchTry(TryTree tree, VisitorState state) { if (INSIDE_MANAGER.matches(tree, state) - && REMOTE_EXCEPTION.matches(tree.getParameter(), state)) { - final List<? extends StatementTree> statements = tree.getBlock().getStatements(); - if (statements.size() != 1 || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) { - return buildDescription(tree) - .setMessage("Must contain single " - + "'throw e.rethrowFromSystemServer()' statement") - .build(); + && contains(ExpressionTree.class, SYSTEM_BINDER_CALL) + .matches(tree.getBlock(), state)) { + for (CatchTree catchTree : tree.getCatches()) { + if (REMOTE_EXCEPTION.matches(catchTree.getParameter(), state)) { + final List<? extends StatementTree> statements = catchTree.getBlock() + .getStatements(); + if (statements.size() != 1 + || !RETHROW_FROM_SYSTEM.matches(statements.get(0), state)) { + return buildDescription(catchTree) + .setMessage("Must contain single " + + "'throw e.rethrowFromSystemServer()' statement") + .build(); + } + } } } return Description.NO_MATCH; } + + private static TypePredicate inPackage(final String filter) { + return new TypePredicate() { + @Override + public boolean apply(Type type, VisitorState state) { + return type.tsym.packge().fullname.toString().startsWith(filter); + } + }; + } } diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java index c0b8cd745afc..c8772306a59b 100644 --- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java @@ -92,4 +92,56 @@ public class ContextUserIdCheckerTest { "}") .doTest(); } + + @Test + public void testDevicePolicyManager() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/android/content/Context.java") + .addSourceFile("/android/foo/IFooService.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/UserHandle.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("DevicePolicyManager.java", + "package android.app.admin;", + "import android.annotation.SystemService;", + "import android.content.Context;", + "import android.foo.IFooService;", + "import android.os.UserHandle;", + "import android.os.RemoteException;", + "@SystemService(\"dp\") public class DevicePolicyManager {", + " IFooService mService;", + " int myUserId() { return 0; }", + " void bar() throws RemoteException {", + " mService.baz(null, myUserId());", + " }", + "}") + .doTest(); + } + + @Test + public void testShortcutManager() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/android/content/Context.java") + .addSourceFile("/android/foo/IFooService.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/UserHandle.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("ShortcutManager.java", + "package android.content.pm;", + "import android.annotation.SystemService;", + "import android.content.Context;", + "import android.foo.IFooService;", + "import android.os.UserHandle;", + "import android.os.RemoteException;", + "@SystemService(\"shortcut\") public class ShortcutManager {", + " IFooService mService;", + " int injectMyUserId() { return 0; }", + " void bar() throws RemoteException {", + " mService.baz(null, injectMyUserId());", + " }", + "}") + .doTest(); + } } diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java index 32efbf206a45..0943bd65c06f 100644 --- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java +++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java @@ -105,4 +105,27 @@ public class RethrowFromSystemCheckerTest { "}") .doTest(); } + + @Test + public void testTelephony() { + compilationHelper + .addSourceFile("/android/annotation/SystemService.java") + .addSourceFile("/com/android/internal/telephony/ITelephony.java") + .addSourceFile("/android/os/IInterface.java") + .addSourceFile("/android/os/RemoteException.java") + .addSourceLines("TelephonyManager.java", + "import android.annotation.SystemService;", + "import com.android.internal.telephony.ITelephony;", + "import android.os.RemoteException;", + "@SystemService(\"telephony\") public class TelephonyManager {", + " ITelephony mService;", + " void bar() {", + " try {", + " mService.bar();", + " } catch (RemoteException ignored) {", + " }", + " }", + "}") + .doTest(); + } } diff --git a/errorprone/tests/res/com/android/internal/telephony/ITelephony.java b/errorprone/tests/res/com/android/internal/telephony/ITelephony.java new file mode 100644 index 000000000000..61c4dd561b0b --- /dev/null +++ b/errorprone/tests/res/com/android/internal/telephony/ITelephony.java @@ -0,0 +1,23 @@ +/* + * 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.internal.telephony; + +import android.os.RemoteException; + +public interface ITelephony extends android.os.IInterface { + public void bar() throws RemoteException; +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java index 8f496d01c83b..f6edc073ac4f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java @@ -66,10 +66,7 @@ public class ShellTaskOrganizer extends TaskOrganizer { public ShellTaskOrganizer(SyncTransactionQueue syncQueue, TransactionPool transactionPool, ShellExecutor mainExecutor, ShellExecutor animExecutor) { - super(); - addListener(new FullscreenTaskListener(syncQueue), WINDOWING_MODE_FULLSCREEN); - mTransitions = new Transitions(this, transactionPool, mainExecutor, animExecutor); - if (Transitions.ENABLE_SHELL_TRANSITIONS) registerTransitionPlayer(mTransitions); + this(null, syncQueue, transactionPool, mainExecutor, animExecutor); } @VisibleForTesting diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index bb501fb050e6..e236d24334b3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -88,7 +88,7 @@ import java.util.function.Consumer; * This class is also responsible for general resize/offset PiP operations within SysUI component, * see also {@link PipMotionHelper}. */ -public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganizer.TaskListener, +public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, DisplayController.OnDisplaysChangedListener { private static final String TAG = PipTaskOrganizer.class.getSimpleName(); private static final boolean DEBUG = false; diff --git a/location/java/android/location/util/identity/CallerIdentity.java b/location/java/android/location/util/identity/CallerIdentity.java index c32970f1bb04..e023aa1dcd22 100644 --- a/location/java/android/location/util/identity/CallerIdentity.java +++ b/location/java/android/location/util/identity/CallerIdentity.java @@ -150,6 +150,11 @@ public final class CallerIdentity { return mListenerId; } + /** Returns true if this represents a system identity. */ + public boolean isSystem() { + return mUid == Process.SYSTEM_UID; + } + /** * Adds this identity to the worksource supplied, or if not worksource is supplied, creates a * new worksource representing this identity. diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 2fad7f58b4fb..04847d5fec35 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -307,6 +307,7 @@ package android { field public static final int config_helpPackageNameValue = 17039388; // 0x104001c field public static final int config_systemAutomotiveCluster = 17039400; // 0x1040028 field public static final int config_systemGallery = 17039399; // 0x1040027 + field public static final int config_systemVideoCall = 17039401; // 0x1040029 } public static final class R.style { diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java index e5f2ad5b7586..5122f6cf31a1 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java @@ -27,6 +27,7 @@ import android.graphics.Rect; import android.os.Handler; import android.os.RemoteException; import android.util.Log; +import android.view.InsetsState; import android.view.SurfaceControl; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -81,12 +82,25 @@ public class WindowManagerWrapper { WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; public static final int WINDOWING_MODE_FREEFORM = WindowConfiguration.WINDOWING_MODE_FREEFORM; + public static final int ITYPE_EXTRA_NAVIGATION_BAR = InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; + private static final WindowManagerWrapper sInstance = new WindowManagerWrapper(); public static WindowManagerWrapper getInstance() { return sInstance; } + + /** + * Sets {@param providesInsetsTypes} as the inset types provided by {@param params}. + * @param params The window layout params. + * @param providesInsetsTypes The inset types we would like this layout params to provide. + */ + public void setProvidesInsetsTypes(WindowManager.LayoutParams params, + int[] providesInsetsTypes) { + params.providesInsetsTypes = providesInsetsTypes; + } + /** * @return the stable insets for the primary display. */ diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 6ca99d1a244b..40b171869cf2 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -317,7 +317,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind AndroidFuture<Association> future = new AndroidFuture<>(); service.startDiscovery(request, callingPackage, callback, future); return future; - }).whenComplete(uncheckExceptions((association, err) -> { + }).cancelTimeout().whenComplete(uncheckExceptions((association, err) -> { if (err == null) { addAssociation(association); } else { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 2d87b7c8c724..7775354a8077 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -19,11 +19,9 @@ package com.android.server; import static android.Manifest.permission.ACCESS_MTP; import static android.Manifest.permission.INSTALL_PACKAGES; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; -import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_LEGACY_STORAGE; import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE; -import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES; import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE; import static android.content.pm.PackageManager.MATCH_ANY_USER; @@ -135,7 +133,6 @@ import android.util.TimeUtils; import android.util.Xml; import com.android.internal.annotations.GuardedBy; -import com.android.internal.app.IAppOpsCallback; import com.android.internal.app.IAppOpsService; import com.android.internal.content.PackageMonitor; import com.android.internal.os.AppFuseMount; @@ -151,7 +148,6 @@ import com.android.internal.util.HexDump; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; -import com.android.server.SystemService.TargetUser; import com.android.server.pm.Installer; import com.android.server.storage.AppFuseBridge; import com.android.server.storage.StorageSessionController; @@ -2521,19 +2517,6 @@ class StorageManagerService extends IStorageManager.Stub abortIdleMaint(null); } - private void remountUidExternalStorage(int uid, int mode) { - if (uid == Process.SYSTEM_UID) { - // No need to remount uid for system because it has all access anyways - return; - } - - try { - mVold.remountUid(uid, mode); - } catch (Exception e) { - Slog.wtf(TAG, e); - } - } - @Override public void setDebugFlags(int flags, int mask) { enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS); @@ -3845,21 +3828,6 @@ class StorageManagerService extends IStorageManager.Stub } } - private IAppOpsCallback.Stub mAppOpsCallback = new IAppOpsCallback.Stub() { - @Override - public void opChanged(int op, int uid, String packageName) throws RemoteException { - if (!ENABLE_ISOLATED_STORAGE) return; - - int mountMode = getMountMode(uid, packageName); - boolean isUidActive = LocalServices.getService(ActivityManagerInternal.class) - .getUidProcessState(uid) != PROCESS_STATE_NONEXISTENT; - - if (isUidActive) { - remountUidExternalStorage(uid, mountMode); - } - } - }; - private void addObbStateLocked(ObbState obbState) throws RemoteException { final IBinder binder = obbState.getBinder(); List<ObbState> obbStates = mObbMounts.get(binder); @@ -4546,12 +4514,6 @@ class StorageManagerService extends IStorageManager.Stub } @Override - public void onExternalStoragePolicyChanged(int uid, String packageName) { - final int mountMode = getExternalStorageMountMode(uid, packageName); - remountUidExternalStorage(uid, mountMode); - } - - @Override public int getExternalStorageMountMode(int uid, String packageName) { if (ENABLE_ISOLATED_STORAGE) { return getMountMode(uid, packageName); @@ -4696,16 +4658,6 @@ class StorageManagerService extends IStorageManager.Stub updateLegacyStorageApps(packageName, uid, mode == MODE_ALLOWED); return; } - - if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE - || code == OP_WRITE_EXTERNAL_STORAGE - || code == OP_REQUEST_INSTALL_PACKAGES)) { - final UserManagerInternal userManagerInternal = - LocalServices.getService(UserManagerInternal.class); - if (userManagerInternal.isUserInitialized(UserHandle.getUserId(uid))) { - onExternalStoragePolicyChanged(uid, packageName); - } - } } finally { Binder.restoreCallingIdentity(token); } diff --git a/services/core/java/com/android/server/location/LocationProviderManager.java b/services/core/java/com/android/server/location/LocationProviderManager.java index 48f8da4f4b14..c6a9a1f3a6b3 100644 --- a/services/core/java/com/android/server/location/LocationProviderManager.java +++ b/services/core/java/com/android/server/location/LocationProviderManager.java @@ -524,16 +524,18 @@ class LocationProviderManager extends } } - if (baseRequest.isLocationSettingsIgnored()) { + boolean locationSettingsIgnored = baseRequest.isLocationSettingsIgnored(); + if (locationSettingsIgnored) { // if we are not currently allowed use location settings ignored, disable it if (!mSettingsHelper.getIgnoreSettingsPackageWhitelist().contains( getIdentity().getPackageName()) && !mLocationManagerInternal.isProvider( null, getIdentity())) { builder.setLocationSettingsIgnored(false); + locationSettingsIgnored = false; } } - if (!baseRequest.isLocationSettingsIgnored() && !isThrottlingExempt()) { + if (!locationSettingsIgnored && !isThrottlingExempt()) { // throttle in the background if (!mForeground) { builder.setIntervalMillis(max(baseRequest.getIntervalMillis(), @@ -1010,7 +1012,7 @@ class LocationProviderManager extends // if the provider is currently disabled fail immediately int userId = getIdentity().getUserId(); - if (!getRequest().isLocationSettingsIgnored() && !isEnabled(userId)) { + if (!isEnabled(userId)) { deliverLocation(null); } } @@ -1172,7 +1174,7 @@ class LocationProviderManager extends protected final LocationManagerInternal mLocationManagerInternal; protected final SettingsHelper mSettingsHelper; - protected final UserInfoHelper mUserInfoHelper; + protected final UserInfoHelper mUserHelper; protected final AlarmHelper mAlarmHelper; protected final AppOpsHelper mAppOpsHelper; protected final LocationPermissionsHelper mLocationPermissionsHelper; @@ -1234,7 +1236,7 @@ class LocationProviderManager extends mLocationManagerInternal = Objects.requireNonNull( LocalServices.getService(LocationManagerInternal.class)); mSettingsHelper = injector.getSettingsHelper(); - mUserInfoHelper = injector.getUserInfoHelper(); + mUserHelper = injector.getUserInfoHelper(); mAlarmHelper = injector.getAlarmHelper(); mAppOpsHelper = injector.getAppOpsHelper(); mLocationPermissionsHelper = injector.getLocationPermissionsHelper(); @@ -1259,7 +1261,7 @@ class LocationProviderManager extends synchronized (mLock) { mStarted = true; - mUserInfoHelper.addListener(mUserChangedListener); + mUserHelper.addListener(mUserChangedListener); mSettingsHelper.addOnLocationEnabledChangedListener(mLocationEnabledChangedListener); long identity = Binder.clearCallingIdentity(); @@ -1274,20 +1276,19 @@ class LocationProviderManager extends public void stopManager() { synchronized (mLock) { - mUserInfoHelper.removeListener(mUserChangedListener); + mUserHelper.removeListener(mUserChangedListener); mSettingsHelper.removeOnLocationEnabledChangedListener(mLocationEnabledChangedListener); - // notify and remove all listeners + mStarted = false; + long identity = Binder.clearCallingIdentity(); try { - onUserStopped(UserHandle.USER_ALL); + onEnabledChanged(UserHandle.USER_ALL); removeRegistrationIf(key -> true); + mEnabledListeners.clear(); } finally { Binder.restoreCallingIdentity(identity); } - - mEnabledListeners.clear(); - mStarted = false; } } @@ -1439,11 +1440,13 @@ class LocationProviderManager extends identity.getPackageName())) { return null; } - if (!mUserInfoHelper.isCurrentUserId(identity.getUserId())) { - return null; - } - if (!ignoreLocationSettings && !isEnabled(identity.getUserId())) { - return null; + if (!ignoreLocationSettings) { + if (!isEnabled(identity.getUserId())) { + return null; + } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + return null; + } } Location location = getLastLocationUnsafe(identity.getUserId(), permissionLevel, @@ -1471,7 +1474,7 @@ class LocationProviderManager extends if (userId == UserHandle.USER_ALL) { // find the most recent location across all users Location lastLocation = null; - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { Location next = getLastLocationUnsafe(runningUserIds[i], permissionLevel, ignoreLocationSettings, maximumAgeMs); @@ -1516,7 +1519,7 @@ class LocationProviderManager extends private void setLastLocation(Location location, int userId) { if (userId == UserHandle.USER_ALL) { - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { setLastLocation(location, runningUserIds[i]); } @@ -1542,7 +1545,7 @@ class LocationProviderManager extends @Nullable public ICancellationSignal getCurrentLocation(LocationRequest request, - CallerIdentity callerIdentity, int permissionLevel, ILocationCallback callback) { + CallerIdentity identity, int permissionLevel, ILocationCallback callback) { if (request.getDurationMillis() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) { request = new LocationRequest.Builder(request) .setDurationMillis(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) @@ -1552,27 +1555,31 @@ class LocationProviderManager extends GetCurrentLocationListenerRegistration registration = new GetCurrentLocationListenerRegistration( request, - callerIdentity, + identity, new GetCurrentLocationTransport(callback), permissionLevel); synchronized (mLock) { - if (mSettingsHelper.isLocationPackageBlacklisted(callerIdentity.getUserId(), - callerIdentity.getPackageName())) { + // shortcut various failure conditions so that we can return immediately rather than + // waiting for location to timeout + if (mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), + identity.getPackageName())) { registration.deliverLocation(null); return null; } - if (!mUserInfoHelper.isCurrentUserId(callerIdentity.getUserId())) { - registration.deliverLocation(null); - return null; - } - if (!request.isLocationSettingsIgnored() && !isEnabled(callerIdentity.getUserId())) { - registration.deliverLocation(null); - return null; + if (!request.isLocationSettingsIgnored()) { + if (!isEnabled(identity.getUserId())) { + registration.deliverLocation(null); + return null; + } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + registration.deliverLocation(null); + return null; + } } Location lastLocation = getLastLocationUnsafe( - callerIdentity.getUserId(), + identity.getUserId(), permissionLevel, request.isLocationSettingsIgnored(), MAX_CURRENT_LOCATION_AGE_MS); @@ -1582,11 +1589,11 @@ class LocationProviderManager extends } // if last location isn't good enough then we add a location request - long identity = Binder.clearCallingIdentity(); + long ident = Binder.clearCallingIdentity(); try { addRegistration(callback.asBinder(), registration); } finally { - Binder.restoreCallingIdentity(identity); + Binder.restoreCallingIdentity(ident); } } @@ -1610,20 +1617,20 @@ class LocationProviderManager extends } } - public void registerLocationRequest(LocationRequest request, CallerIdentity callerIdentity, + public void registerLocationRequest(LocationRequest request, CallerIdentity identity, @PermissionLevel int permissionLevel, ILocationListener listener) { synchronized (mLock) { - long identity = Binder.clearCallingIdentity(); + long ident = Binder.clearCallingIdentity(); try { addRegistration( listener.asBinder(), new LocationListenerRegistration( request, - callerIdentity, + identity, new LocationListenerTransport(listener), permissionLevel)); } finally { - Binder.restoreCallingIdentity(identity); + Binder.restoreCallingIdentity(ident); } } } @@ -1850,6 +1857,9 @@ class LocationProviderManager extends if (!isEnabled(identity.getUserId())) { return false; } + if (!identity.isSystem() && !mUserHelper.isCurrentUserId(identity.getUserId())) { + return false; + } switch (mLocationPowerSaveModeHelper.getLocationPowerSaveMode()) { case LOCATION_MODE_FOREGROUND_ONLY: @@ -1978,7 +1988,8 @@ class LocationProviderManager extends synchronized (mLock) { switch (change) { case UserListener.CURRENT_USER_CHANGED: - onEnabledChanged(userId); + updateRegistrations( + registration -> registration.getIdentity().getUserId() == userId); break; case UserListener.USER_STARTED: onUserStarted(userId); @@ -2159,13 +2170,10 @@ class LocationProviderManager extends } if (userId == UserHandle.USER_ALL) { - onEnabledChanged(UserHandle.USER_ALL); mEnabled.clear(); mLastLocations.clear(); } else { Preconditions.checkArgument(userId >= 0); - - onEnabledChanged(userId); mEnabled.delete(userId); mLastLocations.remove(userId); } @@ -2182,7 +2190,7 @@ class LocationProviderManager extends // settings for instance) do not support the null user return; } else if (userId == UserHandle.USER_ALL) { - final int[] runningUserIds = mUserInfoHelper.getRunningUserIds(); + final int[] runningUserIds = mUserHelper.getRunningUserIds(); for (int i = 0; i < runningUserIds.length; i++) { onEnabledChanged(runningUserIds[i]); } @@ -2193,7 +2201,6 @@ class LocationProviderManager extends boolean enabled = mStarted && mProvider.getState().allowed - && mUserInfoHelper.isCurrentUserId(userId) && mSettingsHelper.isLocationEnabled(userId); int index = mEnabled.indexOfKey(userId); @@ -2261,7 +2268,7 @@ class LocationProviderManager extends super.dump(fd, ipw, args); - int[] userIds = mUserInfoHelper.getRunningUserIds(); + int[] userIds = mUserHelper.getRunningUserIds(); for (int userId : userIds) { if (userIds.length != 1) { ipw.print("user "); diff --git a/services/core/java/com/android/server/location/geofence/GeofenceManager.java b/services/core/java/com/android/server/location/geofence/GeofenceManager.java index 58e6d593ed2d..baa01b1506af 100644 --- a/services/core/java/com/android/server/location/geofence/GeofenceManager.java +++ b/services/core/java/com/android/server/location/geofence/GeofenceManager.java @@ -327,7 +327,7 @@ public class GeofenceManager extends protected boolean isActive(GeofenceRegistration registration) { CallerIdentity identity = registration.getIdentity(); return registration.isPermitted() - && mUserInfoHelper.isCurrentUserId(identity.getUserId()) + && (identity.isSystem() || mUserInfoHelper.isCurrentUserId(identity.getUserId())) && mSettingsHelper.isLocationEnabled(identity.getUserId()) && !mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), identity.getPackageName()); diff --git a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java index e782d5ec436d..1cdb118f5787 100644 --- a/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java +++ b/services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java @@ -259,7 +259,7 @@ public abstract class GnssListenerMultiplexer<TRequest, TListener extends IInter CallerIdentity identity = registration.getIdentity(); return registration.isPermitted() && (registration.isForeground() || isBackgroundRestrictionExempt(identity)) - && mUserInfoHelper.isCurrentUserId(identity.getUserId()) + && (identity.isSystem() || mUserInfoHelper.isCurrentUserId(identity.getUserId())) && mLocationManagerInternal.isProviderEnabledForUser(GPS_PROVIDER, identity.getUserId()) && !mSettingsHelper.isLocationPackageBlacklisted(identity.getUserId(), diff --git a/services/core/java/com/android/server/location/util/LocationPowerSaveModeHelper.java b/services/core/java/com/android/server/location/util/LocationPowerSaveModeHelper.java index d85ca5e730b0..6e4cf064b440 100644 --- a/services/core/java/com/android/server/location/util/LocationPowerSaveModeHelper.java +++ b/services/core/java/com/android/server/location/util/LocationPowerSaveModeHelper.java @@ -16,7 +16,13 @@ package com.android.server.location.util; +import static android.os.PowerManager.locationPowerSaveModeToString; + +import static com.android.server.location.LocationManagerService.D; +import static com.android.server.location.LocationManagerService.TAG; + import android.os.PowerManager.LocationPowerSaveMode; +import android.util.Log; import java.util.concurrent.CopyOnWriteArrayList; @@ -60,7 +66,12 @@ public abstract class LocationPowerSaveModeHelper { protected final void notifyLocationPowerSaveModeChanged( @LocationPowerSaveMode int locationPowerSaveMode) { + if (D) { + Log.d(TAG, "location power save mode is now " + locationPowerSaveModeToString( + locationPowerSaveMode)); + } mLocationEventLog.logLocationPowerSaveMode(locationPowerSaveMode); + for (LocationPowerSaveModeChangedListener listener : mListeners) { listener.onLocationPowerSaveModeChanged(locationPowerSaveMode); } diff --git a/services/core/java/com/android/server/location/util/ScreenInteractiveHelper.java b/services/core/java/com/android/server/location/util/ScreenInteractiveHelper.java index d47bce31ed23..ecd6966c1493 100644 --- a/services/core/java/com/android/server/location/util/ScreenInteractiveHelper.java +++ b/services/core/java/com/android/server/location/util/ScreenInteractiveHelper.java @@ -16,6 +16,11 @@ package com.android.server.location.util; +import static com.android.server.location.LocationManagerService.D; +import static com.android.server.location.LocationManagerService.TAG; + +import android.util.Log; + import java.util.concurrent.CopyOnWriteArrayList; /** @@ -55,6 +60,10 @@ public abstract class ScreenInteractiveHelper { } protected final void notifyScreenInteractiveChanged(boolean interactive) { + if (D) { + Log.d(TAG, "screen interactive is now " + interactive); + } + for (ScreenInteractiveChangedListener listener : mListeners) { listener.onScreenInteractiveChanged(interactive); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 98a27228c7cc..4da5fad26960 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -3084,6 +3084,8 @@ public class NotificationManagerService extends SystemService { UserHandle.getUserId(uid), REASON_PACKAGE_BANNED, null); } + mAppOps.setMode(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg, + enabled ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED); try { getContext().sendBroadcastAsUser( new Intent(ACTION_APP_BLOCK_STATE_CHANGED) diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java index 2ff18f8bdf79..de9d3a09df35 100644 --- a/services/core/java/com/android/server/pm/PackageSetting.java +++ b/services/core/java/com/android/server/pm/PackageSetting.java @@ -28,7 +28,7 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.server.pm.parsing.pkg.AndroidPackage; -import com.android.server.pm.permission.AppIdPermissionState; +import com.android.server.pm.permission.LegacyPermissionState; import com.android.server.pm.pkg.PackageStateUnserialized; import java.io.File; @@ -214,11 +214,12 @@ public class PackageSetting extends PackageSettingBase { mimeGroups = updatedMimeGroups; } + @Deprecated @Override - public AppIdPermissionState getPermissionsState() { + public LegacyPermissionState getLegacyPermissionState() { return (sharedUser != null) - ? sharedUser.getPermissionsState() - : super.getPermissionsState(); + ? sharedUser.getLegacyPermissionState() + : super.getLegacyPermissionState(); } public int getAppId() { diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java index c1258b1efd48..968c4b514ed0 100644 --- a/services/core/java/com/android/server/pm/SettingBase.java +++ b/services/core/java/com/android/server/pm/SettingBase.java @@ -19,23 +19,29 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.pm.permission.AppIdPermissionState; +import com.android.server.pm.permission.LegacyPermissionState; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public abstract class SettingBase { int pkgFlags; int pkgPrivateFlags; - protected final AppIdPermissionState mPermissionsState; + /** + * The legacy permission state that is read from package settings persistence for migration. + * This state here can not reflect the current permission state and should not be used for + * purposes other than migration. + */ + @Deprecated + protected final LegacyPermissionState mLegacyPermissionsState; SettingBase(int pkgFlags, int pkgPrivateFlags) { setFlags(pkgFlags); setPrivateFlags(pkgPrivateFlags); - mPermissionsState = new AppIdPermissionState(); + mLegacyPermissionsState = new LegacyPermissionState(); } SettingBase(SettingBase orig) { - mPermissionsState = new AppIdPermissionState(); + mLegacyPermissionsState = new LegacyPermissionState(); doCopy(orig); } @@ -46,11 +52,12 @@ public abstract class SettingBase { private void doCopy(SettingBase orig) { pkgFlags = orig.pkgFlags; pkgPrivateFlags = orig.pkgPrivateFlags; - mPermissionsState.copyFrom(orig.mPermissionsState); + mLegacyPermissionsState.copyFrom(orig.mLegacyPermissionsState); } - public AppIdPermissionState getPermissionsState() { - return mPermissionsState; + @Deprecated + public LegacyPermissionState getLegacyPermissionState() { + return mLegacyPermissionsState; } void setFlags(int pkgFlags) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index c16bd5cdf1fa..1dc035f26d83 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -107,10 +107,10 @@ import com.android.server.pm.Installer.InstallerException; import com.android.server.pm.parsing.PackageInfoUtils; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; -import com.android.server.pm.permission.AppIdPermissionState; -import com.android.server.pm.permission.AppIdPermissionState.PermissionState; import com.android.server.pm.permission.BasePermission; import com.android.server.pm.permission.LegacyPermissionDataProvider; +import com.android.server.pm.permission.LegacyPermissionState; +import com.android.server.pm.permission.LegacyPermissionState.PermissionState; import com.android.server.pm.permission.PermissionSettings; import com.android.server.utils.TimingsTraceAndSlog; @@ -733,7 +733,8 @@ public final class Settings { pkgSetting.signatures = new PackageSignatures(disabledPkg.signatures); pkgSetting.appId = disabledPkg.appId; // Clone permissions - pkgSetting.getPermissionsState().copyFrom(disabledPkg.getPermissionsState()); + pkgSetting.getLegacyPermissionState() + .copyFrom(disabledPkg.getLegacyPermissionState()); // Clone component info List<UserInfo> users = getAllUsers(userManager); if (users != null) { @@ -2114,7 +2115,7 @@ public final class Settings { } void readInstallPermissionsLPr(XmlPullParser parser, - AppIdPermissionState permissionsState) throws IOException, XmlPullParserException { + LegacyPermissionState permissionsState) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT @@ -2406,7 +2407,7 @@ public final class Settings { serializer.attribute(null, "userId", Integer.toString(usr.userId)); usr.signatures.writeXml(serializer, "sigs", mPastSignatures); - writePermissionsLPr(serializer, usr.getPermissionsState() + writePermissionsLPr(serializer, usr.getLegacyPermissionState() .getInstallPermissionStates()); serializer.endTag(null, "shared-user"); } @@ -2734,7 +2735,7 @@ public final class Settings { // If this is a shared user, the permissions will be written there. if (pkg.sharedUser == null) { - writePermissionsLPr(serializer, pkg.getPermissionsState() + writePermissionsLPr(serializer, pkg.getLegacyPermissionState() .getInstallPermissionStates()); } @@ -2825,7 +2826,8 @@ public final class Settings { serializer, "install-initiator-sigs", mPastSignatures); } - writePermissionsLPr(serializer, pkg.getPermissionsState().getInstallPermissionStates()); + writePermissionsLPr(serializer, + pkg.getLegacyPermissionState().getInstallPermissionStates()); writeSigningKeySetLPr(serializer, pkg.keySetData); writeUpgradeKeySetsLPr(serializer, pkg.keySetData); @@ -3551,7 +3553,7 @@ public final class Settings { } if (parser.getName().equals(TAG_PERMISSIONS)) { - readInstallPermissionsLPr(parser, ps.getPermissionsState()); + readInstallPermissionsLPr(parser, ps.getLegacyPermissionState()); } else if (parser.getName().equals(TAG_USES_STATIC_LIB)) { readUsesStaticLibLPw(parser, ps); } else { @@ -3848,7 +3850,7 @@ public final class Settings { packageSetting.signatures.readXml(parser, mPastSignatures); } else if (tagName.equals(TAG_PERMISSIONS)) { readInstallPermissionsLPr(parser, - packageSetting.getPermissionsState()); + packageSetting.getLegacyPermissionState()); packageSetting.installPermissionsFixed = true; } else if (tagName.equals("proper-signing-keyset")) { long id = Long.parseLong(parser.getAttributeValue(null, "identifier")); @@ -4074,7 +4076,7 @@ public final class Settings { if (tagName.equals("sigs")) { su.signatures.readXml(parser, mPastSignatures); } else if (tagName.equals("perms")) { - readInstallPermissionsLPr(parser, su.getPermissionsState()); + readInstallPermissionsLPr(parser, su.getLegacyPermissionState()); } else { PackageManagerService.reportSettingsProblem(Log.WARN, "Unknown element under <shared-user>: " + parser.getName()); @@ -4494,7 +4496,7 @@ public final class Settings { void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet<String> permissionNames, PackageSetting ps, - AppIdPermissionState permissionsState, SimpleDateFormat sdf, Date date, + LegacyPermissionState permissionsState, SimpleDateFormat sdf, Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) { AndroidPackage pkg = ps.pkg; if (checkinTag != null) { @@ -4944,8 +4946,8 @@ public final class Settings { && !packageName.equals(ps.name)) { continue; } - final AppIdPermissionState permissionsState = - mPermissionDataProvider.getAppIdPermissionState(ps.appId); + final LegacyPermissionState permissionsState = + mPermissionDataProvider.getLegacyPermissionState(ps.appId); if (permissionNames != null && !permissionsState.hasPermissionState(permissionNames)) { continue; @@ -5002,8 +5004,8 @@ public final class Settings { pw.println("Hidden system packages:"); printedSomething = true; } - final AppIdPermissionState permissionsState = - mPermissionDataProvider.getAppIdPermissionState(ps.appId); + final LegacyPermissionState permissionsState = + mPermissionDataProvider.getLegacyPermissionState(ps.appId); dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, permissionsState, sdf, date, users, packageName != null, dumpAllComponents); } @@ -5033,8 +5035,8 @@ public final class Settings { if (packageName != null && su != dumpState.getSharedUser()) { continue; } - final AppIdPermissionState permissionsState = - mPermissionDataProvider.getAppIdPermissionState(su.userId); + final LegacyPermissionState permissionsState = + mPermissionDataProvider.getLegacyPermissionState(su.userId); if (permissionNames != null && !permissionsState.hasPermissionState(permissionNames)) { continue; @@ -5178,7 +5180,7 @@ public final class Settings { } void dumpInstallPermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, - AppIdPermissionState permissionsState) { + LegacyPermissionState permissionsState) { Collection<PermissionState> permissionStates = permissionsState.getInstallPermissionStates(); if (!permissionStates.isEmpty()) { @@ -5424,7 +5426,7 @@ public final class Settings { if (packageSetting.sharedUser == null) { List<RuntimePermissionsState.PermissionState> permissions = getPermissionsFromPermissionsState( - packageSetting.getPermissionsState(), userId); + packageSetting.getLegacyPermissionState(), userId); packagePermissions.put(packageName, permissions); } } @@ -5437,7 +5439,7 @@ public final class Settings { SharedUserSetting sharedUserSetting = mSharedUsers.valueAt(i); List<RuntimePermissionsState.PermissionState> permissions = getPermissionsFromPermissionsState( - sharedUserSetting.getPermissionsState(), userId); + sharedUserSetting.getLegacyPermissionState(), userId); sharedUserPermissions.put(sharedUserName, permissions); } @@ -5449,7 +5451,7 @@ public final class Settings { @NonNull private List<RuntimePermissionsState.PermissionState> getPermissionsFromPermissionsState( - @NonNull AppIdPermissionState permissionsState, @UserIdInt int userId) { + @NonNull LegacyPermissionState permissionsState, @UserIdInt int userId) { Collection<PermissionState> permissionStates = permissionsState.getRuntimePermissionStates(userId); List<RuntimePermissionsState.PermissionState> permissions = new ArrayList<>(); @@ -5509,11 +5511,11 @@ public final class Settings { List<RuntimePermissionsState.PermissionState> permissions = packagePermissions.get(packageName); if (permissions != null) { - readPermissionsStateLpr(permissions, packageSetting.getPermissionsState(), + readPermissionsStateLpr(permissions, packageSetting.getLegacyPermissionState(), userId); } else if (packageSetting.sharedUser == null && !isUpgradeToR) { Slog.w(TAG, "Missing permission state for package: " + packageName); - packageSetting.getPermissionsState().setMissing(true, userId); + packageSetting.getLegacyPermissionState().setMissing(true, userId); } } @@ -5527,18 +5529,18 @@ public final class Settings { List<RuntimePermissionsState.PermissionState> permissions = sharedUserPermissions.get(sharedUserName); if (permissions != null) { - readPermissionsStateLpr(permissions, sharedUserSetting.getPermissionsState(), - userId); + readPermissionsStateLpr(permissions, + sharedUserSetting.getLegacyPermissionState(), userId); } else if (!isUpgradeToR) { Slog.w(TAG, "Missing permission state for shared user: " + sharedUserName); - sharedUserSetting.getPermissionsState().setMissing(true, userId); + sharedUserSetting.getLegacyPermissionState().setMissing(true, userId); } } } private void readPermissionsStateLpr( @NonNull List<RuntimePermissionsState.PermissionState> permissions, - @NonNull AppIdPermissionState permissionsState, @UserIdInt int userId) { + @NonNull LegacyPermissionState permissionsState, @UserIdInt int userId) { int permissionsSize = permissions.size(); for (int i = 0; i < permissionsSize; i++) { RuntimePermissionsState.PermissionState permission = permissions.get(i); @@ -5617,7 +5619,7 @@ public final class Settings { XmlUtils.skipCurrentTag(parser); continue; } - parsePermissionsLPr(parser, ps.getPermissionsState(), userId); + parsePermissionsLPr(parser, ps.getLegacyPermissionState(), userId); } break; case TAG_SHARED_USER: { @@ -5628,14 +5630,14 @@ public final class Settings { XmlUtils.skipCurrentTag(parser); continue; } - parsePermissionsLPr(parser, sus.getPermissionsState(), userId); + parsePermissionsLPr(parser, sus.getLegacyPermissionState(), userId); } break; } } } private void parsePermissionsLPr(XmlPullParser parser, - AppIdPermissionState permissionsState, int userId) + LegacyPermissionState permissionsState, int userId) throws IOException, XmlPullParserException { final int outerDepth = parser.getDepth(); int type; diff --git a/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java index 7452b522b20a..346a2c527fcb 100644 --- a/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java @@ -31,7 +31,7 @@ public interface LegacyPermissionDataProvider { * @return the legacy permission state */ @NonNull - public abstract AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId); + LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId); /** * Get the GIDs computed from the permission state of a UID, either a package or a shared user. @@ -40,5 +40,5 @@ public interface LegacyPermissionDataProvider { * @return the GIDs for the UID */ @NonNull - public abstract int[] getGidsForUid(int uid); + int[] getGidsForUid(int uid); } diff --git a/services/core/java/com/android/server/pm/permission/AppIdPermissionState.java b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java index aabdafdd453a..63f69cede59c 100644 --- a/services/core/java/com/android/server/pm/permission/AppIdPermissionState.java +++ b/services/core/java/com/android/server/pm/permission/LegacyPermissionState.java @@ -32,7 +32,7 @@ import java.util.Objects; * Legacy permission state that was associated with packages or shared users. */ //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) -public final class AppIdPermissionState { +public final class LegacyPermissionState { // Maps from user IDs to user states. @NonNull private final SparseArray<UserState> mUserStates = new SparseArray<>(); @@ -48,7 +48,7 @@ public final class AppIdPermissionState { * * @hide */ - public void copyFrom(@NonNull AppIdPermissionState other) { + public void copyFrom(@NonNull LegacyPermissionState other) { if (other == this) { return; } @@ -88,7 +88,7 @@ public final class AppIdPermissionState { if (getClass() != object.getClass()) { return false; } - final AppIdPermissionState other = (AppIdPermissionState) object; + final LegacyPermissionState other = (LegacyPermissionState) object; return Objects.equals(mUserStates, other.mUserStates) && Objects.equals(mMissing, other.mMissing); } diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index b293ba6ccc2d..6a9503c7f8b3 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -104,7 +104,6 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.storage.StorageManager; -import android.os.storage.StorageManagerInternal; import android.permission.IOnPermissionsChangeListener; import android.permission.IPermissionManager; import android.permission.PermissionControllerManager; @@ -1554,24 +1553,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { if (bp.isRuntime()) { notifyRuntimePermissionStateChanged(packageName, userId); } - - // Only need to do this if user is initialized. Otherwise it's a new user - // and there are no processes running as the user yet and there's no need - // to make an expensive call to remount processes for the changed permissions. - if (READ_EXTERNAL_STORAGE.equals(permName) - || WRITE_EXTERNAL_STORAGE.equals(permName)) { - final long token = Binder.clearCallingIdentity(); - try { - if (mUserManagerInt.isUserInitialized(userId)) { - StorageManagerInternal storageManagerInternal = LocalServices.getService( - StorageManagerInternal.class); - storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - } @Override @@ -4618,7 +4599,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int[] userIds = getAllUserIds(); mPackageManagerInt.forEachPackageSetting(ps -> { final int appId = ps.getAppId(); - final AppIdPermissionState appIdState = ps.getPermissionsState(); + final LegacyPermissionState legacyState = ps.getLegacyPermissionState(); synchronized (mLock) { for (final int userId : userIds) { @@ -4627,19 +4608,19 @@ public class PermissionManagerService extends IPermissionManager.Stub { userState.setInstallPermissionsFixed(ps.name, ps.areInstallPermissionsFixed()); final UidPermissionState uidState = userState.getOrCreateUidState(appId); uidState.reset(); - uidState.setMissing(appIdState.isMissing(userId)); + uidState.setMissing(legacyState.isMissing(userId)); readStateFromPermissionStates(uidState, - appIdState.getInstallPermissionStates()); + legacyState.getInstallPermissionStates()); readStateFromPermissionStates(uidState, - appIdState.getRuntimePermissionStates(userId)); + legacyState.getRuntimePermissionStates(userId)); } } }); } private void readStateFromPermissionStates(@NonNull UidPermissionState uidState, - @NonNull Collection<AppIdPermissionState.PermissionState> permissionStates) { - for (final AppIdPermissionState.PermissionState permissionState : permissionStates) { + @NonNull Collection<LegacyPermissionState.PermissionState> permissionStates) { + for (final LegacyPermissionState.PermissionState permissionState : permissionStates) { uidState.putPermissionState(permissionState.getPermission(), permissionState.isGranted(), permissionState.getFlags()); } @@ -4649,8 +4630,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { final int[] userIds = mState.getUserIds(); mPackageManagerInt.forEachPackageSetting(ps -> { ps.setInstallPermissionsFixed(false); - final AppIdPermissionState appIdState = ps.getPermissionsState(); - appIdState.reset(); + final LegacyPermissionState legacyState = ps.getLegacyPermissionState(); + legacyState.reset(); final int appId = ps.getAppId(); synchronized (mLock) { @@ -4672,21 +4653,21 @@ public class PermissionManagerService extends IPermissionManager.Stub { continue; } - appIdState.setMissing(uidState.isMissing(), userId); + legacyState.setMissing(uidState.isMissing(), userId); final List<PermissionState> permissionStates = uidState.getPermissionStates(); final int permissionStatesSize = permissionStates.size(); for (int i = 0; i < permissionStatesSize; i++) { final PermissionState permissionState = permissionStates.get(i); - final AppIdPermissionState.PermissionState legacyPermissionState = - new AppIdPermissionState.PermissionState( + final LegacyPermissionState.PermissionState legacyPermissionState = + new LegacyPermissionState.PermissionState( permissionState.getPermission(), permissionState.isGranted(), permissionState.getFlags()); if (permissionState.isRuntime()) { - appIdState.putRuntimePermissionState(legacyPermissionState, + legacyState.putRuntimePermissionState(legacyPermissionState, userId); } else { - appIdState.putInstallPermissionState(legacyPermissionState); + legacyState.putInstallPermissionState(legacyPermissionState); } } } @@ -4695,8 +4676,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @NonNull - private AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId) { - final AppIdPermissionState appIdState = new AppIdPermissionState(); + private LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) { + final LegacyPermissionState legacyState = new LegacyPermissionState(); final int[] userIds = mState.getUserIds(); for (final int userId : userIds) { final UidPermissionState uidState = getUidState(appId, userId); @@ -4711,17 +4692,17 @@ public class PermissionManagerService extends IPermissionManager.Stub { for (int i = 0; i < permissionStatesSize; i++) { final PermissionState permissionState = permissionStates.get(i); - final AppIdPermissionState.PermissionState legacyPermissionState = - new AppIdPermissionState.PermissionState(permissionState.getPermission(), + final LegacyPermissionState.PermissionState legacyPermissionState = + new LegacyPermissionState.PermissionState(permissionState.getPermission(), permissionState.isGranted(), permissionState.getFlags()); if (permissionState.isRuntime()) { - appIdState.putRuntimePermissionState(legacyPermissionState, userId); + legacyState.putRuntimePermissionState(legacyPermissionState, userId); } else if (userId == UserHandle.USER_SYSTEM) { - appIdState.putInstallPermissionState(legacyPermissionState); + legacyState.putInstallPermissionState(legacyPermissionState); } } } - return appIdState; + return legacyState; } @NonNull @@ -5130,8 +5111,8 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @NonNull - public AppIdPermissionState getAppIdPermissionState(@AppIdInt int appId) { - return PermissionManagerService.this.getAppIdPermissionState(appId); + public LegacyPermissionState getLegacyPermissionState(@AppIdInt int appId) { + return PermissionManagerService.this.getLegacyPermissionState(appId); } @NonNull diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java index 56e1187d51da..a0074a2d760c 100644 --- a/services/core/java/com/android/server/wm/LaunchParamsController.java +++ b/services/core/java/com/android/server/wm/LaunchParamsController.java @@ -144,11 +144,11 @@ class LaunchParamsController { mTmpParams.mPreferredTaskDisplayArea, true /* onTop */); } - if (mTmpParams.hasWindowingMode() - && mTmpParams.mWindowingMode != task.getRootTask().getWindowingMode()) { + if (mTmpParams.hasWindowingMode() && task.isRootTask() + && mTmpParams.mWindowingMode != task.getWindowingMode()) { final int activityType = activity != null ? activity.getActivityType() : task.getActivityType(); - task.getRootTask().setWindowingMode(task.getDisplayArea().validateWindowingMode( + task.setWindowingMode(task.getDisplayArea().validateWindowingMode( mTmpParams.mWindowingMode, activity, task, activityType)); } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 696e1cafae95..ce99102fddb3 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -1305,10 +1305,9 @@ final class TaskDisplayArea extends DisplayArea<Task> { final int windowingMode = windowingModes[j]; for (int i = getStackCount() - 1; i >= 0; --i) { final Task stack = getStackAt(i); - if (!stack.isActivityTypeStandardOrUndefined()) { - continue; - } - if (stack.getWindowingMode() != windowingMode) { + if (stack.mCreatedByOrganizer + || !stack.isActivityTypeStandardOrUndefined() + || stack.getWindowingMode() != windowingMode) { continue; } stacks.add(stack); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 9f653d6124b9..13d8dc4c6be1 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -23,12 +23,10 @@ import static android.graphics.Matrix.MSKEW_Y; import static android.graphics.Matrix.MTRANS_X; import static android.graphics.Matrix.MTRANS_Y; import static android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; -import static android.view.WindowManager.LayoutParams.FLAG_SCALED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import static android.view.WindowManager.TRANSIT_NONE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DRAW; @@ -46,19 +44,16 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_CROP; import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER; import static com.android.server.wm.WindowManagerService.logWithStack; import static com.android.server.wm.WindowStateAnimatorProto.DRAW_STATE; -import static com.android.server.wm.WindowStateAnimatorProto.LAST_CLIP_RECT; import static com.android.server.wm.WindowStateAnimatorProto.SURFACE; import static com.android.server.wm.WindowStateAnimatorProto.SYSTEM_DECOR_RECT; import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE; -import android.app.WindowConfiguration; import android.content.Context; import android.graphics.Matrix; import android.graphics.PixelFormat; @@ -365,7 +360,7 @@ class WindowStateAnimator { if (mSurfaceController != null && mPendingDestroySurface != null) { mPostDrawTransaction.reparentChildren( mSurfaceController.getClientViewRootSurface(), - mPendingDestroySurface.mSurfaceControl).apply(); + mPendingDestroySurface.getClientViewRootSurface()).apply(); } destroySurfaceLocked(); mSurfaceDestroyDeferred = true; @@ -399,7 +394,7 @@ class WindowStateAnimator { && (mWin.mActivityRecord == null || !mWin.mActivityRecord.isRelaunching())) { mPostDrawTransaction.reparentChildren( mPendingDestroySurface.getClientViewRootSurface(), - mSurfaceController.mSurfaceControl).apply(); + mSurfaceController.getClientViewRootSurface()).apply(); } destroyDeferredSurfaceLocked(); @@ -993,7 +988,7 @@ class WindowStateAnimator { if (!mPendingDestroySurface.mChildrenDetached) { mPostDrawTransaction.reparentChildren( mPendingDestroySurface.getClientViewRootSurface(), - mSurfaceController.mSurfaceControl); + mSurfaceController.getClientViewRootSurface()); } } diff --git a/services/core/xsd/vts/Android.mk b/services/core/xsd/vts/Android.mk deleted file mode 100644 index 6dc2c437a2f9..000000000000 --- a/services/core/xsd/vts/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := VtsValidateDefaultPermissions -include test/vts/tools/build/Android.host_config.mk diff --git a/services/core/xsd/vts/AndroidTest.xml b/services/core/xsd/vts/AndroidTest.xml deleted file mode 100644 index 4f3b2ef1ace1..000000000000 --- a/services/core/xsd/vts/AndroidTest.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2019 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Config for VTS VtsValidateDefaultPermissions."> - <option name="config-descriptor:metadata" key="plan" value="vts-treble" /> - <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher"> - <option name="abort-on-push-failure" value="false"/> - <option name="push-group" value="HostDrivenTest.push"/> - <option name="push" value="DATA/etc/default-permissions.xsd->/data/local/tmp/default-permissions.xsd"/> - </target_preparer> - <test class="com.android.tradefed.testtype.VtsMultiDeviceTest"> - <option name="test-module-name" value="VtsValidateDefaultPermissions"/> - <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_defaultPermissions_validate_test/vts_defaultPermissions_validate_test" /> - <option name="binary-test-type" value="gtest"/> - <option name="test-timeout" value="30s"/> - </test> -</configuration> diff --git a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java index be258dc5963e..3cd415ecb1c5 100644 --- a/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java @@ -202,22 +202,20 @@ public class LocationProviderManagerTest { @Test public void testIsEnabled() { assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER); mProvider.setAllowed(false); assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isFalse(); mProvider.setAllowed(true); - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - assertThat(mManager.isEnabled(CURRENT_USER)).isFalse(); - assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); - - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); assertThat(mManager.isEnabled(CURRENT_USER)).isTrue(); - assertThat(mManager.isEnabled(OTHER_USER)).isFalse(); + assertThat(mManager.isEnabled(OTHER_USER)).isTrue(); } @Test @@ -237,23 +235,15 @@ public class LocationProviderManagerTest { mProvider.setAllowed(false); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, false); + verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, + false); mProvider.setAllowed(true); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER, true); - - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, CURRENT_USER, - false); verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, true); - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, CURRENT_USER, - true); - verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER, - false); - mManager.removeEnabledListener(listener); mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER); verifyNoMoreInteractions(listener); @@ -397,16 +387,6 @@ public class LocationProviderManagerTest { mProvider.setAllowed(true); verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true); - mInjector.getUserInfoHelper().setCurrentUserId(OTHER_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, false); - loc = createLocation(NAME, mRandom); - mProvider.setProviderLocation(loc); - verify(listener, times(1)).onLocationChanged(any(Location.class), - nullable(IRemoteCallback.class)); - - mInjector.getUserInfoHelper().setCurrentUserId(CURRENT_USER); - verify(listener, timeout(TIMEOUT_MS).times(3)).onProviderEnabledChanged(NAME, true); - loc = createLocation(NAME, mRandom); mProvider.setProviderLocation(loc); verify(listener, times(2)).onLocationChanged(locationCaptor.capture(), diff --git a/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java new file mode 100644 index 000000000000..62e135b09593 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java @@ -0,0 +1,316 @@ +/* + * 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.server.pm; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.content.pm.IDataLoaderStatusListener; +import android.content.pm.PackageManager; +import android.os.ConditionVariable; +import android.os.incremental.IStorageHealthListener; +import android.platform.test.annotations.Presubmit; + +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Unit tests for {@link IncrementalStates}. + * Run with: atest -c FrameworksServicesTests:com.android.server.pm.IncrementalStatesTest + */ +@Presubmit +@RunWith(AndroidJUnit4.class) +@MediumTest +public class IncrementalStatesTest { + private IncrementalStates mIncrementalStates; + private ConditionVariable mUnstartableCalled = new ConditionVariable(); + private ConditionVariable mStartableCalled = new ConditionVariable(); + private ConditionVariable mFullyLoadedCalled = new ConditionVariable(); + private AtomicInteger mUnstartableReason = new AtomicInteger(0); + private static final int WAIT_TIMEOUT_MILLIS = 1000; /* 1 second */ + private IncrementalStates.Callback mCallback = new IncrementalStates.Callback() { + @Override + public void onPackageUnstartable(int reason) { + mUnstartableCalled.open(); + mUnstartableReason.set(reason); + } + + @Override + public void onPackageStartable() { + mStartableCalled.open(); + } + + @Override + public void onPackageFullyLoaded() { + mFullyLoadedCalled.open(); + } + }; + + /** + * Setup the tests as if the package has just been committed. + * By default the package is now startable and is loading. + */ + @Before + public void setUp() { + mIncrementalStates = new IncrementalStates(); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.setCallback(mCallback); + mIncrementalStates.onCommit(true); + // Test that package is now startable and loading + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + assertTrue(mIncrementalStates.isLoading()); + mStartableCalled.close(); + mUnstartableCalled.close(); + mFullyLoadedCalled.close(); + } + + /** + * Test that startable state changes to false when Incremental Storage is unhealthy. + */ + @Test + public void testStartableTransition_IncrementalStorageUnhealthy() { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_UNKNOWN, mUnstartableReason.get()); + } + + /** + * Test that the package is still startable when Incremental Storage has pending reads. + */ + @Test + public void testStartableTransition_IncrementalStorageReadsPending() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_READS_PENDING); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package is still startable when Incremental Storage is at blocked status. + */ + @Test + public void testStartableTransition_IncrementalStorageBlocked() { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_BLOCKED); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package is still startable when Data Loader has unknown transportation issues. + */ + @Test + public void testStartableTransition_DataLoaderTransportError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_TRANSPORT_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data integrity issues. + */ + @Test + public void testStartableTransition_DataLoaderIntegrityError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data source issues. + */ + @Test + public void testStartableTransition_DataLoaderSourceError() { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_SOURCE_ERROR); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_TRANSPORT, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader hits limited storage while + * Incremental storage has a pending reads. + */ + @Test + public void testStartableTransition_DataLoaderStorageErrorWhenIncrementalStoragePending() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_STORAGE_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_READS_PENDING); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Data Loader hits limited storage while + * Incremental storage is at blocked status. + */ + @Test + public void testStartableTransition_DataLoaderStorageErrorWhenIncrementalStorageBlocked() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged( + IDataLoaderStatusListener.STREAM_STORAGE_ERROR); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_BLOCKED); + // Test that package is now unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + assertEquals(PackageManager.UNSTARTABLE_REASON_DATALOADER_STORAGE, + mUnstartableReason.get()); + } + + /** + * Test that the package becomes unstartable when Incremental Storage is unhealthy, and it + * becomes startable again when Incremental Storage is healthy again. + */ + @Test + public void testStartableTransition_IncrementalStorageUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_OK); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when Data Loader has data integrity issue, and it + * becomes startable again when Data Loader is healthy again. + */ + @Test + public void testStartableTransition_DataLoaderUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_HEALTHY); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that the package becomes unstartable when both Incremental Storage and Data Loader + * are unhealthy, and it becomes startable again when both Incremental Storage and Data Loader + * are healthy again. + */ + @Test + public void testStartableTransition_DataLoaderAndIncrementalStorageUnhealthyBackToHealthy() + throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_INTEGRITY_ERROR); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + + mIncrementalStates.onStreamStatusChanged(IDataLoaderStatusListener.STREAM_HEALTHY); + // Test that package is still unstartable + assertFalse(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.onStorageHealthStatusChanged(IStorageHealthListener.HEALTH_STATUS_OK); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that when loading progress is 1, the package becomes fully loaded, and the change of + * Incremental Storage health status does not affect the startable state. + */ + @Test + public void testStartableTransition_HealthStatusChangeWhenFullyLoaded() + throws InterruptedException { + mIncrementalStates.setProgress(1.0f); + // Test that package is now fully loaded + assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isLoading()); + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is still startable + assertFalse(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + } + + /** + * Test that when loading progress is 1, the package becomes fully loaded, and if the package + * was unstartable, it becomes startable. + */ + @Test + public void testLoadingTransition_FullyLoadedWhenUnstartable() throws InterruptedException { + mIncrementalStates.onStorageHealthStatusChanged( + IStorageHealthListener.HEALTH_STATUS_UNHEALTHY); + // Test that package is unstartable + assertTrue(mUnstartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + // Test that package is still loading + assertTrue(mIncrementalStates.isLoading()); + + mIncrementalStates.setProgress(0.5f); + // Test that package is still unstartable + assertFalse(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isStartable()); + mIncrementalStates.setProgress(1.0f); + // Test that package is now startable + assertTrue(mStartableCalled.block(WAIT_TIMEOUT_MILLIS)); + assertTrue(mIncrementalStates.isStartable()); + // Test that package is now fully loaded + assertTrue(mFullyLoadedCalled.block(WAIT_TIMEOUT_MILLIS)); + assertFalse(mIncrementalStates.isLoading()); + } +} diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index bc747832e253..6255630712ae 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -891,8 +891,10 @@ public class PackageManagerSettingsTests { assertNotSame(origPkgSetting.mimeGroups, testPkgSetting.mimeGroups); } assertThat(origPkgSetting.mimeGroups, is(testPkgSetting.mimeGroups)); - assertNotSame(origPkgSetting.mPermissionsState, testPkgSetting.mPermissionsState); - assertThat(origPkgSetting.mPermissionsState, is(testPkgSetting.mPermissionsState)); + assertNotSame(origPkgSetting.mLegacyPermissionsState, + testPkgSetting.mLegacyPermissionsState); + assertThat(origPkgSetting.mLegacyPermissionsState, + is(testPkgSetting.mLegacyPermissionsState)); assertThat(origPkgSetting.name, is(testPkgSetting.name)); // mOldCodePaths is _not_ copied // assertNotSame(origPkgSetting.mOldCodePaths, testPkgSetting.mOldCodePaths); diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java index 820eca4a49a8..bc7516f6514f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.view.Display.INVALID_DISPLAY; import static com.android.dx.mockito.inline.extended.ExtendedMockito.any; @@ -319,6 +320,29 @@ public class LaunchParamsControllerTests extends WindowTestsBase { } /** + * Ensures that {@link LaunchParamsModifier} doesn't alter non-root tasks' windowingMode. + */ + @Test + public void testLayoutNonRootTaskWindowingModeChange() { + final LaunchParams params = new LaunchParams(); + final int windowingMode = WINDOWING_MODE_FREEFORM; + params.mWindowingMode = windowingMode; + final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params); + final Task task = new TaskBuilder(mAtm.mStackSupervisor).setCreateParentTask(true).build(); + task.getRootTask().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY); + + mController.registerModifier(positioner); + + final int beforeWindowMode = task.getWindowingMode(); + assertNotEquals(windowingMode, beforeWindowMode); + + mController.layoutTask(task, null /* windowLayout */); + + final int afterWindowMode = task.getWindowingMode(); + assertEquals(afterWindowMode, beforeWindowMode); + } + + /** * Ensures that {@link LaunchParamsModifier} requests specifying bounds during * layout are honored if window is in freeform. */ |