summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt1
-rw-r--r--api/test-current.txt1
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.cpp42
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.h16
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp45
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp141
-rw-r--r--cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h21
-rw-r--r--cmds/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp380
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java4
-rw-r--r--core/java/android/content/pm/IncrementalStatesInfo.aidl4
-rw-r--r--core/java/android/os/storage/StorageManagerInternal.java7
-rw-r--r--core/java/android/view/Choreographer.java2
-rw-r--r--core/java/android/view/DisplayEventReceiver.java5
-rw-r--r--core/java/android/view/ViewRootImpl.java9
-rw-r--r--core/java/android/window/TaskOrganizer.java5
-rw-r--r--core/jni/android_os_Parcel.cpp93
-rw-r--r--core/res/res/values/config.xml2
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/xsd/vts/Android.bp4
-rw-r--r--core/xsd/vts/AndroidTest.xml30
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java10
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemChecker.java51
-rw-r--r--errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java52
-rw-r--r--errorprone/tests/java/com/google/errorprone/bugpatterns/android/RethrowFromSystemCheckerTest.java23
-rw-r--r--errorprone/tests/res/com/android/internal/telephony/ITelephony.java23
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java2
-rw-r--r--location/java/android/location/util/identity/CallerIdentity.java5
-rw-r--r--non-updatable-api/system-current.txt1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowManagerWrapper.java14
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java2
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java48
-rw-r--r--services/core/java/com/android/server/location/LocationProviderManager.java95
-rw-r--r--services/core/java/com/android/server/location/geofence/GeofenceManager.java2
-rw-r--r--services/core/java/com/android/server/location/gnss/GnssListenerMultiplexer.java2
-rw-r--r--services/core/java/com/android/server/location/util/LocationPowerSaveModeHelper.java11
-rw-r--r--services/core/java/com/android/server/location/util/ScreenInteractiveHelper.java9
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java9
-rw-r--r--services/core/java/com/android/server/pm/SettingBase.java21
-rw-r--r--services/core/java/com/android/server/pm/Settings.java62
-rw-r--r--services/core/java/com/android/server/pm/permission/LegacyPermissionDataProvider.java4
-rw-r--r--services/core/java/com/android/server/pm/permission/LegacyPermissionState.java (renamed from services/core/java/com/android/server/pm/permission/AppIdPermissionState.java)6
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java63
-rw-r--r--services/core/java/com/android/server/wm/LaunchParamsController.java6
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java11
-rw-r--r--services/core/xsd/vts/Android.mk22
-rw-r--r--services/core/xsd/vts/AndroidTest.xml30
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/location/LocationProviderManagerTest.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/IncrementalStatesTest.java316
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java24
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.
*/