Merge "APIs for registering config activation broadcasts"

This commit is contained in:
Tej Singh
2019-01-27 02:32:37 +00:00
committed by Android (Google) Code Review
7 changed files with 142 additions and 0 deletions

View File

@@ -508,11 +508,13 @@ package android.app {
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setFetchReportsOperation(android.app.PendingIntent, long) throws android.app.StatsManager.StatsUnavailableException;
field public static final String ACTION_STATSD_STARTED = "android.app.action.STATSD_STARTED";
field public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS = "android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
field public static final String EXTRA_STATS_BROADCAST_SUBSCRIBER_COOKIES = "android.app.extra.STATS_BROADCAST_SUBSCRIBER_COOKIES";
field public static final String EXTRA_STATS_CONFIG_KEY = "android.app.extra.STATS_CONFIG_KEY";
field public static final String EXTRA_STATS_CONFIG_UID = "android.app.extra.STATS_CONFIG_UID";

View File

@@ -989,6 +989,25 @@ Status StatsService::setDataFetchOperation(int64_t key,
return Status::ok();
}
Status StatsService::setActiveConfigsChangedOperation(const sp<android::IBinder>& intentSender,
const String16& packageName,
vector<int64_t>* output) {
ENFORCE_DUMP_AND_USAGE_STATS(packageName);
IPCThreadState* ipc = IPCThreadState::self();
mConfigManager->SetActiveConfigsChangedReceiver(ipc->getCallingUid(), intentSender);
//TODO: Return the list of configs that are already active
return Status::ok();
}
Status StatsService::removeActiveConfigsChangedOperation(const String16& packageName) {
ENFORCE_DUMP_AND_USAGE_STATS(packageName);
IPCThreadState* ipc = IPCThreadState::self();
mConfigManager->RemoveActiveConfigsChangedReceiver(ipc->getCallingUid());
return Status::ok();
}
Status StatsService::removeConfiguration(int64_t key, const String16& packageName) {
ENFORCE_DUMP_AND_USAGE_STATS(packageName);

View File

@@ -131,6 +131,17 @@ public:
virtual Status removeDataFetchOperation(int64_t key,
const String16& packageName) override;
/**
* Binder call to let clients register the active configs changed operation.
*/
virtual Status setActiveConfigsChangedOperation(const sp<android::IBinder>& intentSender,
const String16& packageName,
vector<int64_t>* output) override;
/**
* Binder call to remove the active configs changed operation for the specified package..
*/
virtual Status removeActiveConfigsChangedOperation(const String16& packageName) override;
/**
* Binder call to allow clients to remove the specified configuration.
*/

View File

@@ -128,6 +128,17 @@ void ConfigManager::RemoveConfigReceiver(const ConfigKey& key) {
mConfigReceivers.erase(key);
}
void ConfigManager::SetActiveConfigsChangedReceiver(const int uid,
const sp<IBinder>& intentSender) {
lock_guard<mutex> lock(mMutex);
mActiveConfigsChangedReceivers[uid] = intentSender;
}
void ConfigManager::RemoveActiveConfigsChangedReceiver(const int uid) {
lock_guard<mutex> lock(mMutex);
mActiveConfigsChangedReceivers.erase(uid);
}
void ConfigManager::RemoveConfig(const ConfigKey& key) {
vector<sp<ConfigListener>> broadcastList;
{
@@ -181,6 +192,11 @@ void ConfigManager::RemoveConfigs(int uid) {
mConfigReceivers.erase(*it);
}
auto itActiveConfigsChangedReceiver = mActiveConfigsChangedReceivers.find(uid);
if (itActiveConfigsChangedReceiver != mActiveConfigsChangedReceivers.end()) {
mActiveConfigsChangedReceivers.erase(itActiveConfigsChangedReceiver);
}
mConfigs.erase(uidIt);
for (const sp<ConfigListener>& listener : mListeners) {
@@ -213,6 +229,7 @@ void ConfigManager::RemoveAllConfigs() {
}
mConfigReceivers.clear();
mActiveConfigsChangedReceivers.clear();
for (const sp<ConfigListener>& listener : mListeners) {
broadcastList.push_back(listener);
}
@@ -250,6 +267,17 @@ const sp<android::IBinder> ConfigManager::GetConfigReceiver(const ConfigKey& key
}
}
const sp<android::IBinder> ConfigManager::GetActiveConfigsChangedReceiver(const int uid) const {
lock_guard<mutex> lock(mMutex);
auto it = mActiveConfigsChangedReceivers.find(uid);
if (it == mActiveConfigsChangedReceivers.end()) {
return nullptr;
} else {
return it->second;
}
}
void ConfigManager::Dump(FILE* out) {
lock_guard<mutex> lock(mMutex);

View File

@@ -81,6 +81,23 @@ public:
*/
void RemoveConfigReceiver(const ConfigKey& key);
/**
* Sets the broadcast receiver that is notified whenever the list of active configs
* changes for this uid.
*/
void SetActiveConfigsChangedReceiver(const int uid, const sp<IBinder>& intentSender);
/**
* Returns the broadcast receiver for active configs changed for this uid.
*/
const sp<IBinder> GetActiveConfigsChangedReceiver(const int uid) const;
/**
* Erase any active configs changed broadcast receiver associated with this uid.
*/
void RemoveActiveConfigsChangedReceiver(const int uid);
/**
* A configuration was removed.
*
@@ -129,6 +146,12 @@ private:
*/
std::map<ConfigKey, sp<android::IBinder>> mConfigReceivers;
/**
* Each uid can be subscribed by up to one receiver to notify that the list of active configs
* for this uid has changed. The receiver is specified as IBinder from PendingIntent.
*/
std::map<int, sp<android::IBinder>> mActiveConfigsChangedReceivers;
/**
* The ConfigListeners that will be told about changes.
*/

View File

@@ -73,6 +73,11 @@ public final class StatsManager {
*/
public static final String EXTRA_STATS_DIMENSIONS_VALUE =
"android.app.extra.STATS_DIMENSIONS_VALUE";
/**
* Long array extra of the active configs for the uid that added those configs.
*/
public static final String EXTRA_STATS_ACTIVE_CONFIG_KEYS =
"android.app.extra.STATS_ACTIVE_CONFIG_KEYS";
/**
* Broadcast Action: Statsd has started.
@@ -274,6 +279,43 @@ public final class StatsManager {
}
}
/**
* Registers the operation that is called whenever there is a change in which configs are
* active. This must be called each time statsd starts. This operation allows
* statsd to inform clients that they should pull data of the configs that are currently
* active. The activeConfigsChangedOperation should set periodic alarms to pull data of configs
* that are active and stop pulling data of configs that are no longer active.
*
* @param pendingIntent the PendingIntent to use when broadcasting info to the subscriber
* associated with the given subscriberId. May be null, in which case
* it removes any associated pending intent for this client.
* @throws StatsUnavailableException if unsuccessful due to failing to connect to stats service
*/
@RequiresPermission(allOf = { DUMP, PACKAGE_USAGE_STATS })
public void setActiveConfigsChangedOperation(@Nullable PendingIntent pendingIntent)
throws StatsUnavailableException {
synchronized (this) {
try {
IStatsManager service = getIStatsManagerLocked();
if (pendingIntent == null) {
service.removeActiveConfigsChangedOperation(mContext.getOpPackageName());
} else {
// Extracts IIntentSender from the PendingIntent and turns it into an IBinder.
IBinder intentSender = pendingIntent.getTarget().asBinder();
service.setActiveConfigsChangedOperation(intentSender,
mContext.getOpPackageName());
}
} catch (RemoteException e) {
Slog.e(TAG,
"Failed to connect to statsd when registering active configs listener.");
throw new StatsUnavailableException("could not connect", e);
} catch (SecurityException e) {
throw new StatsUnavailableException(e.getMessage(), e);
}
}
}
// TODO: Temporary for backwards compatibility. Remove.
/**
* @deprecated Use {@link #setFetchReportsOperation(PendingIntent, long)}

View File

@@ -118,6 +118,23 @@ interface IStatsManager {
*/
void removeDataFetchOperation(long configKey, in String packageName);
/**
* Registers the given pending intent for this packagename. This intent is invoked when the
* active status of any of the configs sent by this package changes and will contain a list of
* config ids that are currently active. It also returns the list of configs that are currently
* active. There can be at most one active configs changed listener per package.
*
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
*/
long[] setActiveConfigsChangedOperation(in IBinder intentSender, in String packageName);
/**
* Removes the active configs changed operation for the specified package name.
*
* Requires Manifest.permission.DUMP and Manifest.permission.PACKAGE_USAGE_STATS.
*/
void removeActiveConfigsChangedOperation(in String packageName);
/**
* Removes the configuration with the matching config key. No-op if this config key does not
* exist.