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