Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 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; |
| 18 | |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 19 | import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; |
| 20 | import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; |
| 21 | |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 22 | import android.content.Context; |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 23 | import android.content.pm.PackageInfo; |
| 24 | import android.content.pm.PackageManager; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 25 | import android.content.pm.PackageManager.NameNotFoundException; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 26 | import android.database.ContentObserver; |
| 27 | import android.net.Uri; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 28 | import android.os.Binder; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 29 | import android.os.Process; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 30 | import android.os.SystemProperties; |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 31 | import android.os.UserHandle; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 32 | import android.provider.Settings; |
Olivier Gaillard | 6f52d15 | 2018-07-25 12:13:12 +0100 | [diff] [blame] | 33 | import android.util.ArrayMap; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 34 | import android.util.ArraySet; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 35 | import android.util.KeyValueListParser; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 36 | import android.util.Slog; |
| 37 | |
Marcin Oczeretko | c4c45a8 | 2018-12-06 15:09:49 +0000 | [diff] [blame] | 38 | import com.android.internal.os.AppIdToPackageMap; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 39 | import com.android.internal.os.BackgroundThread; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 40 | import com.android.internal.os.BinderCallsStats; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 41 | import com.android.internal.os.BinderInternal; |
Marcin Oczeretko | c80c81a | 2018-08-30 20:15:52 +0100 | [diff] [blame] | 42 | import com.android.internal.os.CachedDeviceState; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 43 | |
| 44 | import java.io.FileDescriptor; |
| 45 | import java.io.PrintWriter; |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 46 | import java.util.ArrayList; |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 47 | import java.util.List; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 48 | |
| 49 | public class BinderCallsStatsService extends Binder { |
| 50 | |
| 51 | private static final String TAG = "BinderCallsStatsService"; |
| 52 | |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 53 | private static final String PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING |
| 54 | = "persist.sys.binder_calls_detailed_tracking"; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 55 | |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 56 | /** Resolves the work source of an incoming binder transaction. */ |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 57 | static class AuthorizedWorkSourceProvider implements BinderInternal.WorkSourceProvider { |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 58 | private ArraySet<Integer> mAppIdWhitelist; |
| 59 | |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 60 | AuthorizedWorkSourceProvider() { |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 61 | mAppIdWhitelist = new ArraySet<>(); |
| 62 | } |
| 63 | |
Olivier Gaillard | bab444a | 2019-01-30 17:11:40 +0000 | [diff] [blame] | 64 | public int resolveWorkSourceUid(int untrustedWorkSourceUid) { |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 65 | final int callingUid = getCallingUid(); |
| 66 | final int appId = UserHandle.getAppId(callingUid); |
| 67 | if (mAppIdWhitelist.contains(appId)) { |
Olivier Gaillard | bab444a | 2019-01-30 17:11:40 +0000 | [diff] [blame] | 68 | final int workSource = untrustedWorkSourceUid; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 69 | final boolean isWorkSourceSet = workSource != Binder.UNSET_WORKSOURCE; |
| 70 | return isWorkSourceSet ? workSource : callingUid; |
| 71 | } |
| 72 | return callingUid; |
| 73 | } |
| 74 | |
| 75 | public void systemReady(Context context) { |
| 76 | mAppIdWhitelist = createAppidWhitelist(context); |
| 77 | } |
| 78 | |
Marcin Oczeretko | c4c45a8 | 2018-12-06 15:09:49 +0000 | [diff] [blame] | 79 | public void dump(PrintWriter pw, AppIdToPackageMap packageMap) { |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 80 | pw.println("AppIds of apps that can set the work source:"); |
| 81 | final ArraySet<Integer> whitelist = mAppIdWhitelist; |
| 82 | for (Integer appId : whitelist) { |
Marcin Oczeretko | c4c45a8 | 2018-12-06 15:09:49 +0000 | [diff] [blame] | 83 | pw.println("\t- " + packageMap.mapAppId(appId)); |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 84 | } |
| 85 | } |
| 86 | |
| 87 | protected int getCallingUid() { |
| 88 | return Binder.getCallingUid(); |
| 89 | } |
| 90 | |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 91 | private ArraySet<Integer> createAppidWhitelist(Context context) { |
| 92 | // Use a local copy instead of mAppIdWhitelist to prevent concurrent read access. |
| 93 | final ArraySet<Integer> whitelist = new ArraySet<>(); |
| 94 | |
| 95 | // We trust our own process. |
Olivier Gaillard | 182b4ed | 2018-12-07 11:18:52 +0000 | [diff] [blame] | 96 | whitelist.add(UserHandle.getAppId(Process.myUid())); |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 97 | // We only need to initialize it once. UPDATE_DEVICE_STATS is a system permission. |
| 98 | final PackageManager pm = context.getPackageManager(); |
| 99 | final String[] permissions = { android.Manifest.permission.UPDATE_DEVICE_STATS }; |
| 100 | final int queryFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE; |
| 101 | final List<PackageInfo> packages = |
| 102 | pm.getPackagesHoldingPermissions(permissions, queryFlags); |
| 103 | final int packagesSize = packages.size(); |
| 104 | for (int i = 0; i < packagesSize; i++) { |
| 105 | final PackageInfo pkgInfo = packages.get(i); |
| 106 | try { |
| 107 | final int uid = pm.getPackageUid(pkgInfo.packageName, queryFlags); |
| 108 | final int appId = UserHandle.getAppId(uid); |
| 109 | whitelist.add(appId); |
| 110 | } catch (NameNotFoundException e) { |
| 111 | Slog.e(TAG, "Cannot find uid for package name " + pkgInfo.packageName, e); |
| 112 | } |
| 113 | } |
| 114 | return whitelist; |
| 115 | } |
| 116 | } |
| 117 | |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 118 | /** Listens for flag changes. */ |
| 119 | private static class SettingsObserver extends ContentObserver { |
| 120 | private static final String SETTINGS_ENABLED_KEY = "enabled"; |
| 121 | private static final String SETTINGS_DETAILED_TRACKING_KEY = "detailed_tracking"; |
| 122 | private static final String SETTINGS_UPLOAD_DATA_KEY = "upload_data"; |
| 123 | private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval"; |
Olivier Gaillard | 7949061 | 2018-11-30 16:22:23 +0000 | [diff] [blame] | 124 | private static final String SETTINGS_MAX_CALL_STATS_KEY = "max_call_stats_count"; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 125 | |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 126 | private boolean mEnabled; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 127 | private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS); |
| 128 | private final Context mContext; |
| 129 | private final KeyValueListParser mParser = new KeyValueListParser(','); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 130 | private final BinderCallsStats mBinderCallsStats; |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 131 | private final AuthorizedWorkSourceProvider mWorkSourceProvider; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 132 | |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 133 | SettingsObserver(Context context, BinderCallsStats binderCallsStats, |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 134 | AuthorizedWorkSourceProvider workSourceProvider) { |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 135 | super(BackgroundThread.getHandler()); |
| 136 | mContext = context; |
| 137 | context.getContentResolver().registerContentObserver(mUri, false, this, |
| 138 | UserHandle.USER_SYSTEM); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 139 | mBinderCallsStats = binderCallsStats; |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 140 | mWorkSourceProvider = workSourceProvider; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 141 | // Always kick once to ensure that we match current state |
| 142 | onChange(); |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 143 | } |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 144 | |
| 145 | @Override |
| 146 | public void onChange(boolean selfChange, Uri uri, int userId) { |
| 147 | if (mUri.equals(uri)) { |
| 148 | onChange(); |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | public void onChange() { |
| 153 | // Do not overwrite the default set manually. |
| 154 | if (!SystemProperties.get(PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING).isEmpty()) { |
| 155 | return; |
| 156 | } |
| 157 | |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 158 | try { |
| 159 | mParser.setString(Settings.Global.getString(mContext.getContentResolver(), |
| 160 | Settings.Global.BINDER_CALLS_STATS)); |
| 161 | } catch (IllegalArgumentException e) { |
| 162 | Slog.e(TAG, "Bad binder call stats settings", e); |
| 163 | } |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 164 | mBinderCallsStats.setDetailedTracking(mParser.getBoolean( |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 165 | SETTINGS_DETAILED_TRACKING_KEY, BinderCallsStats.DETAILED_TRACKING_DEFAULT)); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 166 | mBinderCallsStats.setSamplingInterval(mParser.getInt( |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 167 | SETTINGS_SAMPLING_INTERVAL_KEY, |
| 168 | BinderCallsStats.PERIODIC_SAMPLING_INTERVAL_DEFAULT)); |
Olivier Gaillard | 2c9d47a | 2018-12-03 21:49:39 +0000 | [diff] [blame] | 169 | mBinderCallsStats.setMaxBinderCallStats(mParser.getInt( |
Olivier Gaillard | 7949061 | 2018-11-30 16:22:23 +0000 | [diff] [blame] | 170 | SETTINGS_MAX_CALL_STATS_KEY, |
| 171 | BinderCallsStats.MAX_BINDER_CALL_STATS_COUNT_DEFAULT)); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 172 | |
| 173 | |
| 174 | final boolean enabled = |
| 175 | mParser.getBoolean(SETTINGS_ENABLED_KEY, BinderCallsStats.ENABLED_DEFAULT); |
| 176 | if (mEnabled != enabled) { |
Olivier Gaillard | def1b90 | 2018-10-17 17:10:41 +0100 | [diff] [blame] | 177 | if (enabled) { |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 178 | Binder.setObserver(mBinderCallsStats); |
Olivier Gaillard | def1b90 | 2018-10-17 17:10:41 +0100 | [diff] [blame] | 179 | Binder.setProxyTransactListener( |
| 180 | new Binder.PropagateWorkSourceTransactListener()); |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 181 | Binder.setWorkSourceProvider(mWorkSourceProvider); |
Olivier Gaillard | def1b90 | 2018-10-17 17:10:41 +0100 | [diff] [blame] | 182 | } else { |
| 183 | Binder.setObserver(null); |
| 184 | Binder.setProxyTransactListener(null); |
Olivier Gaillard | bab444a | 2019-01-30 17:11:40 +0000 | [diff] [blame] | 185 | Binder.setWorkSourceProvider((x) -> Binder.getCallingUid()); |
Olivier Gaillard | def1b90 | 2018-10-17 17:10:41 +0100 | [diff] [blame] | 186 | } |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 187 | mEnabled = enabled; |
| 188 | mBinderCallsStats.reset(); |
Marcin Oczeretko | 772e8f2 | 2018-11-21 13:00:32 +0000 | [diff] [blame] | 189 | mBinderCallsStats.setAddDebugEntries(enabled); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /** |
| 195 | * @hide Only for use within the system server. |
| 196 | */ |
| 197 | public static class Internal { |
| 198 | private final BinderCallsStats mBinderCallsStats; |
| 199 | |
| 200 | Internal(BinderCallsStats binderCallsStats) { |
| 201 | this.mBinderCallsStats = binderCallsStats; |
| 202 | } |
| 203 | |
Olivier Gaillard | d25f7a8 | 2018-09-12 14:28:48 +0100 | [diff] [blame] | 204 | /** @see BinderCallsStats#reset */ |
| 205 | public void reset() { |
| 206 | mBinderCallsStats.reset(); |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * @see BinderCallsStats#getExportedCallStats. |
| 211 | * |
| 212 | * Note that binder calls stats will be reset by statsd every time |
| 213 | * the data is exported. |
| 214 | */ |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 215 | public ArrayList<BinderCallsStats.ExportedCallStat> getExportedCallStats() { |
| 216 | return mBinderCallsStats.getExportedCallStats(); |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 217 | } |
Olivier Gaillard | 6f52d15 | 2018-07-25 12:13:12 +0100 | [diff] [blame] | 218 | |
Olivier Gaillard | d25f7a8 | 2018-09-12 14:28:48 +0100 | [diff] [blame] | 219 | /** @see BinderCallsStats#getExportedExceptionStats */ |
Olivier Gaillard | 6f52d15 | 2018-07-25 12:13:12 +0100 | [diff] [blame] | 220 | public ArrayMap<String, Integer> getExportedExceptionStats() { |
| 221 | return mBinderCallsStats.getExportedExceptionStats(); |
| 222 | } |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | public static class LifeCycle extends SystemService { |
| 226 | private BinderCallsStatsService mService; |
Olivier Gaillard | 86714d1 | 2018-08-01 15:05:36 +0100 | [diff] [blame] | 227 | private BinderCallsStats mBinderCallsStats; |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 228 | private AuthorizedWorkSourceProvider mWorkSourceProvider; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 229 | |
| 230 | public LifeCycle(Context context) { |
| 231 | super(context); |
| 232 | } |
| 233 | |
| 234 | @Override |
| 235 | public void onStart() { |
Olivier Gaillard | 86714d1 | 2018-08-01 15:05:36 +0100 | [diff] [blame] | 236 | mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector()); |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 237 | mWorkSourceProvider = new AuthorizedWorkSourceProvider(); |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 238 | mService = new BinderCallsStatsService( |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 239 | mBinderCallsStats, mWorkSourceProvider); |
Olivier Gaillard | 86714d1 | 2018-08-01 15:05:36 +0100 | [diff] [blame] | 240 | publishLocalService(Internal.class, new Internal(mBinderCallsStats)); |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 241 | publishBinderService("binder_calls_stats", mService); |
| 242 | boolean detailedTrackingEnabled = SystemProperties.getBoolean( |
| 243 | PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, false); |
| 244 | |
| 245 | if (detailedTrackingEnabled) { |
| 246 | Slog.i(TAG, "Enabled CPU usage tracking for binder calls. Controlled by " |
| 247 | + PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING |
| 248 | + " or via dumpsys binder_calls_stats --enable-detailed-tracking"); |
Olivier Gaillard | 86714d1 | 2018-08-01 15:05:36 +0100 | [diff] [blame] | 249 | mBinderCallsStats.setDetailedTracking(true); |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 250 | } |
| 251 | } |
| 252 | |
| 253 | @Override |
| 254 | public void onBootPhase(int phase) { |
| 255 | if (SystemService.PHASE_SYSTEM_SERVICES_READY == phase) { |
Marcin Oczeretko | c80c81a | 2018-08-30 20:15:52 +0100 | [diff] [blame] | 256 | CachedDeviceState.Readonly deviceState = getLocalService( |
| 257 | CachedDeviceState.Readonly.class); |
Marcin Oczeretko | c80c81a | 2018-08-30 20:15:52 +0100 | [diff] [blame] | 258 | mBinderCallsStats.setDeviceState(deviceState); |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 259 | // It needs to be called before mService.systemReady to make sure the observer is |
| 260 | // initialized before installing it. |
| 261 | mWorkSourceProvider.systemReady(getContext()); |
| 262 | mService.systemReady(getContext()); |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 263 | } |
| 264 | } |
| 265 | } |
| 266 | |
| 267 | private SettingsObserver mSettingsObserver; |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 268 | private final BinderCallsStats mBinderCallsStats; |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 269 | private final AuthorizedWorkSourceProvider mWorkSourceProvider; |
Olivier Gaillard | 1d7f615 | 2018-07-03 13:57:58 +0100 | [diff] [blame] | 270 | |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 271 | BinderCallsStatsService(BinderCallsStats binderCallsStats, |
| 272 | AuthorizedWorkSourceProvider workSourceProvider) { |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 273 | mBinderCallsStats = binderCallsStats; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 274 | mWorkSourceProvider = workSourceProvider; |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 275 | } |
| 276 | |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 277 | public void systemReady(Context context) { |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 278 | mSettingsObserver = new SettingsObserver(context, mBinderCallsStats, mWorkSourceProvider); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 279 | } |
| 280 | |
| 281 | public void reset() { |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 282 | Slog.i(TAG, "Resetting stats"); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 283 | mBinderCallsStats.reset(); |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 284 | } |
| 285 | |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 286 | @Override |
| 287 | protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 288 | boolean verbose = false; |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 289 | if (args != null) { |
| 290 | for (final String arg : args) { |
Fyodor Kupolov | 32a7112 | 2018-04-25 10:41:01 -0700 | [diff] [blame] | 291 | if ("-a".equals(arg)) { |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 292 | verbose = true; |
Fyodor Kupolov | 32a7112 | 2018-04-25 10:41:01 -0700 | [diff] [blame] | 293 | } else if ("--reset".equals(arg)) { |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 294 | reset(); |
| 295 | pw.println("binder_calls_stats reset."); |
| 296 | return; |
Olivier Gaillard | 431cb4c | 2018-09-13 17:06:12 +0100 | [diff] [blame] | 297 | } else if ("--enable".equals(arg)) { |
Olivier Gaillard | 76c231d | 2018-12-05 12:52:08 +0000 | [diff] [blame] | 298 | Binder.setObserver(mBinderCallsStats); |
Olivier Gaillard | 431cb4c | 2018-09-13 17:06:12 +0100 | [diff] [blame] | 299 | return; |
| 300 | } else if ("--disable".equals(arg)) { |
| 301 | Binder.setObserver(null); |
| 302 | return; |
| 303 | } else if ("--no-sampling".equals(arg)) { |
| 304 | mBinderCallsStats.setSamplingInterval(1); |
| 305 | return; |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 306 | } else if ("--enable-detailed-tracking".equals(arg)) { |
| 307 | SystemProperties.set(PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, "1"); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 308 | mBinderCallsStats.setDetailedTracking(true); |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 309 | pw.println("Detailed tracking enabled"); |
| 310 | return; |
| 311 | } else if ("--disable-detailed-tracking".equals(arg)) { |
| 312 | SystemProperties.set(PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, ""); |
Olivier Gaillard | 289ba40 | 2018-07-24 18:50:13 +0100 | [diff] [blame] | 313 | mBinderCallsStats.setDetailedTracking(false); |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 314 | pw.println("Detailed tracking disabled"); |
| 315 | return; |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 316 | } else if ("--dump-worksource-provider".equals(arg)) { |
Marcin Oczeretko | c4c45a8 | 2018-12-06 15:09:49 +0000 | [diff] [blame] | 317 | mWorkSourceProvider.dump(pw, AppIdToPackageMap.getSnapshot()); |
Olivier Gaillard | c17d280 | 2018-11-19 17:08:17 +0000 | [diff] [blame] | 318 | return; |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 319 | } else if ("-h".equals(arg)) { |
| 320 | pw.println("binder_calls_stats commands:"); |
| 321 | pw.println(" --reset: Reset stats"); |
Olivier Gaillard | 431cb4c | 2018-09-13 17:06:12 +0100 | [diff] [blame] | 322 | pw.println(" --enable: Enable tracking binder calls"); |
| 323 | pw.println(" --disable: Disables tracking binder calls"); |
| 324 | pw.println(" --no-sampling: Tracks all calls"); |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 325 | pw.println(" --enable-detailed-tracking: Enables detailed tracking"); |
| 326 | pw.println(" --disable-detailed-tracking: Disables detailed tracking"); |
| 327 | return; |
| 328 | } else { |
| 329 | pw.println("Unknown option: " + arg); |
Fyodor Kupolov | 3f3af61 | 2018-04-18 17:26:43 -0700 | [diff] [blame] | 330 | } |
| 331 | } |
| 332 | } |
Marcin Oczeretko | c4c45a8 | 2018-12-06 15:09:49 +0000 | [diff] [blame] | 333 | mBinderCallsStats.dump(pw, AppIdToPackageMap.getSnapshot(), verbose); |
Fyodor Kupolov | cf0fe2d | 2018-05-22 18:50:04 -0700 | [diff] [blame] | 334 | } |
Fyodor Kupolov | ca34851 | 2018-01-10 18:05:53 -0800 | [diff] [blame] | 335 | } |