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 com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
20 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
21 import static com.android.server.am.AppRestrictionController.DEVICE_CONFIG_SUBNAMESPACE_PREFIX;
22 import static com.android.server.am.BaseAppStateTracker.ONE_DAY;
23 
24 import android.annotation.NonNull;
25 import android.app.ActivityManagerInternal.BroadcastEventListener;
26 import android.content.Context;
27 import android.os.AppBackgroundRestrictionsInfo;
28 import android.os.SystemClock;
29 import android.util.proto.ProtoOutputStream;
30 
31 import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy;
32 import com.android.server.am.AppRestrictionController.TrackerType;
33 import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents;
34 import com.android.server.am.BaseAppStateTracker.Injector;
35 
36 import java.io.PrintWriter;
37 import java.lang.reflect.Constructor;
38 
39 final class AppBroadcastEventsTracker extends BaseAppStateTimeSlotEventsTracker
40         <AppBroadcastEventsPolicy, SimpleAppStateTimeslotEvents> implements BroadcastEventListener {
41 
42     static final String TAG = TAG_WITH_CLASS_NAME ? "AppBroadcastEventsTracker" : TAG_AM;
43 
44     static final boolean DEBUG_APP_STATE_BROADCAST_EVENT_TRACKER = false;
45 
AppBroadcastEventsTracker(Context context, AppRestrictionController controller)46     AppBroadcastEventsTracker(Context context, AppRestrictionController controller) {
47         this(context, controller, null, null);
48     }
49 
AppBroadcastEventsTracker(Context context, AppRestrictionController controller, Constructor<? extends Injector<AppBroadcastEventsPolicy>> injector, Object outerContext)50     AppBroadcastEventsTracker(Context context, AppRestrictionController controller,
51             Constructor<? extends Injector<AppBroadcastEventsPolicy>> injector,
52             Object outerContext) {
53         super(context, controller, injector, outerContext);
54         mInjector.setPolicy(new AppBroadcastEventsPolicy(mInjector, this));
55     }
56 
57     @Override
onSendingBroadcast(String packageName, int uid)58     public void onSendingBroadcast(String packageName, int uid) {
59         if (mInjector.getPolicy().isEnabled()) {
60             onNewEvent(packageName, uid);
61         }
62     }
63 
64     @Override
getType()65     @TrackerType int getType() {
66         return AppRestrictionController.TRACKER_TYPE_BROADCAST_EVENTS;
67     }
68 
69     @Override
onSystemReady()70     void onSystemReady() {
71         super.onSystemReady();
72         mInjector.getActivityManagerInternal().addBroadcastEventListener(this);
73     }
74 
75     @Override
createAppStateEvents(int uid, String packageName)76     public SimpleAppStateTimeslotEvents createAppStateEvents(int uid, String packageName) {
77         return new SimpleAppStateTimeslotEvents(uid, packageName,
78                 mInjector.getPolicy().getTimeSlotSize(), TAG, mInjector.getPolicy());
79     }
80 
81     @Override
createAppStateEvents(SimpleAppStateTimeslotEvents other)82     public SimpleAppStateTimeslotEvents createAppStateEvents(SimpleAppStateTimeslotEvents other) {
83         return new SimpleAppStateTimeslotEvents(other);
84     }
85 
86     @Override
getTrackerInfoForStatsd(int uid)87     byte[] getTrackerInfoForStatsd(int uid) {
88         final long now = SystemClock.elapsedRealtime();
89         final int numOfBroadcasts = getTotalEventsLocked(uid, now);
90         if (numOfBroadcasts == 0) {
91             // Not interested.
92             return null;
93         }
94         final ProtoOutputStream proto = new ProtoOutputStream();
95         proto.write(AppBackgroundRestrictionsInfo.BroadcastEventsTrackerInfo.BROADCASTS_SENT,
96                 numOfBroadcasts);
97         proto.flush();
98         return proto.getBytes();
99     }
100 
101     @Override
dump(PrintWriter pw, String prefix)102     void dump(PrintWriter pw, String prefix) {
103         pw.print(prefix);
104         pw.println("APP BROADCAST EVENT TRACKER:");
105         super.dump(pw, "  " + prefix);
106     }
107 
108     static final class AppBroadcastEventsPolicy
109             extends BaseAppStateTimeSlotEventsPolicy<AppBroadcastEventsTracker> {
110         /**
111          * Whether or not we should enable the monitoring on abusive broadcasts.
112          */
113         static final String KEY_BG_BROADCAST_MONITOR_ENABLED =
114                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "broadcast_monitor_enabled";
115 
116         /**
117          * The size of the sliding window in which the number of broadcasts is checked
118          * against the threshold.
119          */
120         static final String KEY_BG_BROADCAST_WINDOW =
121                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "broadcast_window";
122 
123         /**
124          * The threshold at where the number of broadcasts are considered as "excessive"
125          * within the given window.
126          */
127         static final String KEY_BG_EX_BROADCAST_THRESHOLD =
128                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "ex_broadcast_threshold";
129 
130         /**
131          * Default value to {@link #mTrackerEnabled}.
132          */
133         static final boolean DEFAULT_BG_BROADCAST_MONITOR_ENABLED = true;
134 
135         /**
136          * Default value to {@link #mMaxTrackingDuration}.
137          */
138         static final long DEFAULT_BG_BROADCAST_WINDOW = ONE_DAY;
139 
140         /**
141          * Default value to {@link #mNumOfEventsThreshold}.
142          */
143         static final int DEFAULT_BG_EX_BROADCAST_THRESHOLD = 10_000;
144 
AppBroadcastEventsPolicy(@onNull Injector injector, @NonNull AppBroadcastEventsTracker tracker)145         AppBroadcastEventsPolicy(@NonNull Injector injector,
146                 @NonNull AppBroadcastEventsTracker tracker) {
147             super(injector, tracker,
148                     KEY_BG_BROADCAST_MONITOR_ENABLED, DEFAULT_BG_BROADCAST_MONITOR_ENABLED,
149                     KEY_BG_BROADCAST_WINDOW, DEFAULT_BG_BROADCAST_WINDOW,
150                     KEY_BG_EX_BROADCAST_THRESHOLD, DEFAULT_BG_EX_BROADCAST_THRESHOLD);
151         }
152 
153         @Override
getEventName()154         String getEventName() {
155             return "broadcast";
156         }
157 
158         @Override
dump(PrintWriter pw, String prefix)159         void dump(PrintWriter pw, String prefix) {
160             pw.print(prefix);
161             pw.println("APP BROADCAST EVENT TRACKER POLICY SETTINGS:");
162             super.dump(pw, "  " + prefix);
163         }
164     }
165 }
166