1 /*
2  * Copyright (C) 2022 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.am;
18 
19 import static android.app.ActivityManager.RESTRICTION_LEVEL_UNKNOWN;
20 
21 import android.annotation.CallSuper;
22 import android.annotation.NonNull;
23 import android.app.ActivityManager.RestrictionLevel;
24 import android.os.PowerExemptionManager.ReasonCode;
25 import android.provider.DeviceConfig;
26 
27 import com.android.server.am.BaseAppStateTracker.Injector;
28 
29 import java.io.PrintWriter;
30 
31 /**
32  * Base class to track the policy for certain state of the app.
33  *
34  * @param <T> A class derived from BaseAppStateTracker.
35  */
36 public abstract class BaseAppStatePolicy<T extends BaseAppStateTracker> {
37 
38     protected final Injector<?> mInjector;
39     protected final T mTracker;
40 
41     /**
42      * The key to the device config, on whether or not we should enable the tracker.
43      */
44     protected final @NonNull String mKeyTrackerEnabled;
45 
46     /**
47      * The default settings on whether or not we should enable the tracker.
48      */
49     protected final boolean mDefaultTrackerEnabled;
50 
51     /**
52      * Whether or not we should enable the tracker.
53      */
54     volatile boolean mTrackerEnabled;
55 
BaseAppStatePolicy(@onNull Injector<?> injector, @NonNull T tracker, @NonNull String keyTrackerEnabled, boolean defaultTrackerEnabled)56     BaseAppStatePolicy(@NonNull Injector<?> injector, @NonNull T tracker,
57             @NonNull String keyTrackerEnabled, boolean defaultTrackerEnabled) {
58         mInjector = injector;
59         mTracker = tracker;
60         mKeyTrackerEnabled = keyTrackerEnabled;
61         mDefaultTrackerEnabled = defaultTrackerEnabled;
62     }
63 
updateTrackerEnabled()64     void updateTrackerEnabled() {
65         final boolean enabled = DeviceConfig.getBoolean(
66                 DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
67                 mKeyTrackerEnabled, mDefaultTrackerEnabled);
68         if (enabled != mTrackerEnabled) {
69             mTrackerEnabled = enabled;
70             onTrackerEnabled(enabled);
71         }
72     }
73 
74     /**
75      * Called when the tracker enable flag flips.
76      */
onTrackerEnabled(boolean enabled)77     public abstract void onTrackerEnabled(boolean enabled);
78 
79     /**
80      * Called when a device config property in the activity manager namespace
81      * has changed.
82      */
onPropertiesChanged(@onNull String name)83     public void onPropertiesChanged(@NonNull String name) {
84         if (mKeyTrackerEnabled.equals(name)) {
85             updateTrackerEnabled();
86         }
87     }
88 
89     /**
90      * @return The proposed background restriction policy for the given package/uid,
91      *         the returned level should be capped at {@code maxLevel} (exclusive).
92      */
getProposedRestrictionLevel(String packageName, int uid, @RestrictionLevel int maxLevel)93     public @RestrictionLevel int getProposedRestrictionLevel(String packageName, int uid,
94             @RestrictionLevel int maxLevel) {
95         return RESTRICTION_LEVEL_UNKNOWN;
96     }
97 
98     /**
99      * Called when the system is ready to rock.
100      */
onSystemReady()101     public void onSystemReady() {
102         updateTrackerEnabled();
103     }
104 
105     /**
106      * @return If this tracker is enabled or not.
107      */
isEnabled()108     public boolean isEnabled() {
109         return mTrackerEnabled;
110     }
111 
112     /**
113      * @return If the given UID should be exempted.
114      *
115      * <p>
116      * Note: Call it with caution as it'll try to acquire locks in other services.
117      * </p>
118      */
119     @CallSuper
120     @ReasonCode
shouldExemptUid(int uid)121     public int shouldExemptUid(int uid) {
122         return mTracker.mAppRestrictionController.getBackgroundRestrictionExemptionReason(uid);
123     }
124 
125     /**
126      * Dump to the given printer writer.
127      */
dump(PrintWriter pw, String prefix)128     void dump(PrintWriter pw, String prefix) {
129         pw.print(prefix);
130         pw.print(mKeyTrackerEnabled);
131         pw.print('=');
132         pw.println(mTrackerEnabled);
133     }
134 }
135