Merge "Fix missing showWhenLocked activity attribute"
diff --git a/Android.bp b/Android.bp
index e669307..44f7edd 100644
--- a/Android.bp
+++ b/Android.bp
@@ -181,6 +181,7 @@
"core/java/android/hardware/input/IInputManager.aidl",
"core/java/android/hardware/input/IInputDevicesChangedListener.aidl",
"core/java/android/hardware/input/ITabletModeChangedListener.aidl",
+ "core/java/android/hardware/iris/IIrisService.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardware.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl",
@@ -692,6 +693,7 @@
],
static_libs: [
+ "apex_aidl_interface-java",
"framework-protos",
"mediaplayer2-protos",
"android.hidl.base-V1.0-java",
diff --git a/api/current.txt b/api/current.txt
index 3deb15a..f387c5d 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -42925,7 +42925,6 @@
method public int getLevel();
method public int getRsrp();
method public int getRsrq();
- method public int getRssi();
method public int getRssnr();
method public int getTimingAdvance();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 12e2560a..065f49e 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -276,22 +276,21 @@
*/
void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
- vector<uint8_t>* outData) {
+ ProtoOutputStream* proto) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
- ProtoOutputStream proto;
-
// Start of ConfigKey.
- uint64_t configKeyToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
- proto.end(configKeyToken);
+ uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
+ proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
+ proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
+ proto->end(configKeyToken);
// End of ConfigKey.
// Then, check stats-data directory to see there's any file containing
// ConfigMetricsReport from previous shutdowns to concatenate to reports.
- StorageManager::appendConfigMetricsReport(key, &proto);
+ StorageManager::appendConfigMetricsReport(key, proto);
auto it = mMetricsManagers.find(key);
if (it != mMetricsManagers.end()) {
@@ -301,14 +300,27 @@
// Start of ConfigMetricsReport (reports).
uint64_t reportsToken =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
+ proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
- dumpReportReason, &proto);
- proto.end(reportsToken);
+ erase_data, dumpReportReason, proto);
+ proto->end(reportsToken);
// End of ConfigMetricsReport (reports).
} else {
ALOGW("Config source %s does not exist", key.ToString().c_str());
}
+}
+
+/*
+ * onDumpReport dumps serialized ConfigMetricsReportList into outData.
+ */
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
+ const bool include_current_partial_bucket,
+ const bool erase_data,
+ const DumpReportReason dumpReportReason,
+ vector<uint8_t>* outData) {
+ ProtoOutputStream proto;
+ onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ dumpReportReason, &proto);
if (outData != nullptr) {
outData->clear();
@@ -332,6 +344,7 @@
void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key,
const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
ProtoOutputStream* proto) {
// We already checked whether key exists in mMetricsManagers in
@@ -348,7 +361,7 @@
// First, fill in ConfigMetricsReport using current data on memory, which
// starts from filling in StatsLogReport's.
it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket,
- &str_set, proto);
+ erase_data, &str_set, proto);
// Fill in UidMap if there is at least one metric to report.
// This skips the uid map if it's an empty config.
@@ -479,7 +492,7 @@
}
ProtoOutputStream proto;
onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
- dumpReportReason, &proto);
+ true /* erase_data */, dumpReportReason, &proto);
string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
(long)getWallClockSec(), key.GetUid(), (long long)key.GetId());
android::base::unique_fd fd(open(file_name.c_str(),
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 3e8b9b8..ecfd819 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -61,8 +61,11 @@
size_t GetMetricsSize(const ConfigKey& key) const;
void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
+ const bool include_current_partial_bucket, const bool erase_data,
const DumpReportReason dumpReportReason, vector<uint8_t>* outData);
+ void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
+ const bool include_current_partial_bucket, const bool erase_data,
+ const DumpReportReason dumpReportReason, ProtoOutputStream* proto);
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
void onAnomalyAlarmFired(
@@ -141,6 +144,7 @@
void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
util::ProtoOutputStream* proto);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ce28777..27685fc 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -46,6 +46,8 @@
using namespace android;
using android::base::StringPrintf;
+using android::util::FIELD_COUNT_REPEATED;
+using android::util::FIELD_TYPE_MESSAGE;
namespace android {
namespace os {
@@ -58,6 +60,9 @@
#define STATS_SERVICE_DIR "/data/misc/stats-service"
+// for StatsDataDumpProto
+const int FIELD_ID_REPORTS_LIST = 1;
+
static binder::Status ok() {
return binder::Status::ok();
}
@@ -224,31 +229,48 @@
}
/**
- * Write debugging data about statsd.
+ * Write data from statsd.
+ * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto]
+ * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto]
+ * Anything ending in --proto will be in proto format.
+ * Anything without --metadata as the first argument will be report information.
+ * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
+ * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
*/
status_t StatsService::dump(int fd, const Vector<String16>& args) {
if (!checkCallingPermission(String16(kPermissionDump))) {
return PERMISSION_DENIED;
}
-
- bool verbose = false;
- bool proto = false;
- if (args.size() > 0 && !args[0].compare(String16("-v"))) {
- verbose = true;
+ int lastArg = args.size() - 1;
+ bool asProto = false;
+ if (lastArg >= 0 && !args[lastArg].compare(String16("--proto"))) { // last argument
+ asProto = true;
+ lastArg--;
}
- if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) {
- proto = true;
+ if (args.size() > 0 && !args[0].compare(String16("--metadata"))) { // first argument
+ // Request is to dump statsd stats.
+ bool verbose = false;
+ if (lastArg >= 0 && !args[lastArg].compare(String16("-v"))) {
+ verbose = true;
+ lastArg--;
+ }
+ dumpStatsdStats(fd, verbose, asProto);
+ } else {
+ // Request is to dump statsd report data.
+ if (asProto) {
+ dumpIncidentSection(fd);
+ } else {
+ dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
+ }
}
- dump_impl(fd, verbose, proto);
-
return NO_ERROR;
}
/**
* Write debugging data about statsd in text or proto format.
*/
-void StatsService::dump_impl(int out, bool verbose, bool proto) {
+void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
if (proto) {
vector<uint8_t> data;
StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
@@ -262,6 +284,22 @@
}
/**
+ * Write stats report data in StatsDataDumpProto incident section format.
+ */
+void StatsService::dumpIncidentSection(int out) {
+ ProtoOutputStream proto;
+ for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
+ uint64_t reportsListToken =
+ proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
+ mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
+ true /* includeCurrentBucket */, false /* erase_data */,
+ ADB_DUMP, &proto);
+ proto.end(reportsListToken);
+ proto.flush(out);
+ }
+}
+
+/**
* Implementation of the adb shell cmd stats command.
*/
status_t StatsService::command(int in, int out, int err, Vector<String8>& args,
@@ -283,7 +321,7 @@
}
if (!args[0].compare(String8("dump-report"))) {
- return cmd_dump_report(out, err, args);
+ return cmd_dump_report(out, args);
}
if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
@@ -546,7 +584,7 @@
return UNKNOWN_ERROR;
}
-status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& args) {
+status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
if (mProcessor != nullptr) {
int argCount = args.size();
bool good = false;
@@ -589,14 +627,13 @@
if (good) {
vector<uint8_t> data;
mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
- includeCurrentBucket, ADB_DUMP, &data);
+ includeCurrentBucket, true /* erase_data */, ADB_DUMP, &data);
if (proto) {
for (size_t i = 0; i < data.size(); i ++) {
dprintf(out, "%c", data[i]);
}
} else {
- dprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
- dprintf(out, "See the StatsLogReport in logcat...\n");
+ dprintf(out, "Non-proto stats data dump not currently supported.\n");
}
return android::OK;
} else {
@@ -888,7 +925,7 @@
VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
ConfigKey configKey(ipc->getCallingUid(), key);
mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
- GET_DATA_CALLED, output);
+ true /* erase_data */, GET_DATA_CALLED, output);
return Status::ok();
}
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index cbf3429..4a5f05f 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -213,9 +213,14 @@
uint32_t serial);
/**
- * Text or proto output of dumpsys.
+ * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
*/
- void dump_impl(int outFd, bool verbose, bool proto);
+ void dumpIncidentSection(int outFd);
+
+ /**
+ * Text or proto output of statsdStats dumpsys.
+ */
+ void dumpStatsdStats(int outFd, bool verbose, bool proto);
/**
* Print usage information for the commands
@@ -240,7 +245,7 @@
/**
* Print the event log.
*/
- status_t cmd_dump_report(int outFd, int err, const Vector<String8>& args);
+ status_t cmd_dump_report(int outFd, const Vector<String8>& args);
/**
* Print the mapping of uids to package names.
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 6b8c12a..eddc86e 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -82,7 +82,9 @@
// Create the service
gStatsService = new StatsService(looper);
- if (defaultServiceManager()->addService(String16("stats"), gStatsService) != 0) {
+ if (defaultServiceManager()->addService(String16("stats"), gStatsService, false,
+ IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO)
+ != 0) {
ALOGE("Failed to add service as AIDL service");
return -1;
}
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index bd94800..5ca8814 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -143,6 +143,7 @@
void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (include_current_partial_bucket) {
@@ -230,7 +231,9 @@
protoOutput->end(protoToken);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ }
}
void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 39d4ae2..1ac44264 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -56,6 +56,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index dd3402d..35deffe 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -453,6 +453,7 @@
void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (include_current_partial_bucket) {
@@ -541,7 +542,9 @@
}
protoOutput->end(protoToken);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ }
}
void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 12addb8..1b830a3 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -63,6 +63,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index afd8ec2..a18e406 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -105,6 +105,7 @@
void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (mProto->size() <= 0) {
@@ -120,7 +121,9 @@
protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
- mProto->clear();
+ if (erase_data) {
+ mProto->clear();
+ }
}
void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 7f7aa37..96adfdd 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -47,6 +47,7 @@
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index f5a16e9..05103a9 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -182,6 +182,7 @@
void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("Gauge metric %lld report now...", (long long)mMetricId);
@@ -226,7 +227,6 @@
(long long)(NanoToMillis(pair.second)));
protoOutput->end(wrapperToken);
}
- mSkippedBuckets.clear();
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
@@ -304,7 +304,11 @@
}
protoOutput->end(protoToken);
- mPastBuckets.clear();
+
+ if (erase_data) {
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+ }
}
void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 99827bb..5866139 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -94,6 +94,7 @@
private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index b21fd50..127cbbd 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -133,10 +133,12 @@
// This method clears all the past buckets.
void onDumpReport(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) {
std::lock_guard<std::mutex> lock(mMutex);
- return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, str_set, protoOutput);
+ return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, erase_data,
+ str_set, protoOutput);
}
void clearPastBuckets(const int64_t dumpTimeNs) {
@@ -210,6 +212,7 @@
const int64_t eventTime) = 0;
virtual void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) = 0;
virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index f85ba1f..4244d5b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -197,6 +197,7 @@
void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
@@ -206,11 +207,11 @@
uint64_t token = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
if (mHashStringsInReport) {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, str_set,
- protoOutput);
+ producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ str_set, protoOutput);
} else {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, nullptr,
- protoOutput);
+ producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ nullptr, protoOutput);
}
protoOutput->end(token);
} else {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 649222ff..a4672b6 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -107,6 +107,7 @@
virtual void onDumpReport(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 192a54b..6367479 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -170,6 +170,7 @@
void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("metric %lld dump report now...", (long long)mMetricId);
@@ -211,7 +212,6 @@
(long long)(NanoToMillis(pair.second)));
protoOutput->end(wrapperToken);
}
- mSkippedBuckets.clear();
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
@@ -271,7 +271,10 @@
protoOutput->end(protoToken);
VLOG("metric %lld dump report now...", (long long)mMetricId);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+ }
}
void ValueMetricProducer::onConditionChangedLocked(const bool condition,
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index b2f0b6f..8db2d95 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -94,6 +94,7 @@
private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index b6f635c..8864252 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -168,7 +168,7 @@
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
@@ -197,7 +197,7 @@
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
@@ -227,7 +227,7 @@
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index a8fcc81..5c47af7 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -144,8 +144,8 @@
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -290,8 +290,8 @@
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
index 75bd40f..a8914da 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
@@ -212,7 +212,7 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -548,7 +548,7 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -798,7 +798,7 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
index c5a8a2e..621b6ed 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
@@ -130,8 +130,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -346,8 +346,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -530,8 +530,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -732,8 +732,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
index 5bcc9ee..9f8acaf 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
@@ -143,7 +143,7 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -438,7 +438,7 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -658,8 +658,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index d7b9c11..2d090e0 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -123,8 +123,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -246,8 +246,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -350,8 +350,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 5c1ef01..71afedf 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -149,8 +149,8 @@
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index 0f13a4a..29e86f3 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -167,8 +167,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index cc8894b..9349c85 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -199,8 +199,8 @@
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -318,8 +318,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 67acd61..3cb553f 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -46,7 +46,7 @@
IPCThreadState* ipc = IPCThreadState::self();
ConfigKey configKey(ipc->getCallingUid(), kConfigKey);
processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
- ADB_DUMP, &output);
+ true /* erase_data */, ADB_DUMP, &output);
ConfigMetricsReportList reports;
reports.ParseFromArray(output.data(), output.size());
EXPECT_EQ(1, reports.reports_size());
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index f2e8f58..fed5a3f 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -117,8 +117,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -224,8 +224,8 @@
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index b9d0c62..6d1317c 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -127,8 +127,8 @@
FeedEvents(config, processor);
vector<uint8_t> buffer;
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -164,8 +164,8 @@
FeedEvents(config, processor);
vector<uint8_t> buffer;
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -215,8 +215,8 @@
processor->OnLogEvent(event.get());
}
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -248,8 +248,8 @@
FeedEvents(config, processor);
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
@@ -277,8 +277,8 @@
FeedEvents(config, processor);
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -323,8 +323,8 @@
processor->OnLogEvent(event.get());
}
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 508ea3b..f267169 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -66,6 +66,8 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.input.InputManager;
+import android.hardware.iris.IrisManager;
+import android.hardware.iris.IIrisService;
import android.hardware.location.ContextHubManager;
import android.hardware.radio.RadioManager;
import android.hardware.usb.IUsbManager;
@@ -836,6 +838,18 @@
}
});
+ registerService(Context.IRIS_SERVICE, IrisManager.class,
+ new CachedServiceFetcher<IrisManager>() {
+ @Override
+ public IrisManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ final IBinder binder =
+ ServiceManager.getServiceOrThrow(Context.IRIS_SERVICE);
+ IIrisService service = IIrisService.Stub.asInterface(binder);
+ return new IrisManager(ctx.getOuterContext(), service);
+ }
+ });
+
registerService(Context.BIOMETRIC_SERVICE, BiometricManager.class,
new CachedServiceFetcher<BiometricManager>() {
@Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e378800..6a7829b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3706,6 +3706,17 @@
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.hardware.iris.IrisManager} for handling management
+ * of iris authentication.
+ *
+ * @hide
+ * @see #getSystemService
+ * @see android.hardware.iris.IrisManager
+ */
+ public static final String IRIS_SERVICE = "iris";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.hardware.biometrics.BiometricManager} for handling management
* of face authentication.
*
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1f700f7..67b86c0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -855,6 +855,14 @@
*/
public static final int INSTALL_VIRTUAL_PRELOAD = 0x00010000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that this package
+ * is an APEX package
+ *
+ * @hide
+ */
+ public static final int INSTALL_APEX = 0x00020000;
+
/** @hide */
@IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
DONT_KILL_APP
diff --git a/core/java/android/hardware/iris/IIrisService.aidl b/core/java/android/hardware/iris/IIrisService.aidl
new file mode 100644
index 0000000..8cf3c13
--- /dev/null
+++ b/core/java/android/hardware/iris/IIrisService.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.iris;
+
+/**
+ * Communication channel from client to the iris service. These methods are all require the
+ * MANAGE_BIOMETRIC signature permission.
+ * @hide
+ */
+interface IIrisService {
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/iris/IrisManager.java b/core/java/android/hardware/iris/IrisManager.java
new file mode 100644
index 0000000..281ac47
--- /dev/null
+++ b/core/java/android/hardware/iris/IrisManager.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.hardware.iris;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * A class that coordinates access to the iris authentication hardware.
+ * @hide
+ */
+@SystemService(Context.IRIS_SERVICE)
+public class IrisManager {
+
+ /**
+ * @hide
+ */
+ public IrisManager(Context context, IIrisService service) {
+ }
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index b0b77f3..9acefa5 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -808,7 +808,7 @@
*
* @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
* was not associated with a client
- * @throws IllegalStateException if there were too many registered clients at the service
+ * @throws IllegalStateException if the client is already registered to a valid callback
* @throws NullPointerException if pendingIntent, hubInfo, callback, or executor is null
*
* @hide
@@ -818,8 +818,24 @@
@NonNull PendingIntent pendingIntent, @NonNull ContextHubInfo hubInfo,
@NonNull ContextHubClientCallback callback,
@NonNull @CallbackExecutor Executor executor) {
- // TODO: Implement this
- throw new UnsupportedOperationException("Not implemented yet");
+ Preconditions.checkNotNull(pendingIntent, "PendingIntent cannot be null");
+ Preconditions.checkNotNull(callback, "Callback cannot be null");
+ Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");
+ Preconditions.checkNotNull(executor, "Executor cannot be null");
+
+ ContextHubClient client = new ContextHubClient(hubInfo);
+ IContextHubClientCallback clientInterface = createClientCallback(
+ client, callback, executor);
+
+ IContextHubClient clientProxy;
+ try {
+ clientProxy = mService.bindClient(pendingIntent, clientInterface, hubInfo.getId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ client.setClientProxy(clientProxy);
+ return client;
}
/**
@@ -833,7 +849,7 @@
*
* @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
* was not associated with a client
- * @throws IllegalStateException if there were too many registered clients at the service
+ * @throws IllegalStateException if the client is already registered to a valid callback
* @throws NullPointerException if pendingIntent, hubInfo, or callback is null
*
* @hide
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 233e857..9b0acdf 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -17,6 +17,7 @@
package android.hardware.location;
// Declare any non-default types here with import statements
+import android.app.PendingIntent;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubMessage;
import android.hardware.location.NanoApp;
@@ -60,6 +61,11 @@
// Creates a client to send and receive messages
IContextHubClient createClient(in IContextHubClientCallback client, int contextHubId);
+ // Binds an existing client to a new callback interface, provided a previously registered
+ // PendingIntent
+ IContextHubClient bindClient(
+ in PendingIntent pendingIntent, in IContextHubClientCallback client, int contextHubId);
+
// Returns a list of ContextHub objects of available hubs
List<ContextHubInfo> getContextHubs();
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 2d67d79..769dd1b 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -36,6 +36,7 @@
public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String EMERGENCY_DIAL_SHORTCUTS = "settings_emergency_dial_shortcuts";
+ public static final String SAFETY_HUB = "settings_safety_hub";
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -51,6 +52,7 @@
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put(EMERGENCY_DIAL_SHORTCUTS, "true");
DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
+ DEFAULT_FLAGS.put(SAFETY_HUB, "false");
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
}
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index e7ac566..19d8a83 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -1396,6 +1396,11 @@
return as;
}
+ // See b/118826162 -- to avoid logspaming, we rate limit the WTF.
+ private static final long INVERSE_PROC_STATE_WTF_MIN_INTERVAL_MS = 10_000L;
+ private long mNextInverseProcStateWtfUptime;
+ private int mSkippedInverseProcStateWtfCount;
+
public void updateTrackingAssociationsLocked(int curSeq, long now) {
final int NUM = mTrackingAssociations.size();
for (int i = NUM - 1; i >= 0; i--) {
@@ -1417,12 +1422,24 @@
} else {
act.stopActive(now);
if (act.mProcState < procState) {
- Slog.w(TAG, "Tracking association " + act + " whose proc state "
- + act.mProcState + " is better than process " + proc
- + " proc state " + procState);
+ final long nowUptime = SystemClock.uptimeMillis();
+ if (mNextInverseProcStateWtfUptime > nowUptime) {
+ mSkippedInverseProcStateWtfCount++;
+ } else {
+ // TODO We still see it during boot related to GMS-core.
+ // b/118826162
+ Slog.wtf(TAG, "Tracking association " + act + " whose proc state "
+ + act.mProcState + " is better than process " + proc
+ + " proc state " + procState
+ + " (" + mSkippedInverseProcStateWtfCount + " skipped)");
+ mSkippedInverseProcStateWtfCount = 0;
+ mNextInverseProcStateWtfUptime =
+ nowUptime + INVERSE_PROC_STATE_WTF_MIN_INTERVAL_MS;
+ }
}
}
} else {
+ // Don't need rate limiting on it.
Slog.wtf(TAG, "Tracking association without process: " + act
+ " in " + act.getAssociationState());
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index b799728..25a5a07 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -69,7 +69,7 @@
private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h)
private static final boolean PROFILE_DRAWING = false;
- private static final float LINE_FADE_ALPHA_MULTIPLIER = 3.5f;
+ private static final float LINE_FADE_ALPHA_MULTIPLIER = 1.5f;
private final CellState[][] mCellStates;
private final int mDotSize;
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 8f28970..0b9e347 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -26,6 +26,7 @@
import "frameworks/base/core/proto/android/os/pagetypeinfo.proto";
import "frameworks/base/core/proto/android/os/procrank.proto";
import "frameworks/base/core/proto/android/os/ps.proto";
+import "frameworks/base/core/proto/android/os/statsdata.proto";
import "frameworks/base/core/proto/android/os/system_properties.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
@@ -301,6 +302,12 @@
(section).userdebug_and_eng_only = true
];
+ optional android.os.StatsDataDumpProto stats_data = 3023 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "stats --proto",
+ (section).userdebug_and_eng_only = true
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/core/proto/android/os/statsdata.proto b/core/proto/android/os/statsdata.proto
new file mode 100644
index 0000000..25d76b8
--- /dev/null
+++ b/core/proto/android/os/statsdata.proto
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package android.os;
+
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+// Dump of statsd report data (dumpsys stats --proto).
+message StatsDataDumpProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // The following is an android.os.statsd.ConfigMetricsReportList, which is defined
+ // in frameworks/base/cmds/statsd/src/stats_log.proto. It should not be imported (even weakly)
+ // in AOSP because it would drag with it atoms.proto, which is enormous and awkward.
+ repeated bytes config_metrics_report_list = 1;
+
+}
\ No newline at end of file
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 7b3d940..7163769 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -187,7 +187,7 @@
<shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288" />
<!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
- <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223" />
+ <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" />
<!-- Nigeria -->
<shortcode country="ng" pattern="\\d{1,5}" free="2441" />
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index 33c5551..a8ce196 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -164,7 +164,7 @@
### [com.android.systemui.biometrics.BiometricDialogImpl](/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java)
-Fingerprint UI.
+Biometric UI.
---
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 0462347..9baeaaa 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -64,6 +64,7 @@
<item name="android:paddingBottom">@dimen/bottom_text_spacing_digital</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
<item name="android:fontFeatureSettings">@*android:string/config_headlineFontFeatureSettings</item>
+ <item name="android:ellipsize">none</item>
</style>
<style name="BouncerSecurityContainer">
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d631fa8..52b0275 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17355,8 +17355,6 @@
}
}
- mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
-
incrementProcStateSeqAndNotifyAppsLocked();
mNumServiceProcs = mNewNumServiceProcs;
@@ -17618,6 +17616,9 @@
mHandler.post(new ProcStatsRunnable(ActivityManagerService.this, mProcessStats));
}
+ // Run this after making sure all procstates are updated.
+ mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+
if (DEBUG_OOM_ADJ) {
final long duration = SystemClock.uptimeMillis() - now;
if (false) {
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 5d4263b..bc3cc3b 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -70,7 +70,7 @@
/**
* A service to manage multiple clients that want to access the face HAL API.
* The service is responsible for maintaining a list of clients and dispatching all
- * face -related events.
+ * face-related events.
*
* @hide
*/
diff --git a/services/core/java/com/android/server/biometrics/iris/IrisService.java b/services/core/java/com/android/server/biometrics/iris/IrisService.java
new file mode 100644
index 0000000..37cdc2a
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/iris/IrisService.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.biometrics.iris;
+
+import android.content.Context;
+
+import com.android.server.biometrics.BiometricServiceBase;
+import com.android.server.biometrics.BiometricUtils;
+import com.android.server.biometrics.Metrics;
+
+/**
+ * A service to manage multiple clients that want to access the Iris HAL API.
+ * The service is responsible for maintaining a list of clients and dispatching all
+ * iris-related events.
+ *
+ * TODO: The vendor is expected to fill in the service. See
+ * {@link com.android.server.biometrics.fingerprint.FingerprintService}
+ *
+ * @hide
+ */
+public class IrisService extends BiometricServiceBase {
+
+ private static final String TAG = "IrisService";
+
+ /**
+ * Initializes the system service.
+ * <p>
+ * Subclasses must define a single argument constructor that accepts the context
+ * and passes it to super.
+ * </p>
+ *
+ * @param context The system server context.
+ */
+ public IrisService(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ protected String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected BiometricUtils getBiometricUtils() {
+ return null;
+ }
+
+ @Override
+ protected int getFailedAttemptsLockoutTimed() {
+ return 0;
+ }
+
+ @Override
+ protected int getFailedAttemptsLockoutPermanent() {
+ return 0;
+ }
+
+ @Override
+ protected Metrics getMetrics() {
+ return null;
+ }
+
+ @Override
+ protected boolean hasReachedEnrollmentLimit(int userId) {
+ return false;
+ }
+
+ @Override
+ protected void updateActiveGroup(int userId, String clientPackage) {
+
+ }
+
+ @Override
+ protected String getLockoutResetIntent() {
+ return null;
+ }
+
+ @Override
+ protected String getLockoutBroadcastPermission() {
+ return null;
+ }
+
+ @Override
+ protected long getHalDeviceId() {
+ return 0;
+ }
+
+ @Override
+ protected void handleUserSwitching(int userId) {
+
+ }
+
+ @Override
+ protected boolean hasEnrolledBiometrics(int userId) {
+ return false;
+ }
+
+ @Override
+ protected String getManageBiometricPermission() {
+ return null;
+ }
+
+ @Override
+ protected void checkUseBiometricPermission() {
+
+ }
+
+ @Override
+ protected boolean checkAppOps(int uid, String opPackageName) {
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index 60f70c7..6423470 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -159,25 +159,12 @@
/* package */ ContextHubClientBroker(
Context context, IContexthub contextHubProxy, ContextHubClientManager clientManager,
- ContextHubInfo contextHubInfo, short hostEndPointId,
- IContextHubClientCallback callback) {
+ ContextHubInfo contextHubInfo, short hostEndPointId) {
mContext = context;
mContextHubProxy = contextHubProxy;
mClientManager = clientManager;
mAttachedContextHubInfo = contextHubInfo;
mHostEndPointId = hostEndPointId;
- mCallbackInterface = callback;
- }
-
- /**
- * Attaches a death recipient for this client
- *
- * @throws RemoteException if the client has already died
- */
- /* package */ synchronized void attachDeathRecipient() throws RemoteException {
- if (mCallbackInterface != null) {
- mCallbackInterface.asBinder().linkToDeath(this, 0 /* flags */);
- }
}
/**
@@ -245,9 +232,15 @@
public boolean unregisterIntent(PendingIntent pendingIntent) {
ContextHubServiceUtil.checkPermissions(mContext);
+ boolean success = false;
synchronized (this) {
- return mPendingIntentRequest.unregister(pendingIntent);
+ success = mPendingIntentRequest.unregister(pendingIntent);
+ if (mCallbackInterface == null) {
+ close();
+ }
}
+
+ return success;
}
/**
@@ -276,6 +269,37 @@
}
/**
+ * Sets the callback interface for this client, only if the callback is currently unregistered.
+ *
+ * Also attaches a death recipient to a ContextHubClientBroker object. If unsuccessful, the
+ * connection is closed.
+ *
+ * @param callback the callback interface
+ * @return true if the callback was successfully set, false otherwise
+ *
+ * @throws IllegalStateException if the client has already been registered to a callback
+ */
+ /* package */
+ synchronized boolean setCallback(IContextHubClientCallback callback) {
+ boolean success = false;
+ if (mCallbackInterface != null) {
+ throw new IllegalStateException("Client is already registered with a callback");
+ } else {
+ mCallbackInterface = callback;
+ try {
+ mCallbackInterface.asBinder().linkToDeath(this, 0 /* flags */);
+ success = true;
+ } catch (RemoteException e) {
+ // The client process has died, so we close the connection.
+ Log.e(TAG, "Failed to attach death recipient to client");
+ close();
+ }
+ }
+
+ return success;
+ }
+
+ /**
* @return the ID of the context hub this client is attached to
*/
/* package */ int getAttachedContextHubId() {
@@ -347,6 +371,18 @@
}
/**
+ * @param intent the PendingIntent to compare to
+ * @return true if the given PendingIntent is currently registered, false otherwise
+ */
+ /* package */ boolean hasPendingIntent(PendingIntent intent) {
+ PendingIntent pendingIntent = null;
+ synchronized (this) {
+ pendingIntent = mPendingIntentRequest.getPendingIntent();
+ }
+ return (pendingIntent != null) && pendingIntent.equals(intent);
+ }
+
+ /**
* Helper function to invoke a specified client callback, if the connection is open.
*
* @param consumer the consumer specifying the callback to invoke
@@ -407,6 +443,9 @@
Log.w(TAG, "PendingIntent has been canceled, unregistering from client"
+ " (host endpoint ID " + mHostEndPointId + ")");
mPendingIntentRequest.clear();
+ if (mCallbackInterface == null) {
+ close();
+ }
}
}
}
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index eda8c6f..72879dd 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.app.PendingIntent;
import android.content.Context;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.IContexthub;
@@ -88,15 +89,9 @@
*/
/* package */ IContextHubClient registerClient(
IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
- ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubInfo);
-
- try {
- broker.attachDeathRecipient();
- } catch (RemoteException e) {
- // The client process has died, so we close the connection and return null.
- Log.e(TAG, "Failed to attach death recipient to client");
- broker.close();
- return null;
+ ContextHubClientBroker broker = createNewClientBroker(contextHubInfo);
+ if (!broker.setCallback(clientCallback)) {
+ return null; // Client process has died, so we return null
}
Log.d(TAG, "Registered client with host endpoint ID " + broker.getHostEndPointId());
@@ -104,6 +99,36 @@
}
/**
+ * Binds a existing and registered client with a new callback interface, provided a previously
+ * registered PendingIntent.
+ *
+ * @param pendingIntent a previously registered PendingIntent for a registered client
+ * @param clientCallback the callback interface of the client to bind to
+ * @param contextHubId the ID of the hub this client is attached to
+ *
+ * @return the client interface
+ *
+ * @throws IllegalArgumentException if no matching client is found
+ * @throws IllegalStateException if the client has already been registered to a callback
+ */
+ /* package */ IContextHubClient bindClient(
+ PendingIntent pendingIntent, IContextHubClientCallback clientCallback,
+ int contextHubId) {
+ ContextHubClientBroker broker = getClientBroker(pendingIntent, contextHubId);
+ if (broker == null) {
+ throw new IllegalArgumentException("Could not find client of Context Hub (ID = "
+ + contextHubId + ") with PendingIntent");
+ }
+
+ if (!broker.setCallback(clientCallback)) {
+ return null; // Client process has died, so we return null
+ }
+
+ Log.d(TAG, "Re-registered client with host endpoint ID " + broker.getHostEndPointId());
+ return IContextHubClient.Stub.asInterface(broker);
+ }
+
+ /**
* Handles a message sent from a nanoapp.
*
* @param contextHubId the ID of the hub where the nanoapp sent the message from
@@ -182,7 +207,6 @@
* Creates a new ContextHubClientBroker object for a client and registers it with the client
* manager.
*
- * @param clientCallback the callback interface of the client to register
* @param contextHubInfo the object describing the hub this client is attached to
*
* @return the ContextHubClientBroker object
@@ -190,7 +214,7 @@
* @throws IllegalStateException if max number of clients have already registered
*/
private synchronized ContextHubClientBroker createNewClientBroker(
- IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
+ ContextHubInfo contextHubInfo) {
if (mHostEndPointIdToClientMap.size() == MAX_CLIENT_ID + 1) {
throw new IllegalStateException("Could not register client - max limit exceeded");
}
@@ -200,8 +224,7 @@
for (int i = 0; i <= MAX_CLIENT_ID; i++) {
if (!mHostEndPointIdToClientMap.containsKey((short) id)) {
broker = new ContextHubClientBroker(
- mContext, mContextHubProxy, this, contextHubInfo, (short) id,
- clientCallback);
+ mContext, mContextHubProxy, this, contextHubInfo, (short) id);
mHostEndPointIdToClientMap.put((short) id, broker);
mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
break;
@@ -236,4 +259,22 @@
}
}
}
+
+ /**
+ * Retrieves a ContextHubClientBroker object with a matching PendingIntent and Context Hub ID.
+ *
+ * @param pendingIntent the PendingIntent to match
+ * @param contextHubId the ID of the Context Hub the client is attached to
+ * @return the matching ContextHubClientBroker, null if not found
+ */
+ private ContextHubClientBroker getClientBroker(PendingIntent pendingIntent, int contextHubId) {
+ for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) {
+ if (broker.hasPendingIntent(pendingIntent)
+ && broker.getAttachedContextHubId() == contextHubId) {
+ return broker;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index e3c2863..215e67c 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.app.PendingIntent;
import android.content.Context;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.ContextHub;
@@ -631,6 +632,37 @@
}
/**
+ * Recreates and binds a IContextHubClientCallback interface to an existing and registered
+ * client at the service for the specified Context Hub, provided a previously registered
+ * PendingIntent.
+ *
+ * @param pendingIntent the PendingIntent previously registered for the client
+ * @param clientCallback the client interface to register with the service
+ * @param contextHubId the ID of the hub this client is attached to
+ * @return the generated client interface, null if registration was unsuccessful
+ *
+ * @throws IllegalArgumentException if contextHubId is not a valid ID
+ * @throws NullPointerException if clientCallback or pendingIntent is null
+ */
+ @Override
+ public IContextHubClient bindClient(
+ PendingIntent pendingIntent, IContextHubClientCallback clientCallback,
+ int contextHubId) throws RemoteException {
+ checkPermissions();
+ if (!isValidContextHubId(contextHubId)) {
+ throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
+ }
+ if (pendingIntent == null) {
+ throw new NullPointerException("Cannot create client with null pending intent");
+ }
+ if (clientCallback == null) {
+ throw new NullPointerException("Cannot create client with null callback");
+ }
+
+ return mClientManager.bindClient(pendingIntent, clientCallback, contextHubId);
+ }
+
+ /**
* Loads a nanoapp binary at the specified Context hub.
*
* @param contextHubId the ID of the hub to load the binary
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0b32d1a..6ccd040 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -58,7 +58,6 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SELinux;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -646,8 +645,8 @@
}
try {
- Os.mkdir(stageDir.getAbsolutePath(), 0755);
- Os.chmod(stageDir.getAbsolutePath(), 0755);
+ Os.mkdir(stageDir.getAbsolutePath(), 0775);
+ Os.chmod(stageDir.getAbsolutePath(), 0775);
} catch (ErrnoException e) {
// This purposefully throws if directory already exists
throw new IOException("Failed to prepare session dir: " + stageDir, e);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 51225a7..6e45013 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -43,6 +43,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.apex.IApexService;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
@@ -75,6 +76,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -838,12 +840,15 @@
resolveStageDirLocked();
mSealed = true;
-
- // Verify that stage looks sane with respect to existing application.
- // This currently only ensures packageName, versionCode, and certificate
- // consistency.
try {
- validateInstallLocked(pkgInfo);
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ validateApexInstallLocked(pkgInfo);
+ } else {
+ // Verify that stage looks sane with respect to existing application.
+ // This currently only ensures packageName, versionCode, and certificate
+ // consistency.
+ validateApkInstallLocked(pkgInfo);
+ }
} catch (PackageManagerException e) {
throw e;
} catch (Throwable e) {
@@ -926,6 +931,31 @@
Preconditions.checkNotNull(mSigningDetails);
Preconditions.checkNotNull(mResolvedBaseFile);
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ commitApexLocked();
+ } else {
+ commitApkLocked();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void commitApexLocked() throws PackageManagerException {
+ try {
+ IApexService apex = IApexService.Stub.asInterface(
+ ServiceManager.getService("apexservice"));
+ apex.installPackage(mResolvedBaseFile.toString());
+ } catch (Throwable e) {
+ // Convert all exceptions into package manager exceptions as only those are handled
+ // in the code above
+ throw new PackageManagerException(e);
+ } finally {
+ destroyInternal();
+ dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "APEX installed", null);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void commitApkLocked() throws PackageManagerException {
if (needToAskForPermissionsLocked()) {
// User needs to confirm installation; give installer an intent they can use to involve
// user.
@@ -1047,6 +1077,57 @@
(params.installFlags & PackageManager.DONT_KILL_APP) != 0;
}
+ @GuardedBy("mLock")
+ private void validateApexInstallLocked(@Nullable PackageInfo pkgInfo)
+ throws PackageManagerException {
+ mResolvedStagedFiles.clear();
+ mResolvedInheritedFiles.clear();
+
+ try {
+ resolveStageDirLocked();
+ } catch (IOException e) {
+ throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+ "Failed to resolve stage location", e);
+ }
+
+ final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+ if (ArrayUtils.isEmpty(addedFiles)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
+ }
+
+ if (addedFiles.length > 1) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Only one APEX file at a time might be installed");
+ }
+ File addedFile = addedFiles[0];
+ final ApkLite apk;
+ try {
+ apk = PackageParser.parseApkLite(
+ addedFile, PackageParser.PARSE_COLLECT_CERTIFICATES);
+ } catch (PackageParserException e) {
+ throw PackageManagerException.from(e);
+ }
+
+ mPackageName = apk.packageName;
+ mVersionCode = apk.getLongVersionCode();
+ mSigningDetails = apk.signingDetails;
+ mResolvedBaseFile = addedFile;
+
+ assertApkConsistentLocked(String.valueOf(addedFile), apk);
+
+ if (mSigningDetails == PackageParser.SigningDetails.UNKNOWN) {
+ try {
+ // STOPSHIP: For APEX we should also implement proper APK Signature verification.
+ mSigningDetails = ApkSignatureVerifier.plsCertsNoVerifyOnlyCerts(
+ pkgInfo.applicationInfo.sourceDir,
+ PackageParser.SigningDetails.SignatureSchemeVersion.JAR);
+ } catch (PackageParserException e) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Couldn't obtain signatures from base APK");
+ }
+ }
+ }
+
/**
* Validate install by confirming that all application packages are have
* consistent package name, version code, and signing certificates.
@@ -1060,7 +1141,7 @@
* {@link PackageManagerService}.
*/
@GuardedBy("mLock")
- private void validateInstallLocked(@Nullable PackageInfo pkgInfo)
+ private void validateApkInstallLocked(@Nullable PackageInfo pkgInfo)
throws PackageManagerException {
ApkLite baseApk = null;
mPackageName = null;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index e25cca4..38bd172 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -920,7 +920,10 @@
pw.println("Error: must either specify a package size or an APK file");
return 1;
}
- if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
+ final boolean isApex =
+ (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+ String splitName = "base." + (isApex ? "apex" : "apk");
+ if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
return 1;
}
@@ -2262,6 +2265,9 @@
case "--force-sdk":
sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
break;
+ case "--apex":
+ sessionParams.installFlags |= PackageManager.INSTALL_APEX;
+ break;
default:
throw new IllegalArgumentException("Unknown option " + opt);
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 392d4d8..753c283 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -30,6 +30,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings.Global;
+import android.util.Log;
import android.util.Slog;
import android.util.jar.StrictJarFile;
@@ -74,7 +75,7 @@
private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST =
"pm.dexopt.priv-apps-oob-list";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
@@ -192,6 +193,16 @@
String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
classLoaderNames, classPaths);
+ // A null classLoaderContexts means that there are unsupported class loaders in the
+ // chain.
+ if (classLoaderContexts == null) {
+ if (DEBUG) {
+ Slog.i(TAG, loadingAppInfo.packageName +
+ " uses unsupported class loader in " + classLoaderNames);
+ }
+ return;
+ }
+
int dexPathIndex = 0;
for (String dexPath : dexPathsToRegister) {
// Find the owning package name.
@@ -219,14 +230,10 @@
}
// Record dex file usage. If the current usage is a new pattern (e.g. new secondary,
- // or UsedBytOtherApps), record will return true and we trigger an async write
+ // or UsedByOtherApps), record will return true and we trigger an async write
// to disk to make sure we don't loose the data in case of a reboot.
- // A null classLoaderContexts means that there are unsupported class loaders in the
- // chain.
- String classLoaderContext = classLoaderContexts == null
- ? PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT
- : classLoaderContexts[dexPathIndex];
+ String classLoaderContext = classLoaderContexts[dexPathIndex];
if (mPackageDexUsage.record(searchResult.mOwningPackageName,
dexPath, loaderUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
loadingAppInfo.packageName, classLoaderContext)) {
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 602ce3b..86f7380 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -21,6 +21,7 @@
import android.os.Build;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FastPrintWriter;
import com.android.server.pm.AbstractStatsBase;
import com.android.server.pm.PackageManagerServiceUtils;
@@ -78,14 +79,16 @@
// skip optimizations on that dex files.
/*package*/ static final String VARIABLE_CLASS_LOADER_CONTEXT =
"=VariableClassLoaderContext=";
- // The marker used for unsupported class loader contexts.
- /*package*/ static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
- "=UnsupportedClassLoaderContext=";
// The markers used for unknown class loader contexts. This can happen if the dex file was
// recorded in a previous version and we didn't have a chance to update its usage.
/*package*/ static final String UNKNOWN_CLASS_LOADER_CONTEXT =
"=UnknownClassLoaderContext=";
+ // The marker used for unsupported class loader contexts (no longer written, may occur in old
+ // files so discarded on read).
+ private static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
+ "=UnsupportedClassLoaderContext=";
+
// Map which structures the information we have on a package.
// Maps package name to package data (which stores info about UsedByOtherApps and
// secondary dex files.).
@@ -365,6 +368,12 @@
Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
String classLoaderContext = maybeReadClassLoaderContext(in, version);
+ if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(classLoaderContext)) {
+ // We used to record use of unsupported class loaders, but we no longer do.
+ // Discard such entries; they will be deleted when we next write the file.
+ continue;
+ }
+
int ownerUserId = Integer.parseInt(elems[0]);
boolean isUsedByOtherApps = readBoolean(elems[1]);
DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId,
@@ -709,13 +718,13 @@
// the compiled code will be private.
private boolean mUsedByOtherAppsBeforeUpgrade;
- public PackageUseInfo() {
+ /*package*/ PackageUseInfo() {
mCodePathsUsedByOtherApps = new HashMap<>();
mDexUseInfoMap = new HashMap<>();
}
// Creates a deep copy of the `other`.
- public PackageUseInfo(PackageUseInfo other) {
+ private PackageUseInfo(PackageUseInfo other) {
mCodePathsUsedByOtherApps = new HashMap<>();
for (Map.Entry<String, Set<String>> e : other.mCodePathsUsedByOtherApps.entrySet()) {
mCodePathsUsedByOtherApps.put(e.getKey(), new HashSet<>(e.getValue()));
@@ -796,8 +805,9 @@
// Packages who load this dex file.
private final Set<String> mLoadingPackages;
- public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String classLoaderContext,
- String loaderIsa) {
+ @VisibleForTesting
+ /* package */ DexUseInfo(boolean isUsedByOtherApps, int ownerUserId,
+ String classLoaderContext, String loaderIsa) {
mIsUsedByOtherApps = isUsedByOtherApps;
mOwnerUserId = ownerUserId;
mClassLoaderContext = classLoaderContext;
@@ -809,7 +819,7 @@
}
// Creates a deep copy of the `other`.
- public DexUseInfo(DexUseInfo other) {
+ private DexUseInfo(DexUseInfo other) {
mIsUsedByOtherApps = other.mIsUsedByOtherApps;
mOwnerUserId = other.mOwnerUserId;
mClassLoaderContext = other.mClassLoaderContext;
@@ -827,11 +837,7 @@
if (UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext)) {
// Can happen if we read a previous version.
mClassLoaderContext = dexUseInfo.mClassLoaderContext;
- } else if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(dexUseInfo.mClassLoaderContext)) {
- // We detected an unsupported context.
- mClassLoaderContext = UNSUPPORTED_CLASS_LOADER_CONTEXT;
- } else if (!UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext) &&
- !Objects.equals(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
+ } else if (!Objects.equals(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
// We detected a context change.
mClassLoaderContext = VARIABLE_CLASS_LOADER_CONTEXT;
}
@@ -846,7 +852,7 @@
return mIsUsedByOtherApps;
}
- public int getOwnerUserId() {
+ /* package */ int getOwnerUserId() {
return mOwnerUserId;
}
@@ -860,17 +866,15 @@
public String getClassLoaderContext() { return mClassLoaderContext; }
- public boolean isUnsupportedClassLoaderContext() {
- return UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
- }
-
- public boolean isUnknownClassLoaderContext() {
+ @VisibleForTesting
+ /* package */ boolean isUnknownClassLoaderContext() {
// The class loader context may be unknown if we loaded the data from a previous version
// which didn't save the context.
return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
- public boolean isVariableClassLoaderContext() {
+ @VisibleForTesting
+ /* package */ boolean isVariableClassLoaderContext() {
return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 49f410d..f432c8d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -68,6 +68,7 @@
import com.android.server.appbinding.AppBindingService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.BiometricService;
+import com.android.server.biometrics.iris.IrisService;
import com.android.server.broadcastradio.BroadcastRadioService;
import com.android.server.camera.CameraServiceProxy;
import com.android.server.clipboard.ClipboardService;
@@ -1589,6 +1590,8 @@
final boolean hasFeatureFace
= mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE);
+ final boolean hasFeatureIris
+ = mPackageManager.hasSystemFeature(PackageManager.FEATURE_IRIS);
final boolean hasFeatureFingerprint
= mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
@@ -1598,13 +1601,19 @@
traceEnd();
}
+ if (hasFeatureIris) {
+ traceBeginAndSlog("StartIrisSensor");
+ mSystemServiceManager.startService(IrisService.class);
+ traceEnd();
+ }
+
if (hasFeatureFingerprint) {
traceBeginAndSlog("StartFingerprintSensor");
mSystemServiceManager.startService(FingerprintService.class);
traceEnd();
}
- if (hasFeatureFace || hasFeatureFingerprint) {
+ if (hasFeatureFace || hasFeatureIris || hasFeatureFingerprint) {
// Start this service after all biometric services.
traceBeginAndSlog("StartBiometricPromptService");
mSystemServiceManager.startService(BiometricService.class);
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 416a616..bd42b73 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -401,15 +401,7 @@
List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
- PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
- assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
- // We expect that all the contexts are unsupported.
- String[] expectedContexts =
- Collections.nCopies(secondaries.size(),
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+ assertNoUseInfo(mBarUser0UnsupportedClassLoader);
}
@Test
@@ -438,27 +430,18 @@
}
@Test
- public void testNotifyUnsupportedClassLoaderDoesNotChange() {
- List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
+ public void testNotifyUnsupportedClassLoaderDoesNotChangeExisting() {
+ List<String> secondaries = mBarUser0.getSecondaryDexPaths();
+
+ notifyDexLoad(mBarUser0, secondaries, mUser0);
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+ assertSecondaryUse(mBarUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
+
+ // Record bar secondaries again with an unsupported class loader. This should not change the
+ // context.
notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
-
- PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
- assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
- // We expect that all the contexts are unsupported.
- String[] expectedContexts =
- Collections.nCopies(secondaries.size(),
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
-
- // Record bar secondaries again with a different class loader. This will change the context.
- // However, because the context was already marked as unsupported we should not chage it.
- notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
- pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
-
+ pui = getPackageUseInfo(mBarUser0);
+ assertSecondaryUse(mBarUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index 3e93dcf..7755e94 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -399,20 +399,6 @@
}
@Test
- public void testRecordClassLoaderContextUnsupportedContext() {
- // Record a secondary dex file.
- assertTrue(record(mFooSecondary1User0));
- // Now update its context.
- TestData unsupportedContext = mFooSecondary1User0.updateClassLoaderContext(
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT);
- assertTrue(record(unsupportedContext));
-
- assertPackageDexUsage(null, unsupportedContext);
- writeAndReadBack();
- assertPackageDexUsage(null, unsupportedContext);
- }
-
- @Test
public void testRecordClassLoaderContextTransitionFromUnknown() {
// Record a secondary dex file.
TestData unknownContext = mFooSecondary1User0.updateClassLoaderContext(
@@ -440,29 +426,41 @@
PackageDexUsage.DexUseInfo validContext = new DexUseInfo(isUsedByOtherApps, userId,
"valid_context", "arm");
assertFalse(validContext.isUnknownClassLoaderContext());
- assertFalse(validContext.isUnsupportedClassLoaderContext());
assertFalse(validContext.isVariableClassLoaderContext());
- PackageDexUsage.DexUseInfo unsupportedContext = new DexUseInfo(isUsedByOtherApps, userId,
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT, "arm");
- assertFalse(unsupportedContext.isUnknownClassLoaderContext());
- assertTrue(unsupportedContext.isUnsupportedClassLoaderContext());
- assertFalse(unsupportedContext.isVariableClassLoaderContext());
-
PackageDexUsage.DexUseInfo variableContext = new DexUseInfo(isUsedByOtherApps, userId,
PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT, "arm");
assertFalse(variableContext.isUnknownClassLoaderContext());
- assertFalse(variableContext.isUnsupportedClassLoaderContext());
assertTrue(variableContext.isVariableClassLoaderContext());
PackageDexUsage.DexUseInfo unknownContext = new DexUseInfo(isUsedByOtherApps, userId,
PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT, "arm");
assertTrue(unknownContext.isUnknownClassLoaderContext());
- assertFalse(unknownContext.isUnsupportedClassLoaderContext());
assertFalse(unknownContext.isVariableClassLoaderContext());
}
@Test
+ public void testUnsupportedClassLoaderDiscardedOnRead() throws Exception {
+ String content = "PACKAGE_MANAGER__PACKAGE_DEX_USAGE__2\n"
+ + mBarSecondary1User0.mPackageName + "\n"
+ + "#" + mBarSecondary1User0.mDexFile + "\n"
+ + "0,0," + mBarSecondary1User0.mLoaderIsa + "\n"
+ + "@\n"
+ + "=UnsupportedClassLoaderContext=\n"
+
+ + mFooSecondary1User0.mPackageName + "\n"
+ + "#" + mFooSecondary1User0.mDexFile + "\n"
+ + "0,0," + mFooSecondary1User0.mLoaderIsa + "\n"
+ + "@\n"
+ + mFooSecondary1User0.mClassLoaderContext + "\n";
+
+ mPackageDexUsage.read(new StringReader(content));
+
+ assertPackageDexUsage(mFooBaseUser0, mFooSecondary1User0);
+ assertPackageDexUsage(mBarBaseUser0);
+ }
+
+ @Test
public void testReadVersion1() {
String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
// Equivalent to
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 05c1fd5..d6856b3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -31,27 +31,8 @@
private static final String LOG_TAG = "CellSignalStrengthLte";
private static final boolean DBG = false;
- /**
- * Indicates the unknown or undetectable RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
- /**
- * Indicates the maximum valid RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
- /**
- * Indicates the minimum valid RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
-
@UnsupportedAppUsage
- private int mRssi;
+ private int mSignalStrength;
@UnsupportedAppUsage
private int mRsrp;
@UnsupportedAppUsage
@@ -70,9 +51,9 @@
}
/** @hide */
- public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
+ public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi,
int timingAdvance) {
- mRssi = convertRssiAsuToDBm(rssi);
+ mSignalStrength = signalStrength;
mRsrp = rsrp;
mRsrq = rsrq;
mRssnr = rssnr;
@@ -87,7 +68,7 @@
/** @hide */
protected void copyFrom(CellSignalStrengthLte s) {
- mRssi = s.mRssi;
+ mSignalStrength = s.mSignalStrength;
mRsrp = s.mRsrp;
mRsrq = s.mRsrq;
mRssnr = s.mRssnr;
@@ -104,7 +85,7 @@
/** @hide */
@Override
public void setDefaultValues() {
- mRssi = CellInfo.UNAVAILABLE;
+ mSignalStrength = CellInfo.UNAVAILABLE;
mRsrp = CellInfo.UNAVAILABLE;
mRsrq = CellInfo.UNAVAILABLE;
mRssnr = CellInfo.UNAVAILABLE;
@@ -161,19 +142,6 @@
}
/**
- * Get Received Signal Strength Indication (RSSI) in dBm
- *
- * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
- *
- * Reference: TS 27.007 8.5 Signal quality +CSQ
- *
- * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
- */
- public int getRssi() {
- return mRssi;
- }
-
- /**
* Get reference signal signal-to-noise ratio
*
* @return the RSSNR if available or
@@ -242,7 +210,7 @@
@Override
public int hashCode() {
- return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
+ return Objects.hash(mSignalStrength, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
}
@Override
@@ -259,7 +227,7 @@
return false;
}
- return mRssi == s.mRssi
+ return mSignalStrength == s.mSignalStrength
&& mRsrp == s.mRsrp
&& mRsrq == s.mRsrq
&& mRssnr == s.mRssnr
@@ -273,7 +241,7 @@
@Override
public String toString() {
return "CellSignalStrengthLte:"
- + " rssi(dBm)=" + mRssi
+ + " ss=" + mSignalStrength
+ " rsrp=" + mRsrp
+ " rsrq=" + mRsrq
+ " rssnr=" + mRssnr
@@ -285,7 +253,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mRssi);
+ dest.writeInt(mSignalStrength);
// Need to multiply rsrp and rsrq by -1
// to ensure consistency when reading values written here
// unless the values are invalid
@@ -301,7 +269,7 @@
* where the token is already been processed.
*/
private CellSignalStrengthLte(Parcel in) {
- mRssi = convertRssiAsuToDBm(in.readInt());
+ mSignalStrength = in.readInt();
// rsrp and rsrq are written into the parcel as positive values.
// Need to convert into negative values unless the values are invalid
mRsrp = in.readInt();
@@ -341,17 +309,4 @@
private static void log(String s) {
Rlog.w(LOG_TAG, s);
}
-
- private static int convertRssiAsuToDBm(int rssiAsu) {
- if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN
- && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
- || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
- Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
- return CellInfo.UNAVAILABLE;
- }
- if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
- return CellInfo.UNAVAILABLE;
- }
- return -113 + (2 * rssiAsu);
- }
}