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