• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 android.os;
18 
19 import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
20 import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
21 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
22 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT;
23 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI;
24 import static android.app.ActivityManager.PROCESS_STATE_TOP;
25 
26 import android.annotation.IntDef;
27 import android.annotation.NonNull;
28 import android.annotation.Nullable;
29 import android.annotation.RequiresPermission;
30 import android.annotation.SystemApi;
31 import android.annotation.SystemService;
32 import android.annotation.UserHandleAware;
33 import android.content.Context;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.Collections;
38 import java.util.List;
39 
40 /**
41  * Interface to access and modify the permanent and temporary power save allow list. The two lists
42  * are kept separately. Apps placed on the permanent allow list are only removed via an explicit
43  * {@link #removeFromPermanentAllowList(String)} call. Apps allow-listed by default by the system
44  * cannot be removed. Apps placed on the temporary allow list are removed from that allow list after
45  * a predetermined amount of time.
46  *
47  * @hide
48  */
49 @SystemApi
50 @SystemService(Context.POWER_EXEMPTION_SERVICE)
51 public class PowerExemptionManager {
52     private final Context mContext;
53     // Proxy to DeviceIdleController for now
54     // TODO: migrate to PowerExemptionController
55     private final IDeviceIdleController mService;
56 
57     /**
58      * Indicates that an unforeseen event has occurred and the app should be allow-listed to handle
59      * it.
60      */
61     public static final int EVENT_UNSPECIFIED = 0;
62 
63     /**
64      * Indicates that an SMS event has occurred and the app should be allow-listed to handle it.
65      */
66     public static final int EVENT_SMS = 1;
67 
68     /**
69      * Indicates that an MMS event has occurred and the app should be allow-listed to handle it.
70      */
71     public static final int EVENT_MMS = 2;
72 
73     /**
74      * @hide
75      */
76     @Retention(RetentionPolicy.SOURCE)
77     @IntDef(prefix = {"EVENT_"}, value = {
78             EVENT_UNSPECIFIED,
79             EVENT_SMS,
80             EVENT_MMS,
81     })
82     public @interface AllowListEvent {
83     }
84 
85     /**
86      * Does not place the app on any temporary allow list. Nullifies the previous call to
87      * {@link android.app.BroadcastOptions#setTemporaryAppAllowlist(long, int, int, String)}.
88      * Note: this will not remove the receiver app from the temp allow list.
89      */
90     public static final int TEMPORARY_ALLOW_LIST_TYPE_NONE = -1;
91     /**
92      * Allow the temp allow list behavior, plus allow foreground service start from background.
93      */
94     public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0;
95     /**
96      * Only allow the temp allow list behavior, not allow foreground service start from background.
97      */
98     public static final int TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1;
99 
100     /**
101      * The list of temp allow list types.
102      * @hide
103      */
104     @IntDef(flag = true, prefix = { "TEMPORARY_ALLOW_LIST_TYPE_" }, value = {
105             TEMPORARY_ALLOW_LIST_TYPE_NONE,
106             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
107             TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED,
108     })
109     @Retention(RetentionPolicy.SOURCE)
110     public @interface TempAllowListType {}
111 
112     /* Reason codes for BG-FGS-launch. */
113     /**
114      * BG-FGS-launch is denied.
115      * @hide
116      */
117     public static final int REASON_DENIED = -1;
118 
119     /* Reason code range 0-9 are reserved for default reasons */
120     /**
121      * The default reason code if reason is unknown.
122      */
123     public static final int REASON_UNKNOWN = 0;
124     /**
125      * Use REASON_OTHER if there is no better choice.
126      */
127     public static final int REASON_OTHER = 1;
128 
129     /* Reason code range 10-49 are reserved for BG-FGS-launch allowed proc states */
130     /** @hide */
131     public static final int REASON_PROC_STATE_PERSISTENT = 10;
132     /** @hide */
133     public static final int REASON_PROC_STATE_PERSISTENT_UI = 11;
134     /** @hide */
135     public static final int REASON_PROC_STATE_TOP = 12;
136     /** @hide */
137     public static final int REASON_PROC_STATE_BTOP = 13;
138     /** @hide */
139     public static final int REASON_PROC_STATE_FGS = 14;
140     /** @hide */
141     public static final int REASON_PROC_STATE_BFGS = 15;
142 
143     /* Reason code range 50-99 are reserved for BG-FGS-launch allowed reasons */
144     /** @hide */
145     public static final int REASON_UID_VISIBLE = 50;
146     /** @hide */
147     public static final int REASON_SYSTEM_UID = 51;
148     /** @hide */
149     public static final int REASON_ACTIVITY_STARTER = 52;
150     /** @hide */
151     public static final int REASON_START_ACTIVITY_FLAG = 53;
152     /** @hide */
153     public static final int REASON_FGS_BINDING = 54;
154     /** @hide */
155     public static final int REASON_DEVICE_OWNER = 55;
156     /** @hide */
157     public static final int REASON_PROFILE_OWNER = 56;
158     /** @hide */
159     public static final int REASON_COMPANION_DEVICE_MANAGER = 57;
160     /**
161      * START_ACTIVITIES_FROM_BACKGROUND permission.
162      * @hide
163      */
164     public static final int REASON_BACKGROUND_ACTIVITY_PERMISSION = 58;
165     /**
166      * START_FOREGROUND_SERVICES_FROM_BACKGROUND permission.
167      * @hide
168      */
169     public static final int REASON_BACKGROUND_FGS_PERMISSION = 59;
170     /** @hide */
171     public static final int REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60;
172     /** @hide */
173     public static final int REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61;
174     /** @hide */
175     public static final int REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62;
176     /** @hide */
177     public static final int REASON_DEVICE_DEMO_MODE = 63;
178     /** @hide */
179     public static final int REASON_ALLOWLISTED_PACKAGE = 65;
180     /** @hide */
181     public static final int REASON_APPOP = 66;
182     /** @hide */
183     public static final int REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD = 67;
184     /** @hide */
185     public static final int REASON_OP_ACTIVATE_VPN = 68;
186     /** @hide */
187     public static final int REASON_OP_ACTIVATE_PLATFORM_VPN = 69;
188     /**
189      * Temporarily allowed to have FGS while-in-use permissions.
190      * @hide
191      */
192     public static final int REASON_TEMP_ALLOWED_WHILE_IN_USE = 70;
193     /** @hide */
194     public static final int REASON_CURRENT_INPUT_METHOD = 71;
195 
196     /* BG-FGS-launch is allowed by temp-allow-list or system-allow-list.
197        Reason code for temp and system allow list starts here.
198        Reason code range 100-199 are reserved for public reasons. */
199     /**
200      * Set temp-allow-list for location geofence purpose.
201      */
202     public static final int REASON_GEOFENCING = 100;
203     /**
204      * Set temp-allow-list for server push messaging.
205      */
206     public static final int REASON_PUSH_MESSAGING = 101;
207     /**
208      * Set temp-allow-list for server push messaging over the quota.
209      */
210     public static final int REASON_PUSH_MESSAGING_OVER_QUOTA = 102;
211     /**
212      * Set temp-allow-list for activity recognition.
213      */
214     public static final int REASON_ACTIVITY_RECOGNITION = 103;
215     /**
216      * Set temp-allow-list for transferring accounts between users.
217      */
218     public static final int REASON_ACCOUNT_TRANSFER = 104;
219 
220     /* Reason code range 200-299 are reserved for broadcast actions */
221     /**
222      * Broadcast ACTION_BOOT_COMPLETED.
223      * @hide
224      */
225     public static final int REASON_BOOT_COMPLETED = 200;
226     /**
227      * Broadcast ACTION_PRE_BOOT_COMPLETED.
228      * @hide
229      */
230     public static final int REASON_PRE_BOOT_COMPLETED = 201;
231     /**
232      * Broadcast ACTION_LOCKED_BOOT_COMPLETED.
233      * @hide
234      */
235     public static final int REASON_LOCKED_BOOT_COMPLETED = 202;
236     /**
237      * All Bluetooth broadcasts.
238      * @hide
239      */
240     public static final int REASON_BLUETOOTH_BROADCAST = 203;
241     /**
242      * Broadcast {@link android.content.Intent#ACTION_TIMEZONE_CHANGED}
243      * @hide
244      */
245     public static final int REASON_TIMEZONE_CHANGED = 204;
246     /**
247      * Broadcast {@link android.content.Intent#ACTION_TIME_CHANGED}
248      * @hide
249      */
250     public static final int REASON_TIME_CHANGED = 205;
251     /**
252      * Broadcast {@link android.content.Intent#ACTION_LOCALE_CHANGED}
253      * @hide
254      */
255     public static final int REASON_LOCALE_CHANGED = 206;
256     /**
257      * Broadcast
258      * {@link android.app.AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED}
259      * @hide
260      */
261     public static final int REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = 207;
262     /* Reason code range 300-399 are reserved for other internal reasons */
263     /**
264      * Device idle system allow list, including EXCEPT-IDLE
265      * @hide
266      */
267     public static final int REASON_SYSTEM_ALLOW_LISTED = 300;
268     /** @hide */
269     public static final int REASON_ALARM_MANAGER_ALARM_CLOCK = 301;
270     /**
271      * AlarmManagerService.
272      * @hide
273      */
274     public static final int REASON_ALARM_MANAGER_WHILE_IDLE = 302;
275     /**
276      * ActiveServices.
277      * @hide
278      */
279     public static final int REASON_SERVICE_LAUNCH = 303;
280     /**
281      * KeyChainSystemService.
282      * @hide
283      */
284     public static final int REASON_KEY_CHAIN = 304;
285     /**
286      * PackageManagerService.
287      * @hide
288      */
289     public static final int REASON_PACKAGE_VERIFIER = 305;
290     /**
291      * SyncManager.
292      * @hide
293      */
294     public static final int REASON_SYNC_MANAGER = 306;
295     /**
296      * DomainVerificationProxyV1.
297      * @hide
298      */
299     public static final int REASON_DOMAIN_VERIFICATION_V1 = 307;
300     /**
301      * DomainVerificationProxyV2.
302      * @hide
303      */
304     public static final int REASON_DOMAIN_VERIFICATION_V2 = 308;
305     /** @hide */
306     public static final int REASON_VPN = 309;
307     /**
308      * NotificationManagerService.
309      * @hide
310      */
311     public static final int REASON_NOTIFICATION_SERVICE = 310;
312     /**
313      * Broadcast ACTION_MY_PACKAGE_REPLACED.
314      * @hide
315      */
316     public static final int REASON_PACKAGE_REPLACED = 311;
317     /**
318      * LocationProvider.
319      * @hide
320      */
321     @SystemApi
322     public static final int REASON_LOCATION_PROVIDER = 312;
323     /**
324      * MediaButtonReceiver.
325      * @hide
326      */
327     public static final int REASON_MEDIA_BUTTON = 313;
328     /**
329      * InboundSmsHandler.
330      * @hide
331      */
332     public static final int REASON_EVENT_SMS = 314;
333     /**
334      * InboundSmsHandler.
335      * @hide
336      */
337     public static final int REASON_EVENT_MMS = 315;
338     /**
339      * Shell app.
340      * @hide
341      */
342     public static final int REASON_SHELL = 316;
343     /**
344      * Media session callbacks.
345      * @hide
346      */
347     public static final int REASON_MEDIA_SESSION_CALLBACK = 317;
348 
349     /** @hide The app requests out-out. */
350     public static final int REASON_OPT_OUT_REQUESTED = 1000;
351 
352     /**
353      * The list of BG-FGS-Launch and temp-allow-list reason code.
354      * @hide
355      */
356     @IntDef(flag = true, prefix = { "REASON_" }, value = {
357             // BG-FGS-Launch reasons.
358             REASON_DENIED,
359             REASON_UNKNOWN,
360             REASON_OTHER,
361             REASON_PROC_STATE_PERSISTENT,
362             REASON_PROC_STATE_PERSISTENT_UI,
363             REASON_PROC_STATE_TOP,
364             REASON_PROC_STATE_BTOP,
365             REASON_PROC_STATE_FGS,
366             REASON_PROC_STATE_BFGS,
367             REASON_UID_VISIBLE,
368             REASON_SYSTEM_UID,
369             REASON_ACTIVITY_STARTER,
370             REASON_START_ACTIVITY_FLAG,
371             REASON_FGS_BINDING,
372             REASON_DEVICE_OWNER,
373             REASON_PROFILE_OWNER,
374             REASON_COMPANION_DEVICE_MANAGER,
375             REASON_BACKGROUND_ACTIVITY_PERMISSION,
376             REASON_BACKGROUND_FGS_PERMISSION,
377             REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION,
378             REASON_INSTR_BACKGROUND_FGS_PERMISSION,
379             REASON_SYSTEM_ALERT_WINDOW_PERMISSION,
380             REASON_DEVICE_DEMO_MODE,
381             REASON_ALLOWLISTED_PACKAGE,
382             REASON_APPOP,
383             REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD,
384             REASON_OP_ACTIVATE_VPN,
385             REASON_OP_ACTIVATE_PLATFORM_VPN,
386             REASON_CURRENT_INPUT_METHOD,
387             REASON_TEMP_ALLOWED_WHILE_IN_USE,
388             // temp and system allow list reasons.
389             REASON_GEOFENCING,
390             REASON_PUSH_MESSAGING,
391             REASON_PUSH_MESSAGING_OVER_QUOTA,
392             REASON_ACTIVITY_RECOGNITION,
393             REASON_ACCOUNT_TRANSFER,
394             REASON_BOOT_COMPLETED,
395             REASON_PRE_BOOT_COMPLETED,
396             REASON_LOCKED_BOOT_COMPLETED,
397             REASON_BLUETOOTH_BROADCAST,
398             REASON_TIMEZONE_CHANGED,
399             REASON_TIME_CHANGED,
400             REASON_LOCALE_CHANGED,
401             REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
402             REASON_SYSTEM_ALLOW_LISTED,
403             REASON_ALARM_MANAGER_ALARM_CLOCK,
404             REASON_ALARM_MANAGER_WHILE_IDLE,
405             REASON_SERVICE_LAUNCH,
406             REASON_KEY_CHAIN,
407             REASON_PACKAGE_VERIFIER,
408             REASON_SYNC_MANAGER,
409             REASON_DOMAIN_VERIFICATION_V1,
410             REASON_DOMAIN_VERIFICATION_V2,
411             REASON_VPN,
412             REASON_NOTIFICATION_SERVICE,
413             REASON_PACKAGE_REPLACED,
414             REASON_LOCATION_PROVIDER,
415             REASON_MEDIA_BUTTON,
416             REASON_EVENT_SMS,
417             REASON_EVENT_MMS,
418             REASON_SHELL,
419             REASON_MEDIA_SESSION_CALLBACK,
420             REASON_OPT_OUT_REQUESTED,
421     })
422     @Retention(RetentionPolicy.SOURCE)
423     public @interface ReasonCode {}
424 
425     /**
426      * @hide
427      */
PowerExemptionManager(@onNull Context context)428     public PowerExemptionManager(@NonNull Context context) {
429         mContext = context;
430         mService = context.getSystemService(DeviceIdleManager.class).getService();
431     }
432 
433     /**
434      * Add the specified package to the permanent power save allow list.
435      *
436      * @hide
437      */
438     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
addToPermanentAllowList(@onNull String packageName)439     public void addToPermanentAllowList(@NonNull String packageName) {
440         addToPermanentAllowList(Collections.singletonList(packageName));
441     }
442 
443     /**
444      * Add the specified packages to the permanent power save allow list.
445      *
446      * @hide
447      */
448     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
addToPermanentAllowList(@onNull List<String> packageNames)449     public void addToPermanentAllowList(@NonNull List<String> packageNames) {
450         try {
451             mService.addPowerSaveWhitelistApps(packageNames);
452         } catch (RemoteException e) {
453             throw e.rethrowFromSystemServer();
454         }
455     }
456 
457     /**
458      * Get a list of app IDs of app that are allow-listed. This does not include temporarily
459      * allow-listed apps.
460      *
461      * @param includingIdle Set to true if the app should be allow-listed from device idle as well
462      *                      as other power save restrictions
463      * @hide
464      */
465     @NonNull
466     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
getAllowListedAppIds(boolean includingIdle)467     public int[] getAllowListedAppIds(boolean includingIdle) {
468         try {
469             if (includingIdle) {
470                 return mService.getAppIdWhitelist();
471             } else {
472                 return mService.getAppIdWhitelistExceptIdle();
473             }
474         } catch (RemoteException e) {
475             throw e.rethrowFromSystemServer();
476         }
477     }
478 
479     /**
480      * Returns true if the app is allow-listed from power save restrictions. This does not include
481      * temporarily allow-listed apps.
482      *
483      * @param includingIdle Set to true if the app should be allow-listed from device
484      *                      idle as well as other power save restrictions
485      * @hide
486      */
isAllowListed(@onNull String packageName, boolean includingIdle)487     public boolean isAllowListed(@NonNull String packageName, boolean includingIdle) {
488         try {
489             if (includingIdle) {
490                 return mService.isPowerSaveWhitelistApp(packageName);
491             } else {
492                 return mService.isPowerSaveWhitelistExceptIdleApp(packageName);
493             }
494         } catch (RemoteException e) {
495             throw e.rethrowFromSystemServer();
496         }
497     }
498 
499     /**
500      * Remove an app from the permanent power save allow list. Only apps that were added via
501      * {@link #addToPermanentAllowList(String)} or {@link #addToPermanentAllowList(List)} will be
502      * removed. Apps allow-listed by default by the system cannot be removed.
503      *
504      * @param packageName The app to remove from the allow list
505      * @hide
506      */
507     @RequiresPermission(android.Manifest.permission.DEVICE_POWER)
removeFromPermanentAllowList(@onNull String packageName)508     public void removeFromPermanentAllowList(@NonNull String packageName) {
509         try {
510             mService.removePowerSaveWhitelistApp(packageName);
511         } catch (RemoteException e) {
512             throw e.rethrowFromSystemServer();
513         }
514     }
515 
516     /**
517      * Add an app to the temporary allow list for a short amount of time.
518      *
519      * @param packageName The package to add to the temp allow list
520      * @param durationMs How long to keep the app on the temp allow list for (in milliseconds)
521      * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
522      * @param reason a optional human readable reason string, could be null or empty string.
523      */
524     @UserHandleAware
525     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
addToTemporaryAllowList(@onNull String packageName, @ReasonCode int reasonCode, @Nullable String reason, long durationMs)526     public void addToTemporaryAllowList(@NonNull String packageName, @ReasonCode int reasonCode,
527             @Nullable String reason, long durationMs) {
528         try {
529             mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(),
530                     reasonCode, reason);
531         } catch (RemoteException e) {
532             throw e.rethrowFromSystemServer();
533         }
534     }
535 
536     /**
537      * Add an app to the temporary allow list for a short amount of time for a specific reason.
538      * The temporary allow list is kept separately from the permanent allow list and apps are
539      * automatically removed from the temporary allow list after a predetermined amount of time.
540      *
541      * @param packageName The package to add to the temp allow list
542      * @param event       The reason to add the app to the temp allow list
543      * @param reasonCode  one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure.
544      * @param reason      A human-readable reason explaining why the app is temp allow-listed. Only
545      *                    used for logging purposes. Could be null or empty string.
546      * @return The duration (in milliseconds) that the app is allow-listed for
547      */
548     @UserHandleAware
549     @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST)
addToTemporaryAllowListForEvent(@onNull String packageName, @ReasonCode int reasonCode, @Nullable String reason, @AllowListEvent int event)550     public long addToTemporaryAllowListForEvent(@NonNull String packageName,
551             @ReasonCode int reasonCode, @Nullable String reason, @AllowListEvent int event) {
552         try {
553             switch (event) {
554                 case EVENT_MMS:
555                     return mService.addPowerSaveTempWhitelistAppForMms(
556                             packageName, mContext.getUserId(), reasonCode, reason);
557                 case EVENT_SMS:
558                     return mService.addPowerSaveTempWhitelistAppForSms(
559                             packageName, mContext.getUserId(), reasonCode, reason);
560                 case EVENT_UNSPECIFIED:
561                 default:
562                     return mService.whitelistAppTemporarily(
563                             packageName, mContext.getUserId(), reasonCode, reason);
564             }
565         } catch (RemoteException e) {
566             throw e.rethrowFromSystemServer();
567         }
568     }
569 
570     /**
571      * @hide
572      */
getReasonCodeFromProcState(int procState)573     public static @ReasonCode int getReasonCodeFromProcState(int procState) {
574         if (procState <= PROCESS_STATE_PERSISTENT) {
575             return REASON_PROC_STATE_PERSISTENT;
576         } else if (procState <= PROCESS_STATE_PERSISTENT_UI) {
577             return REASON_PROC_STATE_PERSISTENT_UI;
578         } else if (procState <= PROCESS_STATE_TOP) {
579             return REASON_PROC_STATE_TOP;
580         } else if (procState <= PROCESS_STATE_BOUND_TOP) {
581             return REASON_PROC_STATE_BTOP;
582         } else if (procState <= PROCESS_STATE_FOREGROUND_SERVICE) {
583             return REASON_PROC_STATE_FGS;
584         } else if (procState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
585             return REASON_PROC_STATE_BFGS;
586         } else {
587             return REASON_DENIED;
588         }
589     }
590 
591     /**
592      * Return string name of the integer reason code.
593      * @hide
594      * @param reasonCode
595      * @return string name of the reason code.
596      */
reasonCodeToString(@easonCode int reasonCode)597     public static String reasonCodeToString(@ReasonCode int reasonCode) {
598         switch (reasonCode) {
599             case REASON_DENIED:
600                 return "DENIED";
601             case REASON_UNKNOWN:
602                 return "UNKNOWN";
603             case REASON_OTHER:
604                 return "OTHER";
605             case REASON_PROC_STATE_PERSISTENT:
606                 return "PROC_STATE_PERSISTENT";
607             case REASON_PROC_STATE_PERSISTENT_UI:
608                 return "PROC_STATE_PERSISTENT_UI";
609             case REASON_PROC_STATE_TOP:
610                 return "PROC_STATE_TOP";
611             case REASON_PROC_STATE_BTOP:
612                 return "PROC_STATE_BTOP";
613             case REASON_PROC_STATE_FGS:
614                 return "PROC_STATE_FGS";
615             case REASON_PROC_STATE_BFGS:
616                 return "PROC_STATE_BFGS";
617             case REASON_UID_VISIBLE:
618                 return "UID_VISIBLE";
619             case REASON_SYSTEM_UID:
620                 return "SYSTEM_UID";
621             case REASON_ACTIVITY_STARTER:
622                 return "ACTIVITY_STARTER";
623             case REASON_START_ACTIVITY_FLAG:
624                 return "START_ACTIVITY_FLAG";
625             case REASON_FGS_BINDING:
626                 return "FGS_BINDING";
627             case REASON_DEVICE_OWNER:
628                 return "DEVICE_OWNER";
629             case REASON_PROFILE_OWNER:
630                 return "PROFILE_OWNER";
631             case REASON_COMPANION_DEVICE_MANAGER:
632                 return "COMPANION_DEVICE_MANAGER";
633             case REASON_BACKGROUND_ACTIVITY_PERMISSION:
634                 return "BACKGROUND_ACTIVITY_PERMISSION";
635             case REASON_BACKGROUND_FGS_PERMISSION:
636                 return "BACKGROUND_FGS_PERMISSION";
637             case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
638                 return "INSTR_BACKGROUND_ACTIVITY_PERMISSION";
639             case REASON_INSTR_BACKGROUND_FGS_PERMISSION:
640                 return "INSTR_BACKGROUND_FGS_PERMISSION";
641             case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
642                 return "SYSTEM_ALERT_WINDOW_PERMISSION";
643             case REASON_DEVICE_DEMO_MODE:
644                 return "DEVICE_DEMO_MODE";
645             case REASON_ALLOWLISTED_PACKAGE:
646                 return "ALLOWLISTED_PACKAGE";
647             case REASON_APPOP:
648                 return "APPOP";
649             case REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD:
650                 return "ACTIVITY_VISIBILITY_GRACE_PERIOD";
651             case REASON_OP_ACTIVATE_VPN:
652                 return "OP_ACTIVATE_VPN";
653             case REASON_OP_ACTIVATE_PLATFORM_VPN:
654                 return "OP_ACTIVATE_PLATFORM_VPN";
655             case REASON_CURRENT_INPUT_METHOD:
656                 return "CURRENT_INPUT_METHOD";
657             case REASON_TEMP_ALLOWED_WHILE_IN_USE:
658                 return "TEMP_ALLOWED_WHILE_IN_USE";
659             case REASON_GEOFENCING:
660                 return "GEOFENCING";
661             case REASON_PUSH_MESSAGING:
662                 return "PUSH_MESSAGING";
663             case REASON_PUSH_MESSAGING_OVER_QUOTA:
664                 return "PUSH_MESSAGING_OVER_QUOTA";
665             case REASON_ACTIVITY_RECOGNITION:
666                 return "ACTIVITY_RECOGNITION";
667             case REASON_ACCOUNT_TRANSFER:
668                 return "REASON_ACCOUNT_TRANSFER";
669             case REASON_BOOT_COMPLETED:
670                 return "BOOT_COMPLETED";
671             case REASON_PRE_BOOT_COMPLETED:
672                 return "PRE_BOOT_COMPLETED";
673             case REASON_LOCKED_BOOT_COMPLETED:
674                 return "LOCKED_BOOT_COMPLETED";
675             case REASON_BLUETOOTH_BROADCAST:
676                 return "BLUETOOTH_BROADCAST";
677             case REASON_TIMEZONE_CHANGED:
678                 return "TIMEZONE_CHANGED";
679             case REASON_TIME_CHANGED:
680                 return "TIME_CHANGED";
681             case REASON_LOCALE_CHANGED:
682                 return "LOCALE_CHANGED";
683             case REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED:
684                 return "REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
685             case REASON_SYSTEM_ALLOW_LISTED:
686                 return "SYSTEM_ALLOW_LISTED";
687             case REASON_ALARM_MANAGER_ALARM_CLOCK:
688                 return "ALARM_MANAGER_ALARM_CLOCK";
689             case REASON_ALARM_MANAGER_WHILE_IDLE:
690                 return "ALARM_MANAGER_WHILE_IDLE";
691             case REASON_SERVICE_LAUNCH:
692                 return "SERVICE_LAUNCH";
693             case REASON_KEY_CHAIN:
694                 return "KEY_CHAIN";
695             case REASON_PACKAGE_VERIFIER:
696                 return "PACKAGE_VERIFIER";
697             case REASON_SYNC_MANAGER:
698                 return "SYNC_MANAGER";
699             case REASON_DOMAIN_VERIFICATION_V1:
700                 return "DOMAIN_VERIFICATION_V1";
701             case REASON_DOMAIN_VERIFICATION_V2:
702                 return "DOMAIN_VERIFICATION_V2";
703             case REASON_VPN:
704                 return "VPN";
705             case REASON_NOTIFICATION_SERVICE:
706                 return "NOTIFICATION_SERVICE";
707             case REASON_PACKAGE_REPLACED:
708                 return "PACKAGE_REPLACED";
709             case REASON_LOCATION_PROVIDER:
710                 return "LOCATION_PROVIDER";
711             case REASON_MEDIA_BUTTON:
712                 return "MEDIA_BUTTON";
713             case REASON_EVENT_SMS:
714                 return "EVENT_SMS";
715             case REASON_EVENT_MMS:
716                 return "EVENT_MMS";
717             case REASON_SHELL:
718                 return "SHELL";
719             case REASON_MEDIA_SESSION_CALLBACK:
720                 return "MEDIA_SESSION_CALLBACK";
721             case REASON_OPT_OUT_REQUESTED:
722                 return "REASON_OPT_OUT_REQUESTED";
723             default:
724                 return "(unknown:" + reasonCode + ")";
725         }
726     }
727 }
728