Merge "Statsd Puller Callback Registration"
This commit is contained in:
@@ -804,6 +804,7 @@ filegroup {
|
||||
srcs: [
|
||||
"core/java/android/os/IStatsCompanionService.aidl",
|
||||
"core/java/android/os/IStatsManager.aidl",
|
||||
"core/java/android/os/IStatsPullerCallback.aidl",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ cc_defaults {
|
||||
"src/external/Perfetto.cpp",
|
||||
"src/external/Perfprofd.cpp",
|
||||
"src/external/StatsPuller.cpp",
|
||||
"src/external/StatsCallbackPuller.cpp",
|
||||
"src/external/StatsCompanionServicePuller.cpp",
|
||||
"src/external/SubsystemSleepStatePuller.cpp",
|
||||
"src/external/PowerStatsPuller.cpp",
|
||||
|
||||
@@ -1057,6 +1057,24 @@ Status StatsService::sendAppBreadcrumbAtom(int32_t label, int32_t state) {
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
Status StatsService::registerPullerCallback(int32_t atomTag,
|
||||
const sp<android::os::IStatsPullerCallback>& pullerCallback,
|
||||
const String16& packageName) {
|
||||
ENFORCE_DUMP_AND_USAGE_STATS(packageName);
|
||||
|
||||
VLOG("StatsService::registerPullerCallback called.");
|
||||
mPullerManager->RegisterPullerCallback(atomTag, pullerCallback);
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
Status StatsService::unregisterPullerCallback(int32_t atomTag, const String16& packageName) {
|
||||
ENFORCE_DUMP_AND_USAGE_STATS(packageName);
|
||||
|
||||
VLOG("StatsService::unregisterPullerCallback called.");
|
||||
mPullerManager->UnregisterPullerCallback(atomTag);
|
||||
return Status::ok();
|
||||
}
|
||||
|
||||
hardware::Return<void> StatsService::reportSpeakerImpedance(
|
||||
const SpeakerImpedance& speakerImpedance) {
|
||||
LogEvent event(getWallClockSec() * NS_PER_SEC, getElapsedRealtimeNs(), speakerImpedance);
|
||||
|
||||
@@ -172,6 +172,19 @@ public:
|
||||
*/
|
||||
virtual Status sendAppBreadcrumbAtom(int32_t label, int32_t state) override;
|
||||
|
||||
/**
|
||||
* Binder call to register a callback function for a vendor pulled atom.
|
||||
* Note: this atom must NOT have uid as a field.
|
||||
*/
|
||||
virtual Status registerPullerCallback(int32_t atomTag,
|
||||
const sp<android::os::IStatsPullerCallback>& pullerCallback,
|
||||
const String16& packageName) override;
|
||||
|
||||
/**
|
||||
* Binder call to unregister any existing callback function for a vendor pulled atom.
|
||||
*/
|
||||
virtual Status unregisterPullerCallback(int32_t atomTag, const String16& packageName) override;
|
||||
|
||||
/**
|
||||
* Binder call to get SpeakerImpedance atom.
|
||||
*/
|
||||
|
||||
61
cmds/statsd/src/external/StatsCallbackPuller.cpp
vendored
Normal file
61
cmds/statsd/src/external/StatsCallbackPuller.cpp
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define DEBUG false // STOPSHIP if true
|
||||
#include "Log.h"
|
||||
|
||||
#include <android/os/IStatsPullerCallback.h>
|
||||
|
||||
#include "StatsCallbackPuller.h"
|
||||
#include "logd/LogEvent.h"
|
||||
#include "stats_log_util.h"
|
||||
|
||||
using namespace android::binder;
|
||||
|
||||
namespace android {
|
||||
namespace os {
|
||||
namespace statsd {
|
||||
|
||||
StatsCallbackPuller::StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback) :
|
||||
StatsPuller(tagId), mCallback(callback) {
|
||||
VLOG("StatsCallbackPuller created for tag %d", tagId);
|
||||
}
|
||||
|
||||
bool StatsCallbackPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
|
||||
VLOG("StatsCallbackPuller called for tag %d", mTagId)
|
||||
if(mCallback == nullptr) {
|
||||
ALOGW("No callback registered");
|
||||
return false;
|
||||
}
|
||||
int64_t wallClockTimeNs = getWallClockNs();
|
||||
int64_t elapsedTimeNs = getElapsedRealtimeNs();
|
||||
vector<StatsLogEventWrapper> returned_value;
|
||||
Status status = mCallback->pullData(mTagId, elapsedTimeNs, wallClockTimeNs, &returned_value);
|
||||
if (!status.isOk()) {
|
||||
ALOGW("StatsCallbackPuller::pull failed for %d", mTagId);
|
||||
return false;
|
||||
}
|
||||
data->clear();
|
||||
for (const StatsLogEventWrapper& it: returned_value) {
|
||||
LogEvent::createLogEvents(it, *data);
|
||||
}
|
||||
VLOG("StatsCallbackPuller::pull succeeded for %d", mTagId);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
38
cmds/statsd/src/external/StatsCallbackPuller.h
vendored
Normal file
38
cmds/statsd/src/external/StatsCallbackPuller.h
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android/os/IStatsPullerCallback.h>
|
||||
#include <utils/String16.h>
|
||||
#include "StatsPuller.h"
|
||||
|
||||
namespace android {
|
||||
namespace os {
|
||||
namespace statsd {
|
||||
|
||||
class StatsCallbackPuller : public StatsPuller {
|
||||
public:
|
||||
explicit StatsCallbackPuller(int tagId, const sp<IStatsPullerCallback>& callback);
|
||||
|
||||
private:
|
||||
bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
|
||||
const sp<IStatsPullerCallback> mCallback;
|
||||
};
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
2
cmds/statsd/src/external/StatsPuller.cpp
vendored
2
cmds/statsd/src/external/StatsPuller.cpp
vendored
@@ -33,7 +33,7 @@ sp<UidMap> StatsPuller::mUidMap = nullptr;
|
||||
void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; }
|
||||
|
||||
StatsPuller::StatsPuller(const int tagId)
|
||||
: mTagId(tagId) {
|
||||
: mTagId(tagId), mLastPullTimeNs(0) {
|
||||
}
|
||||
|
||||
bool StatsPuller::Pull(std::vector<std::shared_ptr<LogEvent>>* data) {
|
||||
|
||||
28
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
28
cmds/statsd/src/external/StatsPullerManager.cpp
vendored
@@ -18,6 +18,7 @@
|
||||
#include "Log.h"
|
||||
|
||||
#include <android/os/IStatsCompanionService.h>
|
||||
#include <android/os/IStatsPullerCallback.h>
|
||||
#include <cutils/log.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
@@ -29,6 +30,7 @@
|
||||
#include "PowerStatsPuller.h"
|
||||
#include "ResourceHealthManagerPuller.h"
|
||||
#include "StatsCompanionServicePuller.h"
|
||||
#include "StatsCallbackPuller.h"
|
||||
#include "StatsPullerManager.h"
|
||||
#include "SubsystemSleepStatePuller.h"
|
||||
#include "statslog.h"
|
||||
@@ -49,7 +51,7 @@ namespace statsd {
|
||||
// Values smaller than this may require to update the alarm.
|
||||
const int64_t NO_ALARM_UPDATE = INT64_MAX;
|
||||
|
||||
const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
|
||||
std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
|
||||
// wifi_bytes_transfer
|
||||
{android::util::WIFI_BYTES_TRANSFER,
|
||||
{.additiveFields = {2, 3, 4, 5},
|
||||
@@ -420,6 +422,30 @@ int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) {
|
||||
return totalCleared;
|
||||
}
|
||||
|
||||
void StatsPullerManager::RegisterPullerCallback(int32_t atomTag,
|
||||
const sp<IStatsPullerCallback>& callback) {
|
||||
AutoMutex _l(mLock);
|
||||
// Platform pullers cannot be changed.
|
||||
if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
|
||||
VLOG("RegisterPullerCallback: atom tag %d is less than min tag %d",
|
||||
atomTag, StatsdStats::kMaxPlatformAtomTag);
|
||||
return;
|
||||
}
|
||||
VLOG("RegisterPullerCallback: adding puller for tag %d", atomTag);
|
||||
StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/true);
|
||||
kAllPullAtomInfo[atomTag] = {.puller = new StatsCallbackPuller(atomTag, callback)};
|
||||
}
|
||||
|
||||
void StatsPullerManager::UnregisterPullerCallback(int32_t atomTag) {
|
||||
AutoMutex _l(mLock);
|
||||
// Platform pullers cannot be changed.
|
||||
if (atomTag < StatsdStats::kMaxPlatformAtomTag) {
|
||||
return;
|
||||
}
|
||||
StatsdStats::getInstance().notePullerCallbackRegistrationChanged(atomTag, /*registered=*/false);
|
||||
kAllPullAtomInfo.erase(atomTag);
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <android/os/IStatsCompanionService.h>
|
||||
#include <android/os/IStatsPullerCallback.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/threads.h>
|
||||
@@ -91,7 +92,12 @@ public:
|
||||
|
||||
void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
|
||||
|
||||
const static std::map<int, PullAtomInfo> kAllPullAtomInfo;
|
||||
void RegisterPullerCallback(int32_t atomTag,
|
||||
const sp<IStatsPullerCallback>& callback);
|
||||
|
||||
void UnregisterPullerCallback(int32_t atomTag);
|
||||
|
||||
static std::map<int, PullAtomInfo> kAllPullAtomInfo;
|
||||
|
||||
private:
|
||||
sp<IStatsCompanionService> mStatsCompanionService = nullptr;
|
||||
|
||||
@@ -423,6 +423,15 @@ void StatsdStats::noteEmptyData(int atomId) {
|
||||
mPulledAtomStats[atomId].emptyData++;
|
||||
}
|
||||
|
||||
void StatsdStats::notePullerCallbackRegistrationChanged(int atomId, bool registered) {
|
||||
lock_guard<std::mutex> lock(mLock);
|
||||
if (registered) {
|
||||
mPulledAtomStats[atomId].registeredCount++;
|
||||
} else {
|
||||
mPulledAtomStats[atomId].unregisteredCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void StatsdStats::noteHardDimensionLimitReached(int64_t metricId) {
|
||||
lock_guard<std::mutex> lock(mLock);
|
||||
getAtomMetricStats(metricId).hardDimensionLimitReached++;
|
||||
@@ -514,6 +523,8 @@ void StatsdStats::resetInternalLocked() {
|
||||
pullStats.second.dataError = 0;
|
||||
pullStats.second.pullTimeout = 0;
|
||||
pullStats.second.pullExceedMaxDelay = 0;
|
||||
pullStats.second.registeredCount = 0;
|
||||
pullStats.second.unregisteredCount = 0;
|
||||
}
|
||||
mAtomMetricStats.clear();
|
||||
}
|
||||
@@ -625,12 +636,14 @@ void StatsdStats::dumpStats(int out) const {
|
||||
" (average pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay "
|
||||
"nanos)%lld, "
|
||||
" (max pull delay nanos)%lld, (data error)%ld\n"
|
||||
" (pull timeout)%ld, (pull exceed max delay)%ld\n",
|
||||
" (pull timeout)%ld, (pull exceed max delay)%ld\n"
|
||||
" (registered count) %ld, (unregistered count) %ld\n",
|
||||
(int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
|
||||
(long)pair.second.minPullIntervalSec, (long long)pair.second.avgPullTimeNs,
|
||||
(long long)pair.second.maxPullTimeNs, (long long)pair.second.avgPullDelayNs,
|
||||
(long long)pair.second.maxPullDelayNs, pair.second.dataError,
|
||||
pair.second.pullTimeout, pair.second.pullExceedMaxDelay);
|
||||
pair.second.pullTimeout, pair.second.pullExceedMaxDelay,
|
||||
pair.second.registeredCount, pair.second.unregisteredCount);
|
||||
}
|
||||
|
||||
if (mAnomalyAlarmRegisteredStats > 0) {
|
||||
|
||||
@@ -146,6 +146,10 @@ public:
|
||||
|
||||
// Max time to do a pull.
|
||||
static const int64_t kPullMaxDelayNs = 10 * NS_PER_SEC;
|
||||
|
||||
// Max platform atom tag number.
|
||||
static const int32_t kMaxPlatformAtomTag = 100000;
|
||||
|
||||
/**
|
||||
* Report a new config has been received and report the static stats about the config.
|
||||
*
|
||||
@@ -339,6 +343,13 @@ public:
|
||||
*/
|
||||
void noteEmptyData(int atomId);
|
||||
|
||||
/**
|
||||
* Records that a puller callback for the given atomId was registered or unregistered.
|
||||
*
|
||||
* @param registered True if the callback was registered, false if was unregistered.
|
||||
*/
|
||||
void notePullerCallbackRegistrationChanged(int atomId, bool registered);
|
||||
|
||||
/**
|
||||
* Hard limit was reached in the cardinality of an atom
|
||||
*/
|
||||
@@ -416,6 +427,8 @@ public:
|
||||
long statsCompanionPullFailed = 0;
|
||||
long statsCompanionPullBinderTransactionFailed = 0;
|
||||
long emptyData = 0;
|
||||
long registeredCount = 0;
|
||||
long unregisteredCount = 0;
|
||||
} PulledAtomStats;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -407,6 +407,8 @@ message StatsdStatsReport {
|
||||
optional int64 stats_companion_pull_failed = 13;
|
||||
optional int64 stats_companion_pull_binder_transaction_failed = 14;
|
||||
optional int64 empty_data = 15;
|
||||
optional int64 registered_count = 16;
|
||||
optional int64 unregistered_count = 17;
|
||||
}
|
||||
repeated PulledAtomStats pulled_atom_stats = 10;
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ const int FIELD_ID_PULL_FAILED = 12;
|
||||
const int FIELD_ID_STATS_COMPANION_FAILED = 13;
|
||||
const int FIELD_ID_STATS_COMPANION_BINDER_TRANSACTION_FAILED = 14;
|
||||
const int FIELD_ID_EMPTY_DATA = 15;
|
||||
const int FIELD_ID_PULL_REGISTERED_COUNT = 16;
|
||||
const int FIELD_ID_PULL_UNREGISTERED_COUNT = 17;
|
||||
// for AtomMetricStats proto
|
||||
const int FIELD_ID_ATOM_METRIC_STATS = 17;
|
||||
const int FIELD_ID_METRIC_ID = 1;
|
||||
@@ -480,6 +482,10 @@ void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>
|
||||
(long long)pair.second.statsCompanionPullBinderTransactionFailed);
|
||||
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_EMPTY_DATA,
|
||||
(long long)pair.second.emptyData);
|
||||
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_REGISTERED_COUNT,
|
||||
(long long) pair.second.registeredCount);
|
||||
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_PULL_UNREGISTERED_COUNT,
|
||||
(long long) pair.second.unregisteredCount);
|
||||
protoOutput->end(token);
|
||||
}
|
||||
|
||||
|
||||
@@ -259,6 +259,10 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
|
||||
stats.notePullDelay(android::util::DISK_SPACE, 3335L);
|
||||
stats.notePull(android::util::DISK_SPACE);
|
||||
stats.notePullFromCache(android::util::DISK_SPACE);
|
||||
stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
|
||||
stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, false);
|
||||
stats.notePullerCallbackRegistrationChanged(android::util::DISK_SPACE, true);
|
||||
|
||||
|
||||
vector<uint8_t> output;
|
||||
stats.dumpStats(&output, false);
|
||||
@@ -276,6 +280,8 @@ TEST(StatsdStatsTest, TestPullAtomStats) {
|
||||
EXPECT_EQ(3333L, report.pulled_atom_stats(0).max_pull_time_nanos());
|
||||
EXPECT_EQ(2223L, report.pulled_atom_stats(0).average_pull_delay_nanos());
|
||||
EXPECT_EQ(3335L, report.pulled_atom_stats(0).max_pull_delay_nanos());
|
||||
EXPECT_EQ(2L, report.pulled_atom_stats(0).registered_count());
|
||||
EXPECT_EQ(1L, report.pulled_atom_stats(0).unregistered_count());
|
||||
}
|
||||
|
||||
TEST(StatsdStatsTest, TestAtomMetricsStats) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.annotation.SystemApi;
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.IStatsManager;
|
||||
import android.os.IStatsPullerCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.AndroidException;
|
||||
@@ -408,6 +409,39 @@ public final class StatsManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a callback for an atom when that atom is to be pulled. The stats service will
|
||||
* invoke pullData in the callback when the stats service determines that this atom needs to be
|
||||
* pulled. Currently, this only works for atoms with tags above 100,000 that do not have a uid.
|
||||
*
|
||||
* @param atomTag The tag of the atom for this puller callback. Must be at least 100000.
|
||||
* @param callback The callback to be invoked when the stats service pulls the atom.
|
||||
* @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
|
||||
public void setPullerCallback(int atomTag, IStatsPullerCallback callback)
|
||||
throws StatsUnavailableException {
|
||||
synchronized (this) {
|
||||
try {
|
||||
IStatsManager service = getIStatsManagerLocked();
|
||||
if (callback == null) {
|
||||
service.unregisterPullerCallback(atomTag, mContext.getOpPackageName());
|
||||
} else {
|
||||
service.registerPullerCallback(atomTag, callback,
|
||||
mContext.getOpPackageName());
|
||||
}
|
||||
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to connect to statsd when registering data listener.");
|
||||
throw new StatsUnavailableException("could not connect", e);
|
||||
} catch (SecurityException e) {
|
||||
throw new StatsUnavailableException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class StatsdDeathRecipient implements IBinder.DeathRecipient {
|
||||
@Override
|
||||
public void binderDied() {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.os.IStatsPullerCallback;
|
||||
|
||||
/**
|
||||
* Binder interface to communicate with the statistics management service.
|
||||
* {@hide}
|
||||
@@ -178,4 +180,20 @@ interface IStatsManager {
|
||||
* this label. This allows building custom metrics and predicates.
|
||||
*/
|
||||
void sendAppBreadcrumbAtom(int label, int state);
|
||||
|
||||
/**
|
||||
* Registers a puller callback function that, when invoked, pulls the data
|
||||
* for the specified vendor atom tag.
|
||||
*
|
||||
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
|
||||
*/
|
||||
oneway void registerPullerCallback(int atomTag, IStatsPullerCallback pullerCallback,
|
||||
String packageName);
|
||||
|
||||
/**
|
||||
* Unregisters a puller callback function for the given vendor atom.
|
||||
*
|
||||
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS
|
||||
*/
|
||||
oneway void unregisterPullerCallback(int atomTag, String packageName);
|
||||
}
|
||||
|
||||
35
core/java/android/os/IStatsPullerCallback.aidl
Normal file
35
core/java/android/os/IStatsPullerCallback.aidl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.os;
|
||||
|
||||
import android.os.StatsLogEventWrapper;
|
||||
|
||||
/**
|
||||
* Binder interface to pull atoms for the stats service.
|
||||
* {@hide}
|
||||
*/
|
||||
interface IStatsPullerCallback {
|
||||
/**
|
||||
* Pull data for the specified atom tag. Returns an array of StatsLogEventWrapper containing
|
||||
* the data.
|
||||
*
|
||||
* Note: These pulled atoms should not have uid/attribution chain. Additionally, the event
|
||||
* timestamps will be truncated to the nearest 5 minutes.
|
||||
*/
|
||||
StatsLogEventWrapper[] pullData(int atomTag, long elapsedNanos, long wallClocknanos);
|
||||
|
||||
}
|
||||
@@ -57,20 +57,18 @@ public final class StatsLogEventWrapper implements Parcelable {
|
||||
public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new
|
||||
Parcelable.Creator<StatsLogEventWrapper>() {
|
||||
public StatsLogEventWrapper createFromParcel(Parcel in) {
|
||||
android.util.EventLog.writeEvent(0x534e4554, "112550251",
|
||||
android.os.Binder.getCallingUid(), "");
|
||||
// Purposefully leaving this method not implemented.
|
||||
throw new RuntimeException("Not implemented");
|
||||
return new StatsLogEventWrapper(in);
|
||||
}
|
||||
|
||||
public StatsLogEventWrapper[] newArray(int size) {
|
||||
android.util.EventLog.writeEvent(0x534e4554, "112550251",
|
||||
android.os.Binder.getCallingUid(), "");
|
||||
// Purposefully leaving this method not implemented.
|
||||
throw new RuntimeException("Not implemented");
|
||||
return new StatsLogEventWrapper[size];
|
||||
}
|
||||
};
|
||||
|
||||
private StatsLogEventWrapper(Parcel in) {
|
||||
readFromParcel(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set work source if any.
|
||||
*/
|
||||
@@ -196,6 +194,70 @@ public final class StatsLogEventWrapper implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads from parcel and appropriately fills member fields.
|
||||
*/
|
||||
public void readFromParcel(Parcel in) {
|
||||
mTypes = new ArrayList<>();
|
||||
mValues = new ArrayList<>();
|
||||
mWorkSource = null;
|
||||
|
||||
mTag = in.readInt();
|
||||
mElapsedTimeNs = in.readLong();
|
||||
mWallClockTimeNs = in.readLong();
|
||||
|
||||
// Clear any data.
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Reading " + mTag + " " + mElapsedTimeNs + " " + mWallClockTimeNs);
|
||||
}
|
||||
// Set up worksource if present.
|
||||
int numWorkChains = in.readInt();
|
||||
if (numWorkChains > 0) {
|
||||
mWorkSource = new WorkSource();
|
||||
for (int i = 0; i < numWorkChains; i++) {
|
||||
android.os.WorkSource.WorkChain workChain = mWorkSource.createWorkChain();
|
||||
int workChainSize = in.readInt();
|
||||
for (int j = 0; j < workChainSize; j++) {
|
||||
int uid = in.readInt();
|
||||
String tag = in.readString();
|
||||
workChain.addNode(uid, tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do the rest of the types.
|
||||
int numTypes = in.readInt();
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Reading " + numTypes + " elements");
|
||||
}
|
||||
for (int i = 0; i < numTypes; i++) {
|
||||
int type = in.readInt();
|
||||
mTypes.add(type);
|
||||
switch (type) {
|
||||
case EVENT_TYPE_INT:
|
||||
mValues.add(in.readInt());
|
||||
break;
|
||||
case EVENT_TYPE_LONG:
|
||||
mValues.add(in.readLong());
|
||||
break;
|
||||
case EVENT_TYPE_FLOAT:
|
||||
mValues.add(in.readFloat());
|
||||
break;
|
||||
case EVENT_TYPE_DOUBLE:
|
||||
mValues.add(in.readDouble());
|
||||
break;
|
||||
case EVENT_TYPE_STRING:
|
||||
mValues.add(in.readString());
|
||||
break;
|
||||
case EVENT_TYPE_STORAGE:
|
||||
mValues.add(in.createByteArray());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Boilerplate for Parcel.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user