Merge "StrictMode to catch implicit Direct Boot matching."
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 0b5e358..1c20bff 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -71,7 +71,7 @@
src/guardrail/StatsdStats.cpp \
src/socket/StatsSocketListener.cpp
-# TODO: Once statsd is using a blueprint file, migrate to the proper filegroups.
+# TODO(b/110563449): Once statsd is using a blueprint file, migrate to the proper filegroups.
statsd_common_src += \
../../../../system/extras/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl \
src/perfprofd/perfprofd_config.proto
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index 02c49b9..b1d6ab3 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -212,7 +212,7 @@
* the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are
* equal. Nothing can beat the performance of this matching algorithm.
*
- * TODO: ADD EXAMPLE HERE.
+ * TODO(b/110561213): ADD EXAMPLE HERE.
*/
struct Matcher {
Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){};
diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp
index 7103034..af8b3af 100644
--- a/cmds/statsd/src/HashableDimensionKey.cpp
+++ b/cmds/statsd/src/HashableDimensionKey.cpp
@@ -65,8 +65,6 @@
for (const auto& value : values) {
for (size_t i = 0; i < matcherFields.size(); ++i) {
const auto& matcher = matcherFields[i];
- // TODO: potential optimization here to break early because all fields are naturally
- // sorted.
if (value.mField.matches(matcher)) {
output->addValue(value);
output->mutableValue(num_matches)->mField.setTag(value.mField.getTag());
@@ -196,4 +194,4 @@
} // namespace statsd
} // namespace os
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ae44ee9..1119eb3 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -440,7 +440,6 @@
if (argCount == 2) {
// Automatically pick the UID
uid = IPCThreadState::self()->getCallingUid();
- // TODO: What if this isn't a binder call? Should we fail?
name.assign(args[1].c_str(), args[1].size());
good = true;
} else if (argCount == 3) {
@@ -493,7 +492,6 @@
if (argCount == 3) {
// Automatically pick the UID
uid = IPCThreadState::self()->getCallingUid();
- // TODO: What if this isn't a binder call? Should we fail?
name.assign(args[2].c_str(), args[2].size());
good = true;
} else if (argCount == 4) {
@@ -578,7 +576,6 @@
if (argCount == 2) {
// Automatically pick the UID
uid = IPCThreadState::self()->getCallingUid();
- // TODO: What if this isn't a binder call? Should we fail?
name.assign(args[1].c_str(), args[1].size());
good = true;
} else if (argCount == 3) {
@@ -604,7 +601,6 @@
vector<uint8_t> data;
mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
false /* include_current_bucket*/, ADB_DUMP, &data);
- // TODO: print the returned StatsLogReport to file instead of printing to logcat.
if (proto) {
for (size_t i = 0; i < data.size(); i ++) {
fprintf(out, "%c", data[i]);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 0a11f7c..ed90050 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -49,7 +49,6 @@
virtual ~StatsService();
/** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
- // TODO: Consider making this configurable. And choose a good number.
const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5;
virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
index 78f0c2b..bc36dad 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.cpp
@@ -60,7 +60,7 @@
ALOGW("Asked to add a 0-time alarm.");
return;
}
- // TODO: Ensure that refractory period is respected.
+ // TODO(b/110563466): Ensure that refractory period is respected.
VLOG("Adding alarm with time %u", alarm->timestampSec);
mPq.push(alarm);
if (mRegisteredAlarmTimeSec < 1 ||
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index f32efee..ee111cd 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -208,7 +208,8 @@
}
void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDimensionKey& key) {
- // TODO: Why receive timestamp? RefractoryPeriod should always be based on real time right now.
+ // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on
+ // real time right now.
if (isInRefractoryPeriod(timestampNs, key)) {
VLOG("Skipping anomaly declaration since within refractory period");
return;
@@ -216,7 +217,8 @@
if (mAlert.has_refractory_period_secs()) {
mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up
+ mAlert.refractory_period_secs();
- // TODO: If we had access to the bucket_size_millis, consider calling resetStorage()
+ // TODO(b/110563466): If we had access to the bucket_size_millis, consider
+ // calling resetStorage()
// if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();}
}
@@ -230,7 +232,7 @@
StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id());
- // TODO: This should also take in the const MetricDimensionKey& key?
+ // TODO(b/110564268): This should also take in the const MetricDimensionKey& key?
android::util::stats_write(android::util::ANOMALY_DETECTED, mConfigKey.GetUid(),
mConfigKey.GetId(), mAlert.id());
}
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
index 3741202..ae97d7a 100644
--- a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
@@ -54,7 +54,7 @@
ResourceHealthManagerPuller::ResourceHealthManagerPuller(int tagId) : StatsPuller(tagId) {
}
-// TODO: add other health atoms (eg. Temperature).
+// TODO(b/110565992): add other health atoms (eg. Temperature).
bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
if (!getHealthHal()) {
ALOGE("Health Hal not loaded");
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 764366f..038cb95 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -103,7 +103,6 @@
{android::util::CPU_TIME_PER_UID_FREQ, {6000, 10000}},
};
-// TODO: add stats for pulled atoms.
StatsdStats::StatsdStats() {
mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1);
mStartTimeSec = getWallClockSec();
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 74541d3..9fb2cd8 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -86,7 +86,6 @@
static StatsdStats& getInstance();
~StatsdStats(){};
- // TODO: set different limit if the device is low ram.
const static int kDimensionKeySizeSoftLimit = 500;
const static int kDimensionKeySizeHardLimit = 800;
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 4e4f146..04d34f3 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -273,7 +273,7 @@
}
int64_t LogEvent::GetLong(size_t key, status_t* err) const {
- // TODO: encapsulate the magical operations all in Field struct as a static function.
+ // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions
int field = getSimpleField(key);
for (const auto& value : mValues) {
if (value.mField.getField() == field) {
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 6aa68da..2f15d0f 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -82,7 +82,6 @@
if (err != NO_ERROR) {
return err;
}
- // TODO: Do we need to tweak thread priority?
err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (err != NO_ERROR) {
pthread_attr_destroy(&attr);
diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h
index 4f30a04..88ab4e6 100644
--- a/cmds/statsd/src/matchers/LogMatchingTracker.h
+++ b/cmds/statsd/src/matchers/LogMatchingTracker.h
@@ -86,8 +86,6 @@
// The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly
// return kNotMatched when we receive an event with an id not in the list. This is especially
// useful when we have a complex CombinationLogMatcherTracker.
- // TODO: Consider use an array instead of stl set. In reality, the number of the tag ids a
- // LogMatchingTracker cares is only a few.
std::set<int> mAtomIds;
};
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 43f53e0..a894782 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -68,7 +68,6 @@
const sp<ConditionWizard>& wizard,
const int64_t startTimeNs)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
- // TODO: evaluate initial conditions. and set mConditionMet.
if (metric.has_bucket()) {
mBucketSizeNs =
TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 139c083..520d5de 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -40,7 +40,6 @@
class CountMetricProducer : public MetricProducer {
public:
- // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
const int64_t startTimeNs);
@@ -80,7 +79,6 @@
void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
- // TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
// The current bucket (may be a partial bucket).
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index 62237bc..a19eb0b 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -76,9 +76,6 @@
mStopAllIndex(stopAllIndex),
mNested(nesting),
mContainANYPositionInInternalDimensions(false) {
- // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract
- // them in the base class, because the proto generated CountMetric, and DurationMetric are
- // not related. Maybe we should add a template in the future??
if (metric.has_bucket()) {
mBucketSizeNs =
TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
@@ -434,8 +431,6 @@
VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
mCondition = conditionMet;
flushIfNeededLocked(eventTime);
- // TODO: need to populate the condition change time from the event which triggers the condition
- // change, instead of using current time.
for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
for (auto& pair : whatIt.second) {
pair.second->onConditionChanged(conditionMet, eventTime);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 88e455a..c496b12 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -115,7 +115,6 @@
ConditionState mUnSlicedPartCondition;
// Save the past buckets and we can clear when the StatsLogReport is dumped.
- // TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets;
// The duration trackers in the current bucket.
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 62d1105..7f7aa37 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -33,7 +33,6 @@
class EventMetricProducer : public MetricProducer {
public:
- // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
EventMetricProducer(const ConfigKey& key, const EventMetric& eventMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
const int64_t startTimeNs);
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index d75bb10..a779410 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -101,7 +101,6 @@
translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers);
}
- // TODO: use UidMap if uid->pkg_name is required
if (metric.has_dimensions_in_what()) {
translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
@@ -299,7 +298,6 @@
protoOutput->end(protoToken);
mPastBuckets.clear();
- // TODO: Clear mDimensionKeyMap once the report is dumped.
}
void GaugeMetricProducer::pullLocked(const int64_t timestampNs) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 62ec27eb..89b1f41 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -122,7 +122,6 @@
const int mPullTagId;
// Save the past buckets and we can clear when the StatsLogReport is dumped.
- // TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
// The current partial bucket.
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 213f9ab..0e5ef4d 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -238,7 +238,6 @@
if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) {
// Check that app breadcrumb reported fields are valid.
- // TODO: Find a way to make these checks easier to maintain.
status_t err = NO_ERROR;
// Uid is 3rd from last field and must match the caller's uid,
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index ef8b6cc..f5e953a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -89,7 +89,6 @@
? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
: StatsdStats::kDimensionKeySizeHardLimit),
mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()) {
- // TODO: valuemetric for pushed events may need unlimited bucket length
int64_t bucketSizeMills = 0;
if (metric.has_bucket()) {
bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 75f3113..943d6dc 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -144,7 +144,6 @@
std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
// Save the past buckets and we can clear when the StatsLogReport is dumped.
- // TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets;
// Pairs of (elapsed start, elapsed end) denoting buckets that were skipped.
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 149b318..ccb1d43 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -44,7 +44,6 @@
int64_t lastStartTime;
// existing duration in current bucket.
int64_t lastDuration;
- // TODO: Optimize the way we track sliced condition in duration metrics.
// cache the HashableDimensionKeys we need to query the condition for this duration event.
ConditionKey conditionKeys;
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index b833dfc..956383a 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -326,7 +326,6 @@
int64_t OringDurationTracker::predictAnomalyTimestampNs(
const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const {
- // TODO: Unit-test this and see if it can be done more efficiently (e.g. use int32).
// The anomaly threshold.
const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold();
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index deb9893..e03edb3 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -103,7 +103,6 @@
}
allConditionTrackers[condition_it->second]->setSliced(true);
allConditionTrackers[it->second]->setSliced(true);
- // TODO: We need to verify the link is valid.
}
conditionIndex = condition_it->second;
@@ -169,7 +168,6 @@
bool isStateTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) {
// 1. must not have "stop". must have "dimension"
if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) {
- // TODO: need to check the start atom matcher too.
auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(
simplePredicate.dimensions().field());
// 2. must be based on a state atom.
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 514eec7..91f2030 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -146,7 +146,6 @@
void getListenerListCopyLocked(std::vector<wp<PackageInfoListener>>* output);
- // TODO: Use shared_mutex for improved read-locking if a library can be found in Android.
mutable mutex mMutex;
mutable mutex mIsolatedMutex;
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 1f81812..3ebc8a4 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -57,7 +57,7 @@
}
// When index ends before hitting 3, file name is corrupted. We
// intentionally put -1 at index 0 to indicate the error to caller.
- // TODO: consider removing files with unexpected name format.
+ // TODO(b/110563137): consider removing files with unexpected name format.
if (index < 3) {
result[0] = -1;
}
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp
index c253bc1..a9305ac 100644
--- a/cmds/statsd/tests/FieldValue_test.cpp
+++ b/cmds/statsd/tests/FieldValue_test.cpp
@@ -312,7 +312,8 @@
dim.addValue(FieldValue(field4, value4));
SubscriberReporter::getStatsDimensionsValue(dim);
- // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
+ // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't
+ // have any read api.
}
TEST(AtomMatcherTest, TestWriteDimensionToProto) {
@@ -483,4 +484,4 @@
} // namespace android
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
\ No newline at end of file
+#endif
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 4de9986..8fbb58a 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -39,8 +39,6 @@
#ifdef __ANDROID__
-// TODO: ADD MORE TEST CASES.
-
const ConfigKey kConfigKey(0, 12345);
const long timeBaseSec = 1000;
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index 11aaab0..cc8894b 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -99,7 +99,6 @@
// If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests,
// we should use the real API which will clear the data after dump data is called.
-// TODO: better refactor the code so that the tests are not so verbose.
TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
auto config = CreateStatsdConfig();
uint64_t bucketStartTimeNs = 10000000000;
diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
index 3a15466..d2fd95c 100644
--- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp
@@ -54,8 +54,8 @@
eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2);
- // TODO: get the report and check the content after the ProtoOutputStream change is done.
- // eventProducer.onDumpReport();
+ // TODO(b/110561136): get the report and check the content after the ProtoOutputStream change
+ // is done eventProducer.onDumpReport();
}
TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) {
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index c7e72f9..19c9f77 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -59,8 +59,6 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- // TODO: pending refactor of StatsPullerManager
- // For now we still need this so that it doesn't do real pulling.
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index d93b46f..5195f01 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -60,8 +60,6 @@
metric.mutable_value_field()->add_child()->set_field(2);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- // TODO: pending refactor of StatsPullerManager
- // For now we still need this so that it doesn't do real pulling.
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
diff --git a/core/java/android/animation/IntEvaluator.java b/core/java/android/animation/IntEvaluator.java
index 34fb0dc..1de2ae7 100644
--- a/core/java/android/animation/IntEvaluator.java
+++ b/core/java/android/animation/IntEvaluator.java
@@ -24,7 +24,7 @@
/**
* This function returns the result of linearly interpolating the start and end values, with
* <code>fraction</code> representing the proportion between the start and end values. The
- * calculation is a simple parametric calculation: <code>result = x0 + t * (v1 - v0)</code>,
+ * calculation is a simple parametric calculation: <code>result = x0 + t * (x1 - x0)</code>,
* where <code>x0</code> is <code>startValue</code>, <code>x1</code> is <code>endValue</code>,
* and <code>t</code> is <code>fraction</code>.
*
@@ -39,4 +39,4 @@
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index d65e051..3120421 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1120,6 +1120,9 @@
/** @hide */
public String[] splitClassLoaderNames;
+ /** @hide */
+ public boolean hiddenUntilInstalled;
+
/**
* Represents the default policy. The actual policy used will depend on other properties of
* the application, e.g. the target SDK version.
@@ -1460,6 +1463,7 @@
compileSdkVersion = orig.compileSdkVersion;
compileSdkVersionCodename = orig.compileSdkVersionCodename;
mHiddenApiPolicy = orig.mHiddenApiPolicy;
+ hiddenUntilInstalled = orig.hiddenUntilInstalled;
}
public String toString() {
@@ -1534,6 +1538,7 @@
dest.writeString(compileSdkVersionCodename);
dest.writeString(appComponentFactory);
dest.writeInt(mHiddenApiPolicy);
+ dest.writeInt(hiddenUntilInstalled ? 1 : 0);
}
public static final Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1605,6 +1610,7 @@
compileSdkVersionCodename = source.readString();
appComponentFactory = source.readString();
mHiddenApiPolicy = source.readInt();
+ hiddenUntilInstalled = source.readInt() != 0;
}
/**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c988fa9..bc5b32c 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -598,6 +598,9 @@
boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
+ void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden);
+ boolean setSystemAppInstallState(String packageName, boolean installed, int userId);
+
IPackageInstaller getPackageInstaller();
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index bac0673..721063a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -147,6 +147,7 @@
GET_DISABLED_COMPONENTS,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
+ MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PackageInfoFlags {}
@@ -164,6 +165,7 @@
MATCH_STATIC_SHARED_LIBRARIES,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
+ MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoFlags {}
@@ -531,6 +533,12 @@
public static final int MATCH_DEBUG_TRIAGED_MISSING = MATCH_DIRECT_BOOT_AUTO;
/**
+ * Internal flag used to indicate that a package is a hidden system app.
+ * @hide
+ */
+ public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 0x20000000;
+
+ /**
* Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when
* resolving an intent that matches the {@code CrossProfileIntentFilter},
* the current profile will be skipped. Only activities in the target user
@@ -4864,7 +4872,8 @@
* on the system for other users, also install it for the specified user.
* @hide
*/
- @RequiresPermission(anyOf = {
+ @RequiresPermission(anyOf = {
+ Manifest.permission.INSTALL_EXISTING_PACKAGES,
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.INTERACT_ACROSS_USERS_FULL})
public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 033d2ee..54d383a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -646,11 +646,19 @@
*/
private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state,
ApplicationInfo appInfo) {
+ // Returns false if the package is hidden system app until installed.
+ if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
+ && !state.installed
+ && appInfo != null && appInfo.hiddenUntilInstalled) {
+ return false;
+ }
+
// If available for the target user, or trying to match uninstalled packages and it's
// a system app.
return state.isAvailable(flags)
|| (appInfo != null && appInfo.isSystemApp()
- && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0);
+ && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
+ || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
}
public static boolean isAvailable(PackageUserState state) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f4b7ec8..e2a5c57 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3046,6 +3046,15 @@
<permission android:name="android.permission.INSTALL_PACKAGE_UPDATES"
android:protectionLevel="signature|privileged" />
+ <!-- Allows an application to install existing system packages. This is a limited
+ version of {@link android.Manifest.permission#INSTALL_PACKAGES}.
+ <p>Not for use by third-party applications.
+ TODO(b/80204953): remove this permission once we have a long-term solution.
+ @hide
+ -->
+ <permission android:name="com.android.permission.INSTALL_EXISTING_PACKAGES"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows an application to clear user data.
<p>Not for use by third-party applications
@hide
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 864f17d..c536e4d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13922,6 +13922,68 @@
return false;
}
+ @Override
+ public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
+ enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled");
+ synchronized (mPackages) {
+ final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+ if (pkgSetting == null || !pkgSetting.isSystem()) {
+ return;
+ }
+ PackageParser.Package pkg = pkgSetting.pkg;
+ if (pkg != null && pkg.applicationInfo != null) {
+ pkg.applicationInfo.hiddenUntilInstalled = hidden;
+ }
+ final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
+ if (disabledPs == null) {
+ return;
+ }
+ pkg = disabledPs.pkg;
+ if (pkg != null && pkg.applicationInfo != null) {
+ pkg.applicationInfo.hiddenUntilInstalled = hidden;
+ }
+ }
+ }
+
+ @Override
+ public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
+ enforceSystemOrPhoneCaller("setSystemAppInstallState");
+ synchronized (mPackages) {
+ final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+ // The target app should always be in system
+ if (pkgSetting == null || !pkgSetting.isSystem()) {
+ return false;
+ }
+ // Check if the install state is the same
+ if (pkgSetting.getInstalled(userId) == installed) {
+ return false;
+ }
+ }
+
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ if (installed) {
+ // install the app from uninstalled state
+ installExistingPackageAsUser(
+ packageName,
+ userId,
+ 0 /*installFlags*/,
+ PackageManager.INSTALL_REASON_DEVICE_SETUP);
+ return true;
+ }
+
+ // uninstall the app from installed state
+ deletePackageVersioned(
+ new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+ new LegacyPackageDeleteObserver(null).getBinder(),
+ userId,
+ PackageManager.DELETE_SYSTEM_APP);
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -13986,10 +14048,16 @@
@Override
public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
int installReason) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
- null);
- PackageSetting pkgSetting;
final int callingUid = Binder.getCallingUid();
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED
+ && mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Neither user " + callingUid + " nor current process has "
+ + android.Manifest.permission.INSTALL_PACKAGES + ".");
+ }
+ PackageSetting pkgSetting;
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"installExistingPackage for user " + userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d963afb..d17697b 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4121,7 +4121,8 @@
continue;
}
final boolean shouldInstall = ps.isSystem() &&
- !ArrayUtils.contains(disallowedPackages, ps.name);
+ !ArrayUtils.contains(disallowedPackages, ps.name) &&
+ !ps.pkg.applicationInfo.hiddenUntilInstalled;
// Only system apps are initially installed.
ps.setInstalled(shouldInstall, userHandle);
if (!shouldInstall) {
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index bcad554..a1bea4d 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -21,7 +21,6 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.res.Resources;
import android.os.RemoteException;
import android.provider.Settings;
import android.telephony.TelephonyManager;
@@ -145,6 +144,18 @@
telephonyManager.checkCarrierPrivilegesForPackageAnyPhone(packageName) ==
TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
+ // add hiddenUntilInstalled flag for carrier apps and associated apps
+ packageManager.setSystemAppHiddenUntilInstalled(packageName, true);
+ List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
+ if (associatedAppList != null) {
+ for (ApplicationInfo associatedApp : associatedAppList) {
+ packageManager.setSystemAppHiddenUntilInstalled(
+ associatedApp.packageName,
+ true
+ );
+ }
+ }
+
if (hasPrivileges) {
// Only update enabled state for the app on /system. Once it has been
// updated we shouldn't touch it.
@@ -152,9 +163,14 @@
&& (ai.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+ userId);
+ packageManager.setSystemAppInstallState(
+ packageName,
+ true /*installed*/,
+ userId);
packageManager.setApplicationEnabledSetting(
packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -164,15 +180,20 @@
}
// Also enable any associated apps for this carrier app.
- List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
if (associatedAppList != null) {
for (ApplicationInfo associatedApp : associatedAppList) {
if (associatedApp.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| associatedApp.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ || (associatedApp.flags
+ & ApplicationInfo.FLAG_INSTALLED) == 0) {
Slog.i(TAG, "Update associated state(" + associatedApp.packageName
+ "): ENABLED for user " + userId);
+ packageManager.setSystemAppInstallState(
+ associatedApp.packageName,
+ true /*installed*/,
+ userId);
packageManager.setApplicationEnabledSetting(
associatedApp.packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -190,36 +211,33 @@
// updated we shouldn't touch it.
if (!ai.isUpdatedSystemApp()
&& ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
Slog.i(TAG, "Update state(" + packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setApplicationEnabledSetting(
+ packageManager.setSystemAppInstallState(
packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
- 0,
- userId,
- callingPackage);
+ false /*installed*/,
+ userId);
}
// Also disable any associated apps for this carrier app if this is the first
// run. We avoid doing this a second time because it is brittle to rely on the
// distinction between "default" and "enabled".
if (!hasRunOnce) {
- List<ApplicationInfo> associatedAppList = associatedApps.get(packageName);
if (associatedAppList != null) {
for (ApplicationInfo associatedApp : associatedAppList) {
if (associatedApp.enabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+ == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && (associatedApp.flags
+ & ApplicationInfo.FLAG_INSTALLED) != 0) {
Slog.i(TAG,
"Update associated state(" + associatedApp.packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setApplicationEnabledSetting(
+ packageManager.setSystemAppInstallState(
associatedApp.packageName,
- PackageManager
- .COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
- 0,
- userId,
- callingPackage);
+ false /*installed*/,
+ userId);
}
}
}
@@ -357,7 +375,8 @@
String packageName) {
try {
ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+ | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, userId);
if (ai != null && ai.isSystemApp()) {
return ai;
}