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