1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.uri; 18 19 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; 20 21 import android.app.StatsManager; 22 import android.content.Context; 23 import android.util.SparseArray; 24 import android.util.StatsEvent; 25 26 import com.android.internal.util.FrameworkStatsLog; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.concurrent.TimeUnit; 31 32 final class UriMetricsHelper { 33 34 private static final StatsManager.PullAtomMetadata DAILY_PULL_METADATA = 35 new StatsManager.PullAtomMetadata.Builder() 36 .setCoolDownMillis(TimeUnit.DAYS.toMillis(1)) 37 .build(); 38 39 40 private final Context mContext; 41 private final PersistentUriGrantsProvider mPersistentUriGrantsProvider; 42 UriMetricsHelper(Context context, PersistentUriGrantsProvider provider)43 UriMetricsHelper(Context context, PersistentUriGrantsProvider provider) { 44 mContext = context; 45 mPersistentUriGrantsProvider = provider; 46 } 47 registerPuller()48 void registerPuller() { 49 final StatsManager statsManager = mContext.getSystemService(StatsManager.class); 50 statsManager.setPullAtomCallback( 51 FrameworkStatsLog.PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE, 52 DAILY_PULL_METADATA, 53 DIRECT_EXECUTOR, 54 (atomTag, data) -> { 55 reportPersistentUriPermissionsPerPackage(data); 56 return StatsManager.PULL_SUCCESS; 57 }); 58 } 59 reportPersistentUriFlushed(int amount)60 void reportPersistentUriFlushed(int amount) { 61 FrameworkStatsLog.write( 62 FrameworkStatsLog.PERSISTENT_URI_PERMISSIONS_FLUSHED, 63 amount 64 ); 65 } 66 reportPersistentUriPermissionsPerPackage(List<StatsEvent> data)67 private void reportPersistentUriPermissionsPerPackage(List<StatsEvent> data) { 68 final ArrayList<UriPermission> persistentUriGrants = 69 mPersistentUriGrantsProvider.providePersistentUriGrants(); 70 71 final SparseArray<Integer> perUidCount = new SparseArray<>(); 72 73 final int persistentUriGrantsSize = persistentUriGrants.size(); 74 for (int i = 0; i < persistentUriGrantsSize; i++) { 75 final UriPermission uriPermission = persistentUriGrants.get(i); 76 77 perUidCount.put( 78 uriPermission.targetUid, 79 perUidCount.get(uriPermission.targetUid, 0) + 1 80 ); 81 } 82 83 final int perUidCountSize = perUidCount.size(); 84 for (int i = 0; i < perUidCountSize; i++) { 85 final int uid = perUidCount.keyAt(i); 86 final int amount = perUidCount.valueAt(i); 87 88 data.add( 89 FrameworkStatsLog.buildStatsEvent( 90 FrameworkStatsLog.PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE, 91 uid, 92 amount 93 ) 94 ); 95 } 96 } 97 98 interface PersistentUriGrantsProvider { providePersistentUriGrants()99 ArrayList<UriPermission> providePersistentUriGrants(); 100 } 101 } 102