diff options
| author | 2020-02-24 17:37:45 +0000 | |
|---|---|---|
| committer | 2020-02-24 17:37:45 +0000 | |
| commit | fd2f367df6f6e351ef5660511946d7bd7e6c3e8a (patch) | |
| tree | 679fbf03d7313a7ecc0931931dbf92e3f55edf2a | |
| parent | 9fa3a870c63be5e884f25c4d3764c2956891c2f9 (diff) | |
| parent | 7dcc51dc796f24156112b4aeaa134721eb534872 (diff) | |
Merge "Add atom and puller for AppOps with FeatureIds" into rvc-dev
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 48 | ||||
| -rw-r--r-- | services/core/java/com/android/server/stats/pull/StatsPullAtomService.java | 83 |
2 files changed, 128 insertions, 3 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index 1b0e51e28b59..257554207ef5 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -397,7 +397,7 @@ message Atom { } // Pulled events will start at field 10000. - // Next: 10075 + // Next: 10076 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"]; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"]; @@ -479,6 +479,7 @@ message Atom { PackageNotificationChannelGroupPreferences package_notification_channel_group_preferences = 10073 [(module) = "framework"]; GnssStats gnss_stats = 10074 [(module) = "framework"]; + AppFeaturesOps app_features_ops = 10075 [(module) = "framework"]; } // DO NOT USE field numbers above 100,000 in AOSP. @@ -7548,6 +7549,51 @@ message AppOps { } /** + * Historical app ops data per package and features. + */ +message AppFeaturesOps { + // Uid of the package requesting the op + optional int32 uid = 1 [(is_uid) = true]; + + // Name of the package performing the op + optional string package_name = 2; + + // feature id; provided by developer when accessing related API, limited at 50 chars by API. + // Features must be provided through manifest using <feature> tag available in R and above. + optional string feature_id = 3; + + // operation id; maps to the OPSTR_* constants in AppOpsManager.java + optional string op = 4; + + // The number of times the op was granted while the app was in the + // foreground (only for trusted requests) + optional int64 trusted_foreground_granted_count = 5; + + // The number of times the op was granted while the app was in the + // background (only for trusted requests) + optional int64 trusted_background_granted_count = 6; + + // The number of times the op was rejected while the app was in the + // foreground (only for trusted requests) + optional int64 trusted_foreground_rejected_count = 7; + + // The number of times the op was rejected while the app was in the + // background (only for trusted requests) + optional int64 trusted_background_rejected_count = 8; + + // For long-running operations, total duration of the operation + // while the app was in the foreground (only for trusted requests) + optional int64 trusted_foreground_duration_millis = 9; + + // For long-running operations, total duration of the operation + // while the app was in the background (only for trusted requests) + optional int64 trusted_background_duration_millis = 10; + + // Whether AppOps is guarded by Runtime permission + optional bool is_runtime_permission = 11; +} + +/** * Location Manager API Usage information(e.g. API under usage, * API call's parameters). * Logged from: diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index aed2d9bb9dc7..3c8ef6c832a3 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -395,6 +395,8 @@ public class StatsPullAtomService extends SystemService { case FrameworkStatsLog.BATTERY_VOLTAGE: case FrameworkStatsLog.BATTERY_CYCLE_COUNT: return pullHealthHal(atomTag, data); + case FrameworkStatsLog.APP_FEATURES_OPS: + return pullAppFeaturesOps(atomTag, data); default: throw new UnsupportedOperationException("Unknown tagId=" + atomTag); } @@ -550,6 +552,7 @@ public class StatsPullAtomService extends SystemService { registerAppsOnExternalStorageInfo(); registerFaceSettings(); registerAppOps(); + registerAppFeaturesOps(); registerRuntimeAppOpAccessMessage(); registerNotificationRemoteViews(); registerDangerousPermissionState(); @@ -2843,7 +2846,6 @@ public class StatsPullAtomService extends SystemService { BackgroundThread.getExecutor(), mStatsCallbackImpl ); - } private void registerRuntimeAppOpAccessMessage() { @@ -2854,7 +2856,6 @@ public class StatsPullAtomService extends SystemService { BackgroundThread.getExecutor(), mStatsCallbackImpl ); - } int pullAppOps(int atomTag, List<StatsEvent> pulledData) { @@ -2917,6 +2918,84 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } + private void registerAppFeaturesOps() { + int tagId = FrameworkStatsLog.APP_FEATURES_OPS; + mStatsManager.registerPullAtomCallback( + tagId, + null, // use default PullAtomMetadata values + BackgroundThread.getExecutor(), + mStatsCallbackImpl + ); + } + + int pullAppFeaturesOps(int atomTag, List<StatsEvent> pulledData) { + final long token = Binder.clearCallingIdentity(); + try { + AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class); + + CompletableFuture<HistoricalOps> ops = new CompletableFuture<>(); + HistoricalOpsRequest histOpsRequest = + new HistoricalOpsRequest.Builder(0, Long.MAX_VALUE).setFlags( + OP_FLAGS_PULLED).build(); + appOps.getHistoricalOps(histOpsRequest, mContext.getMainExecutor(), ops::complete); + + HistoricalOps histOps = ops.get(EXTERNAL_STATS_SYNC_TIMEOUT_MILLIS, + TimeUnit.MILLISECONDS); + + for (int uidIdx = 0; uidIdx < histOps.getUidCount(); uidIdx++) { + final HistoricalUidOps uidOps = histOps.getUidOpsAt(uidIdx); + final int uid = uidOps.getUid(); + for (int pkgIdx = 0; pkgIdx < uidOps.getPackageCount(); pkgIdx++) { + final HistoricalPackageOps packageOps = uidOps.getPackageOpsAt(pkgIdx); + for (int featureIdx = 0; featureIdx < packageOps.getFeatureCount(); + featureIdx++) { + final AppOpsManager.HistoricalFeatureOps featureOps = + packageOps.getFeatureOpsAt(featureIdx); + for (int opIdx = 0; opIdx < featureOps.getOpCount(); opIdx++) { + final AppOpsManager.HistoricalOp op = featureOps.getOpAt(opIdx); + StatsEvent.Builder e = StatsEvent.newBuilder(); + e.setAtomId(atomTag); + e.writeInt(uid); + e.writeString(packageOps.getPackageName()); + e.writeString(featureOps.getFeatureId()); + e.writeString(op.getOpName()); + e.writeLong(op.getForegroundAccessCount(OP_FLAGS_PULLED)); + e.writeLong(op.getBackgroundAccessCount(OP_FLAGS_PULLED)); + e.writeLong(op.getForegroundRejectCount(OP_FLAGS_PULLED)); + e.writeLong(op.getBackgroundRejectCount(OP_FLAGS_PULLED)); + e.writeLong(op.getForegroundAccessDuration(OP_FLAGS_PULLED)); + e.writeLong(op.getBackgroundAccessDuration(OP_FLAGS_PULLED)); + + String perm = AppOpsManager.opToPermission(op.getOpCode()); + if (perm == null) { + e.writeBoolean(false); + } else { + PermissionInfo permInfo; + try { + permInfo = mContext.getPackageManager().getPermissionInfo(perm, + 0); + e.writeBoolean( + permInfo.getProtection() == PROTECTION_DANGEROUS); + } catch (PackageManager.NameNotFoundException exception) { + e.writeBoolean(false); + } + } + pulledData.add(e.build()); + } + + } + } + } + } catch (Throwable t) { + // TODO: catch exceptions at a more granular level + Slog.e(TAG, "Could not read appops", t); + return StatsManager.PULL_SKIP; + } finally { + Binder.restoreCallingIdentity(token); + } + return StatsManager.PULL_SUCCESS; + } + int pullRuntimeAppOpAccessMessage(int atomTag, List<StatsEvent> pulledData) { final long token = Binder.clearCallingIdentity(); try { |