Pull all current role holders into statsd

Create a new atom RoleHolder that maps a uid -> role and add the
mappings that currently exist in RoleManagerService

Test: - ./out/host/linux-x86/bin/statsd_testdrive 10049
      - adb shell cmd stats pull-source 10049
Bug: 123594188
Change-Id: Ib0fa60b07a95c06a219f3e3b37d51f59b624a017
This commit is contained in:
Philip P. Moltmann
2019-01-29 16:24:19 -08:00
parent 48518f4345
commit 70b42ae8ee
6 changed files with 164 additions and 11 deletions

View File

@@ -269,6 +269,7 @@ message Atom {
DebugElapsedClock debug_elapsed_clock = 10046;
DebugFailingElapsedClock debug_failing_elapsed_clock = 10047;
NumBiometricsEnrolled num_faces_enrolled = 10048;
RoleHolder role_holder = 10049;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -3420,6 +3421,20 @@ message NumBiometricsEnrolled {
optional int32 num_enrolled = 2;
}
/**
* A mapping of role holder -> role
*/
message RoleHolder {
// uid of the role holder
optional int32 uid = 1 [(is_uid) = true];
// package name of the role holder
optional string package_name = 2;
// the role held
optional string role = 3;
}
message AggStats {
optional int64 min = 1;

View File

@@ -220,6 +220,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// BuildInformation.
{android::util::BUILD_INFORMATION,
{.puller = new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}},
// RoleHolder.
{android::util::ROLE_HOLDER,
{.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {

View File

@@ -52,6 +52,7 @@ import android.os.UserManagerInternal;
import android.service.sms.FinancialSmsService;
import android.telephony.IFinancialSmsCallback;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.PackageUtils;
import android.util.Slog;
@@ -145,6 +146,9 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
LocalServices.addService(RoleManagerServiceInternal.class,
new RoleManagerServiceInternalImpl());
registerUserRemovedReceiver();
}
@@ -381,6 +385,19 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
}
/**
* Get all roles and packages hold them.
*
* @param user The user to query to roles for
*
* @return The roles and their holders
*/
@NonNull
private ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
RoleUserState userState = getOrCreateUserState(user.getIdentifier());
return userState.getRoleHolders();
}
private class Stub extends IRoleManager.Stub {
@Override
@@ -675,4 +692,16 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
}
}
/**
* Entry point for internal calls into role manager
*/
private final class RoleManagerServiceInternalImpl extends RoleManagerServiceInternal {
@NonNull
@Override
public ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
return RoleManagerService.this.getRoleHoldersAsUser(user);
}
}
}

View 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.
*/
package com.android.server.role;
import android.annotation.NonNull;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
/**
* Internal calls into {@link RoleManagerService}
*/
public abstract class RoleManagerServiceInternal {
/**
* Get all roles and packages hold them.
*
* @param user The user to query to roles for
*
* @return The roles and their holders
*/
@NonNull
public abstract ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(
@NonNull UserHandle user);
}

View File

@@ -376,7 +376,7 @@ public class RoleUserState {
version = mVersion;
packagesHash = mPackagesHash;
roles = snapshotRolesLocked();
roles = getRoleHolders();
}
AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
@@ -541,7 +541,7 @@ public class RoleUserState {
version = mVersion;
packagesHash = mPackagesHash;
roles = snapshotRolesLocked();
roles = getRoleHolders();
}
long fieldToken = dumpOutputStream.start(fieldName, fieldId);
@@ -570,17 +570,24 @@ public class RoleUserState {
dumpOutputStream.end(fieldToken);
}
@GuardedBy("mLock")
private ArrayMap<String, ArraySet<String>> snapshotRolesLocked() {
ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
String roleName = mRoles.keyAt(i);
ArraySet<String> roleHolders = mRoles.valueAt(i);
/**
* Get the roles and their holders.
*
* @return A copy of the roles and their holders
*/
@NonNull
public ArrayMap<String, ArraySet<String>> getRoleHolders() {
synchronized (mLock) {
ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
String roleName = mRoles.keyAt(i);
ArraySet<String> roleHolders = mRoles.valueAt(i);
roleHolders = new ArraySet<>(roleHolders);
roles.put(roleName, roleHolders);
roleHolders = new ArraySet<>(roleHolders);
roles.put(roleName, roleHolders);
}
return roles;
}
return roles;
}
/**

View File

@@ -23,6 +23,7 @@ import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
@@ -83,6 +84,7 @@ import android.os.storage.StorageManager;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.StatsLog;
@@ -112,6 +114,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.am.MemoryStatUtil.MemoryStat;
import com.android.server.role.RoleManagerServiceInternal;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -1780,6 +1783,60 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pulledData.add(e);
}
/**
* Add a RoleHolder atom for each package that holds a role.
*
* @param elapsedNanos the time since boot
* @param wallClockNanos the time on the clock
* @param pulledData the data sink to write to
*/
private void pullRoleHolders(long elapsedNanos, final long wallClockNanos,
@NonNull List<StatsLogEventWrapper> pulledData) {
long callingToken = Binder.clearCallingIdentity();
try {
PackageManager pm = mContext.getPackageManager();
RoleManagerServiceInternal rm =
LocalServices.getService(RoleManagerServiceInternal.class);
List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
int numUsers = users.size();
for (int userNum = 0; userNum < numUsers; userNum++) {
UserHandle user = users.get(userNum).getUserHandle();
ArrayMap<String, ArraySet<String>> roles = rm.getRoleHoldersAsUser(user);
int numRoles = roles.size();
for (int roleNum = 0; roleNum < numRoles; roleNum++) {
String roleName = roles.keyAt(roleNum);
ArraySet<String> holders = roles.valueAt(roleNum);
int numHolders = holders.size();
for (int holderNum = 0; holderNum < numHolders; holderNum++) {
String holderName = holders.valueAt(holderNum);
PackageInfo pkg;
try {
pkg = pm.getPackageInfoAsUser(holderName, 0, user.getIdentifier());
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Role holder " + holderName + " not found");
return;
}
StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER,
elapsedNanos, wallClockNanos);
e.writeInt(pkg.applicationInfo.uid);
e.writeString(holderName);
e.writeString(roleName);
pulledData.add(e);
}
}
}
} finally {
Binder.restoreCallingIdentity(callingToken);
}
}
/**
* Pulls various data.
*/
@@ -1954,6 +2011,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullDebugFailingElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
case StatsLog.ROLE_HOLDER: {
pullRoleHolders(elapsedNanos, wallClockNanos, ret);
break;
}
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;