Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2020 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.car.watchdog; |
| 18 | |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 19 | import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STARTING; |
| 20 | import static android.car.user.CarUserManager.USER_LIFECYCLE_EVENT_TYPE_STOPPED; |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 21 | |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 22 | import static com.android.car.CarLog.TAG_WATCHDOG; |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 23 | |
| 24 | import android.annotation.NonNull; |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 25 | import android.automotive.watchdog.internal.ICarWatchdogServiceForSystem; |
Lakshman Annadorai | 8dfeeaf | 2020-12-15 14:10:53 -0800 | [diff] [blame] | 26 | import android.automotive.watchdog.internal.PackageInfo; |
Lakshman Annadorai | dd4a4e4 | 2021-02-19 14:22:06 -0800 | [diff] [blame] | 27 | import android.automotive.watchdog.internal.PackageIoOveruseStats; |
Lakshman Annadorai | 967b21e | 2020-10-30 09:35:29 -0700 | [diff] [blame] | 28 | import android.automotive.watchdog.internal.PowerCycle; |
| 29 | import android.automotive.watchdog.internal.StateType; |
| 30 | import android.automotive.watchdog.internal.UserState; |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 31 | import android.car.Car; |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 32 | import android.car.hardware.power.CarPowerManager.CarPowerStateListener; |
| 33 | import android.car.hardware.power.ICarPowerStateListener; |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 34 | import android.car.watchdog.CarWatchdogManager; |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 35 | import android.car.watchdog.ICarWatchdogService; |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 36 | import android.car.watchdog.ICarWatchdogServiceCallback; |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 37 | import android.car.watchdog.IResourceOveruseListener; |
| 38 | import android.car.watchdog.PackageKillableState; |
| 39 | import android.car.watchdog.ResourceOveruseConfiguration; |
| 40 | import android.car.watchdog.ResourceOveruseStats; |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 41 | import android.car.watchdoglib.CarWatchdogDaemonHelper; |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 42 | import android.content.Context; |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 43 | import android.content.pm.UserInfo; |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 44 | import android.os.RemoteException; |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 45 | import android.os.UserHandle; |
| 46 | import android.os.UserManager; |
Lakshman Annadorai | ec4d08a | 2021-04-30 08:29:10 -0700 | [diff] [blame] | 47 | import android.util.ArraySet; |
Felipe Leme | 176a5fd | 2021-01-20 15:48:33 -0800 | [diff] [blame] | 48 | import android.util.IndentingPrintWriter; |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 49 | |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 50 | import com.android.car.CarLocalServices; |
Mayank Garg | 72c71d2 | 2021-02-03 23:54:45 -0800 | [diff] [blame] | 51 | import com.android.car.CarLog; |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 52 | import com.android.car.CarServiceBase; |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 53 | import com.android.car.ICarImpl; |
Eric Jeong | bc351e2 | 2020-07-31 13:54:17 -0700 | [diff] [blame] | 54 | import com.android.car.power.CarPowerManagementService; |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 55 | import com.android.car.user.CarUserService; |
Eric Jeong | 0ee7281 | 2020-04-21 15:23:54 -0700 | [diff] [blame] | 56 | import com.android.internal.annotations.VisibleForTesting; |
Lakshman Annadorai | e17cba7 | 2020-12-17 14:03:36 -0800 | [diff] [blame] | 57 | import com.android.internal.util.ArrayUtils; |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 58 | import com.android.server.utils.Slogf; |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 59 | |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 60 | import java.lang.ref.WeakReference; |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 61 | import java.util.List; |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 62 | |
| 63 | /** |
| 64 | * Service to implement CarWatchdogManager API. |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 65 | */ |
| 66 | public final class CarWatchdogService extends ICarWatchdogService.Stub implements CarServiceBase { |
Lakshman Annadorai | d7b8a03 | 2021-04-20 12:31:05 -0700 | [diff] [blame] | 67 | static final boolean DEBUG = false; // STOPSHIP if true |
| 68 | static final String TAG = CarLog.tagFor(CarWatchdogService.class); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 69 | |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 70 | private final Context mContext; |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 71 | private final ICarWatchdogServiceForSystemImpl mWatchdogServiceForSystem; |
Lakshman Annadorai | 5f1181b | 2021-04-01 16:03:07 -0700 | [diff] [blame] | 72 | private final PackageInfoHandler mPackageInfoHandler; |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 73 | private final WatchdogProcessHandler mWatchdogProcessHandler; |
| 74 | private final WatchdogPerfHandler mWatchdogPerfHandler; |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 75 | private final CarWatchdogDaemonHelper mCarWatchdogDaemonHelper; |
Lakshman Annadorai | 8ee56ec | 2021-04-27 11:51:08 -0700 | [diff] [blame^] | 76 | private final CarWatchdogDaemonHelper.OnConnectionChangeListener mConnectionListener; |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 77 | |
Eric Jeong | 0ee7281 | 2020-04-21 15:23:54 -0700 | [diff] [blame] | 78 | public CarWatchdogService(Context context) { |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 79 | mContext = context; |
Lakshman Annadorai | 5f1181b | 2021-04-01 16:03:07 -0700 | [diff] [blame] | 80 | mPackageInfoHandler = new PackageInfoHandler(mContext.getPackageManager()); |
Eric Jeong | 0ee7281 | 2020-04-21 15:23:54 -0700 | [diff] [blame] | 81 | mCarWatchdogDaemonHelper = new CarWatchdogDaemonHelper(TAG_WATCHDOG); |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 82 | mWatchdogServiceForSystem = new ICarWatchdogServiceForSystemImpl(this); |
Lakshman Annadorai | cf5f3a9 | 2021-04-02 15:26:16 -0700 | [diff] [blame] | 83 | mWatchdogProcessHandler = new WatchdogProcessHandler(mWatchdogServiceForSystem, |
Lakshman Annadorai | d7b8a03 | 2021-04-20 12:31:05 -0700 | [diff] [blame] | 84 | mCarWatchdogDaemonHelper); |
Lakshman Annadorai | cf5f3a9 | 2021-04-02 15:26:16 -0700 | [diff] [blame] | 85 | mWatchdogPerfHandler = new WatchdogPerfHandler(mContext, mCarWatchdogDaemonHelper, |
Lakshman Annadorai | d7b8a03 | 2021-04-20 12:31:05 -0700 | [diff] [blame] | 86 | mPackageInfoHandler); |
Lakshman Annadorai | 8ee56ec | 2021-04-27 11:51:08 -0700 | [diff] [blame^] | 87 | mConnectionListener = (isConnected) -> { |
| 88 | if (isConnected) { |
| 89 | registerToDaemon(); |
| 90 | } |
| 91 | mWatchdogPerfHandler.onDaemonConnectionChange(isConnected); |
| 92 | }; |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | @Override |
| 96 | public void init() { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 97 | mWatchdogProcessHandler.init(); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 98 | subscribePowerCycleChange(); |
| 99 | subscribeUserStateChange(); |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 100 | mCarWatchdogDaemonHelper.addOnConnectionChangeListener(mConnectionListener); |
| 101 | mCarWatchdogDaemonHelper.connect(); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 102 | mWatchdogPerfHandler.init(); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 103 | if (DEBUG) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 104 | Slogf.d(TAG, "CarWatchdogService is initialized"); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 105 | } |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 106 | } |
| 107 | |
| 108 | @Override |
| 109 | public void release() { |
Lakshman Annadorai | cf5f3a9 | 2021-04-02 15:26:16 -0700 | [diff] [blame] | 110 | mWatchdogPerfHandler.release(); |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 111 | unregisterFromDaemon(); |
| 112 | mCarWatchdogDaemonHelper.disconnect(); |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | @Override |
Felipe Leme | 176a5fd | 2021-01-20 15:48:33 -0800 | [diff] [blame] | 116 | public void dump(IndentingPrintWriter writer) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 117 | writer.println("*CarWatchdogService*"); |
| 118 | mWatchdogProcessHandler.dump(writer); |
| 119 | mWatchdogPerfHandler.dump(writer); |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 120 | } |
| 121 | |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 122 | /** |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 123 | * Registers {@link android.car.watchdog.ICarWatchdogServiceCallback} to |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 124 | * {@link CarWatchdogService}. |
| 125 | */ |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 126 | @Override |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 127 | public void registerClient(ICarWatchdogServiceCallback client, int timeout) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 128 | mWatchdogProcessHandler.registerClient(client, timeout); |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 129 | } |
| 130 | |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 131 | /** |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 132 | * Unregisters {@link android.car.watchdog.ICarWatchdogServiceCallback} from |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 133 | * {@link CarWatchdogService}. |
| 134 | */ |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 135 | @Override |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 136 | public void unregisterClient(ICarWatchdogServiceCallback client) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 137 | mWatchdogProcessHandler.unregisterClient(client); |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 138 | } |
| 139 | |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 140 | /** |
| 141 | * Tells {@link CarWatchdogService} that the client is alive. |
| 142 | */ |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 143 | @Override |
Eric Jeong | 4e111e9 | 2020-06-23 19:50:55 -0700 | [diff] [blame] | 144 | public void tellClientAlive(ICarWatchdogServiceCallback client, int sessionId) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 145 | mWatchdogProcessHandler.tellClientAlive(client, sessionId); |
| 146 | } |
| 147 | |
| 148 | @VisibleForTesting |
| 149 | protected int getClientCount(int timeout) { |
| 150 | return mWatchdogProcessHandler.getClientCount(timeout); |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 151 | } |
| 152 | |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 153 | /** Returns {@link android.car.watchdog.ResourceOveruseStats} for the calling package. */ |
| 154 | @Override |
| 155 | @NonNull |
| 156 | public ResourceOveruseStats getResourceOveruseStats( |
| 157 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag, |
| 158 | @CarWatchdogManager.StatsPeriod int maxStatsPeriod) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 159 | return mWatchdogPerfHandler.getResourceOveruseStats(resourceOveruseFlag, maxStatsPeriod); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 160 | } |
| 161 | |
| 162 | /** |
| 163 | * Returns {@link android.car.watchdog.ResourceOveruseStats} for all packages for the maximum |
| 164 | * specified period, and the specified resource types with stats greater than or equal to the |
| 165 | * minimum specified stats. |
| 166 | */ |
| 167 | @Override |
| 168 | @NonNull |
| 169 | public List<ResourceOveruseStats> getAllResourceOveruseStats( |
| 170 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag, |
| 171 | @CarWatchdogManager.MinimumStatsFlag int minimumStatsFlag, |
| 172 | @CarWatchdogManager.StatsPeriod int maxStatsPeriod) { |
| 173 | ICarImpl.assertPermission(mContext, Car.PERMISSION_COLLECT_CAR_WATCHDOG_METRICS); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 174 | return mWatchdogPerfHandler.getAllResourceOveruseStats(resourceOveruseFlag, |
| 175 | minimumStatsFlag, maxStatsPeriod); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | /** Returns {@link android.car.watchdog.ResourceOveruseStats} for the specified user package. */ |
| 179 | @Override |
| 180 | @NonNull |
| 181 | public ResourceOveruseStats getResourceOveruseStatsForUserPackage( |
| 182 | @NonNull String packageName, @NonNull UserHandle userHandle, |
| 183 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag, |
| 184 | @CarWatchdogManager.StatsPeriod int maxStatsPeriod) { |
| 185 | ICarImpl.assertPermission(mContext, Car.PERMISSION_COLLECT_CAR_WATCHDOG_METRICS); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 186 | return mWatchdogPerfHandler.getResourceOveruseStatsForUserPackage(packageName, userHandle, |
| 187 | resourceOveruseFlag, maxStatsPeriod); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 188 | } |
| 189 | |
| 190 | /** |
| 191 | * Adds {@link android.car.watchdog.IResourceOveruseListener} for the calling package's resource |
| 192 | * overuse notifications. |
| 193 | */ |
| 194 | @Override |
| 195 | public void addResourceOveruseListener( |
| 196 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag, |
| 197 | @NonNull IResourceOveruseListener listener) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 198 | mWatchdogPerfHandler.addResourceOveruseListener(resourceOveruseFlag, listener); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 199 | } |
| 200 | |
| 201 | /** |
| 202 | * Removes the previously added {@link android.car.watchdog.IResourceOveruseListener} for the |
| 203 | * calling package's resource overuse notifications. |
| 204 | */ |
| 205 | @Override |
| 206 | public void removeResourceOveruseListener(@NonNull IResourceOveruseListener listener) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 207 | mWatchdogPerfHandler.removeResourceOveruseListener(listener); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 208 | } |
| 209 | |
| 210 | /** |
| 211 | * Adds {@link android.car.watchdog.IResourceOveruseListener} for all packages' resource overuse |
| 212 | * notifications. |
| 213 | */ |
| 214 | @Override |
| 215 | public void addResourceOveruseListenerForSystem( |
| 216 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag, |
| 217 | @NonNull IResourceOveruseListener listener) { |
| 218 | ICarImpl.assertPermission(mContext, Car.PERMISSION_COLLECT_CAR_WATCHDOG_METRICS); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 219 | mWatchdogPerfHandler.addResourceOveruseListenerForSystem(resourceOveruseFlag, listener); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 220 | } |
| 221 | |
| 222 | /** |
| 223 | * Removes the previously added {@link android.car.watchdog.IResourceOveruseListener} for all |
| 224 | * packages' resource overuse notifications. |
| 225 | */ |
| 226 | @Override |
| 227 | public void removeResourceOveruseListenerForSystem(@NonNull IResourceOveruseListener listener) { |
| 228 | ICarImpl.assertPermission(mContext, Car.PERMISSION_COLLECT_CAR_WATCHDOG_METRICS); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 229 | mWatchdogPerfHandler.removeResourceOveruseListenerForSystem(listener); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 230 | } |
| 231 | |
| 232 | /** Sets whether or not a user package is killable on resource overuse. */ |
| 233 | @Override |
| 234 | public void setKillablePackageAsUser(String packageName, UserHandle userHandle, |
| 235 | boolean isKillable) { |
| 236 | ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 237 | mWatchdogPerfHandler.setKillablePackageAsUser(packageName, userHandle, isKillable); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 238 | } |
| 239 | |
| 240 | /** |
| 241 | * Returns all {@link android.car.watchdog.PackageKillableState} on resource overuse for |
| 242 | * the specified user. |
| 243 | */ |
| 244 | @Override |
| 245 | @NonNull |
| 246 | public List<PackageKillableState> getPackageKillableStatesAsUser(UserHandle userHandle) { |
| 247 | ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 248 | return mWatchdogPerfHandler.getPackageKillableStatesAsUser(userHandle); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 249 | } |
| 250 | |
| 251 | /** |
| 252 | * Sets {@link android.car.watchdog.ResourceOveruseConfiguration} for the specified resources. |
| 253 | */ |
| 254 | @Override |
Lakshman Annadorai | 8ee56ec | 2021-04-27 11:51:08 -0700 | [diff] [blame^] | 255 | @CarWatchdogManager.ReturnCode |
| 256 | public int setResourceOveruseConfigurations( |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 257 | List<ResourceOveruseConfiguration> configurations, |
| 258 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) { |
| 259 | ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG); |
Lakshman Annadorai | 8ee56ec | 2021-04-27 11:51:08 -0700 | [diff] [blame^] | 260 | return mWatchdogPerfHandler.setResourceOveruseConfigurations(configurations, |
| 261 | resourceOveruseFlag); |
Lakshman Annadorai | ec1944b | 2021-03-03 16:18:34 -0800 | [diff] [blame] | 262 | } |
| 263 | |
| 264 | /** Returns the available {@link android.car.watchdog.ResourceOveruseConfiguration}. */ |
| 265 | @Override |
| 266 | @NonNull |
| 267 | public List<ResourceOveruseConfiguration> getResourceOveruseConfigurations( |
| 268 | @CarWatchdogManager.ResourceOveruseFlag int resourceOveruseFlag) { |
| 269 | ICarImpl.assertAnyPermission(mContext, Car.PERMISSION_CONTROL_CAR_WATCHDOG_CONFIG, |
| 270 | Car.PERMISSION_COLLECT_CAR_WATCHDOG_METRICS); |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 271 | return mWatchdogPerfHandler.getResourceOveruseConfigurations(resourceOveruseFlag); |
Eric Jeong | 0ee7281 | 2020-04-21 15:23:54 -0700 | [diff] [blame] | 272 | } |
| 273 | |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 274 | private void registerToDaemon() { |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 275 | try { |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 276 | mCarWatchdogDaemonHelper.registerCarWatchdogService(mWatchdogServiceForSystem); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 277 | if (DEBUG) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 278 | Slogf.d(TAG, "CarWatchdogService registers to car watchdog daemon"); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 279 | } |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 280 | } catch (RemoteException | RuntimeException e) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 281 | Slogf.w(TAG, "Cannot register to car watchdog daemon: %s", e); |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 282 | } |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 283 | UserManager userManager = UserManager.get(mContext); |
| 284 | List<UserInfo> users = userManager.getUsers(); |
| 285 | try { |
| 286 | // TODO(b/152780162): reduce the number of RPC calls(isUserRunning). |
| 287 | for (UserInfo info : users) { |
| 288 | int userState = userManager.isUserRunning(info.id) |
| 289 | ? UserState.USER_STATE_STARTED : UserState.USER_STATE_STOPPED; |
| 290 | mCarWatchdogDaemonHelper.notifySystemStateChange(StateType.USER_STATE, info.id, |
| 291 | userState); |
| 292 | if (userState == UserState.USER_STATE_STOPPED) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 293 | mWatchdogProcessHandler.updateUserState(info.id, /*isStopped=*/true); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 294 | } else { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 295 | mWatchdogProcessHandler.updateUserState(info.id, /*isStopped=*/false); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 296 | } |
| 297 | } |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 298 | } catch (RemoteException | RuntimeException e) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 299 | Slogf.w(TAG, "Notifying system state change failed: %s", e); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 300 | } |
Eric Jeong | 6df075f | 2020-03-11 16:12:23 -0700 | [diff] [blame] | 301 | } |
| 302 | |
| 303 | private void unregisterFromDaemon() { |
| 304 | try { |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 305 | mCarWatchdogDaemonHelper.unregisterCarWatchdogService(mWatchdogServiceForSystem); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 306 | if (DEBUG) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 307 | Slogf.d(TAG, "CarWatchdogService unregisters from car watchdog daemon"); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 308 | } |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 309 | } catch (RemoteException | RuntimeException e) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 310 | Slogf.w(TAG, "Cannot unregister from car watchdog daemon: %s", e); |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 311 | } |
| 312 | } |
| 313 | |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 314 | private void subscribePowerCycleChange() { |
| 315 | CarPowerManagementService powerService = |
| 316 | CarLocalServices.getService(CarPowerManagementService.class); |
| 317 | if (powerService == null) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 318 | Slogf.w(TAG, "Cannot get CarPowerManagementService"); |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 319 | return; |
| 320 | } |
| 321 | powerService.registerListener(new ICarPowerStateListener.Stub() { |
| 322 | @Override |
| 323 | public void onStateChanged(int state) { |
| 324 | int powerCycle; |
| 325 | switch (state) { |
| 326 | // SHUTDOWN_PREPARE covers suspend and shutdown. |
| 327 | case CarPowerStateListener.SHUTDOWN_PREPARE: |
| 328 | powerCycle = PowerCycle.POWER_CYCLE_SUSPEND; |
| 329 | break; |
| 330 | // ON covers resume. |
| 331 | case CarPowerStateListener.ON: |
| 332 | powerCycle = PowerCycle.POWER_CYCLE_RESUME; |
| 333 | // There might be outdated & incorrect info. We should reset them before |
| 334 | // starting to do health check. |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 335 | mWatchdogProcessHandler.prepareHealthCheck(); |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 336 | break; |
| 337 | default: |
| 338 | return; |
| 339 | } |
| 340 | try { |
| 341 | mCarWatchdogDaemonHelper.notifySystemStateChange(StateType.POWER_CYCLE, |
| 342 | powerCycle, /* arg2= */ -1); |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 343 | if (DEBUG) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 344 | Slogf.d(TAG, "Notified car watchdog daemon a power cycle(%d)", powerCycle); |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 345 | } |
| 346 | } catch (RemoteException | RuntimeException e) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 347 | Slogf.w(TAG, "Notifying system state change failed: %s", e); |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 348 | } |
Eric Jeong | 27a178f | 2020-03-24 16:39:39 -0700 | [diff] [blame] | 349 | } |
| 350 | }); |
| 351 | } |
| 352 | |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 353 | private void subscribeUserStateChange() { |
| 354 | CarUserService userService = CarLocalServices.getService(CarUserService.class); |
| 355 | if (userService == null) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 356 | Slogf.w(TAG, "Cannot get CarUserService"); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 357 | return; |
| 358 | } |
| 359 | userService.addUserLifecycleListener((event) -> { |
| 360 | int userId = event.getUserHandle().getIdentifier(); |
| 361 | int userState; |
| 362 | String userStateDesc; |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 363 | switch (event.getEventType()) { |
| 364 | case USER_LIFECYCLE_EVENT_TYPE_STARTING: |
| 365 | mWatchdogProcessHandler.updateUserState(userId, /*isStopped=*/false); |
| 366 | userState = UserState.USER_STATE_STARTED; |
| 367 | userStateDesc = "STARTING"; |
| 368 | break; |
| 369 | case USER_LIFECYCLE_EVENT_TYPE_STOPPED: |
| 370 | mWatchdogProcessHandler.updateUserState(userId, /*isStopped=*/true); |
| 371 | userState = UserState.USER_STATE_STOPPED; |
| 372 | userStateDesc = "STOPPING"; |
| 373 | break; |
| 374 | default: |
| 375 | return; |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 376 | } |
| 377 | try { |
| 378 | mCarWatchdogDaemonHelper.notifySystemStateChange(StateType.USER_STATE, userId, |
| 379 | userState); |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 380 | if (DEBUG) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 381 | Slogf.d(TAG, "Notified car watchdog daemon user %d's user state, %s", |
| 382 | userId, userStateDesc); |
Eric Jeong | 4825ca3 | 2020-04-13 18:07:44 -0700 | [diff] [blame] | 383 | } |
| 384 | } catch (RemoteException | RuntimeException e) { |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 385 | Slogf.w(TAG, "Notifying system state change failed: %s", e); |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 386 | } |
Eric Jeong | 01a28aa | 2020-03-27 16:43:19 -0700 | [diff] [blame] | 387 | }); |
| 388 | } |
| 389 | |
Lakshman Annadorai | d26098a | 2020-11-10 14:05:04 -0800 | [diff] [blame] | 390 | private static final class ICarWatchdogServiceForSystemImpl |
| 391 | extends ICarWatchdogServiceForSystem.Stub { |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 392 | private final WeakReference<CarWatchdogService> mService; |
| 393 | |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 394 | ICarWatchdogServiceForSystemImpl(CarWatchdogService service) { |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 395 | mService = new WeakReference<>(service); |
| 396 | } |
| 397 | |
| 398 | @Override |
| 399 | public void checkIfAlive(int sessionId, int timeout) { |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 400 | CarWatchdogService service = mService.get(); |
| 401 | if (service == null) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 402 | Slogf.w(TAG, "CarWatchdogService is not available"); |
Eric Jeong | ae2c04c | 2020-02-21 09:18:31 -0800 | [diff] [blame] | 403 | return; |
| 404 | } |
Lakshman Annadorai | 016127e | 2021-03-18 09:11:43 -0700 | [diff] [blame] | 405 | service.mWatchdogProcessHandler.postHealthCheckMessage(sessionId); |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 406 | } |
Jeongik Cha | 1d04bdd | 2020-04-08 22:19:52 +0900 | [diff] [blame] | 407 | |
| 408 | @Override |
Eric Jeong | 515009b | 2020-04-10 17:23:56 -0700 | [diff] [blame] | 409 | public void prepareProcessTermination() { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 410 | Slogf.w(TAG, "CarWatchdogService is about to be killed by car watchdog daemon"); |
Eric Jeong | 515009b | 2020-04-10 17:23:56 -0700 | [diff] [blame] | 411 | } |
Lakshman Annadorai | 8dfeeaf | 2020-12-15 14:10:53 -0800 | [diff] [blame] | 412 | |
| 413 | @Override |
Lakshman Annadorai | e17cba7 | 2020-12-17 14:03:36 -0800 | [diff] [blame] | 414 | public List<PackageInfo> getPackageInfosForUids( |
| 415 | int[] uids, List<String> vendorPackagePrefixes) { |
| 416 | if (ArrayUtils.isEmpty(uids)) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 417 | Slogf.w(TAG, "UID list is empty"); |
Lakshman Annadorai | e17cba7 | 2020-12-17 14:03:36 -0800 | [diff] [blame] | 418 | return null; |
| 419 | } |
| 420 | CarWatchdogService service = mService.get(); |
| 421 | if (service == null) { |
Lakshman Annadorai | 54e1054 | 2021-03-16 15:36:04 -0700 | [diff] [blame] | 422 | Slogf.w(TAG, "CarWatchdogService is not available"); |
Lakshman Annadorai | e17cba7 | 2020-12-17 14:03:36 -0800 | [diff] [blame] | 423 | return null; |
| 424 | } |
Lakshman Annadorai | 5f1181b | 2021-04-01 16:03:07 -0700 | [diff] [blame] | 425 | return service.mPackageInfoHandler.getPackageInfosForUids(uids, vendorPackagePrefixes); |
Lakshman Annadorai | 8dfeeaf | 2020-12-15 14:10:53 -0800 | [diff] [blame] | 426 | } |
Lakshman Annadorai | dd4a4e4 | 2021-02-19 14:22:06 -0800 | [diff] [blame] | 427 | |
| 428 | @Override |
Lakshman Annadorai | 9ed4732 | 2021-03-11 16:09:28 -0800 | [diff] [blame] | 429 | public void latestIoOveruseStats(List<PackageIoOveruseStats> packageIoOveruseStats) { |
Lakshman Annadorai | cf5f3a9 | 2021-04-02 15:26:16 -0700 | [diff] [blame] | 430 | if (packageIoOveruseStats.isEmpty()) { |
| 431 | Slogf.w(TAG, "Latest I/O overuse stats is empty"); |
| 432 | return; |
| 433 | } |
| 434 | CarWatchdogService service = mService.get(); |
| 435 | if (service == null) { |
| 436 | Slogf.w(TAG, "CarWatchdogService is not available"); |
| 437 | return; |
| 438 | } |
| 439 | service.mWatchdogPerfHandler.latestIoOveruseStats(packageIoOveruseStats); |
Lakshman Annadorai | dd4a4e4 | 2021-02-19 14:22:06 -0800 | [diff] [blame] | 440 | } |
Lakshman Annadorai | ec4d08a | 2021-04-30 08:29:10 -0700 | [diff] [blame] | 441 | |
| 442 | @Override |
| 443 | public void resetResourceOveruseStats(List<String> packageNames) { |
| 444 | if (packageNames.isEmpty()) { |
| 445 | Slogf.w(TAG, "Provided an empty package name to reset resource overuse stats"); |
| 446 | return; |
| 447 | } |
| 448 | CarWatchdogService service = mService.get(); |
| 449 | if (service == null) { |
| 450 | Slogf.w(TAG, "CarWatchdogService is not available"); |
| 451 | return; |
| 452 | } |
| 453 | service.mWatchdogPerfHandler.resetResourceOveruseStats(new ArraySet<>(packageNames)); |
| 454 | } |
Eric Jeong | 0965756 | 2020-03-20 16:02:39 -0700 | [diff] [blame] | 455 | } |
Eric Jeong | 38ae821 | 2020-01-14 10:25:10 -0800 | [diff] [blame] | 456 | } |