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.BindServiceEventListener;
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.AppBindServiceEventsTracker.AppBindServiceEventsPolicy;
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 AppBindServiceEventsTracker extends BaseAppStateTimeSlotEventsTracker
40         <AppBindServiceEventsPolicy, SimpleAppStateTimeslotEvents>
41         implements BindServiceEventListener {
42 
43     static final String TAG = TAG_WITH_CLASS_NAME ? "AppBindServiceEventsTracker" : TAG_AM;
44 
45     static final boolean DEBUG_APP_STATE_BIND_SERVICE_EVENT_TRACKER = false;
46 
AppBindServiceEventsTracker(Context context, AppRestrictionController controller)47     AppBindServiceEventsTracker(Context context, AppRestrictionController controller) {
48         this(context, controller, null, null);
49     }
50 
AppBindServiceEventsTracker(Context context, AppRestrictionController controller, Constructor<? extends Injector<AppBindServiceEventsPolicy>> injector, Object outerContext)51     AppBindServiceEventsTracker(Context context, AppRestrictionController controller,
52             Constructor<? extends Injector<AppBindServiceEventsPolicy>> injector,
53             Object outerContext) {
54         super(context, controller, injector, outerContext);
55         mInjector.setPolicy(new AppBindServiceEventsPolicy(mInjector, this));
56     }
57 
58     @Override
onBindingService(String packageName, int uid)59     public void onBindingService(String packageName, int uid) {
60         if (mInjector.getPolicy().isEnabled()) {
61             onNewEvent(packageName, uid);
62         }
63     }
64 
65     @Override
getType()66     @TrackerType int getType() {
67         return AppRestrictionController.TRACKER_TYPE_BIND_SERVICE_EVENTS;
68     }
69 
70     @Override
onSystemReady()71     void onSystemReady() {
72         super.onSystemReady();
73         mInjector.getActivityManagerInternal().addBindServiceEventListener(this);
74     }
75 
76     @Override
createAppStateEvents(int uid, String packageName)77     public SimpleAppStateTimeslotEvents createAppStateEvents(int uid, String packageName) {
78         return new SimpleAppStateTimeslotEvents(uid, packageName,
79                 mInjector.getPolicy().getTimeSlotSize(), TAG, mInjector.getPolicy());
80     }
81 
82     @Override
createAppStateEvents(SimpleAppStateTimeslotEvents other)83     public SimpleAppStateTimeslotEvents createAppStateEvents(SimpleAppStateTimeslotEvents other) {
84         return new SimpleAppStateTimeslotEvents(other);
85     }
86 
87     @Override
getTrackerInfoForStatsd(int uid)88     byte[] getTrackerInfoForStatsd(int uid) {
89         final long now = SystemClock.elapsedRealtime();
90         final int numOfBindRequests = getTotalEventsLocked(uid, now);
91         if (numOfBindRequests == 0) {
92             // Not interested.
93             return null;
94         }
95         final ProtoOutputStream proto = new ProtoOutputStream();
96         proto.write(
97                 AppBackgroundRestrictionsInfo.BindServiceEventsTrackerInfo.BIND_SERVICE_REQUESTS,
98                 numOfBindRequests);
99         proto.flush();
100         return proto.getBytes();
101     }
102 
103     @Override
dump(PrintWriter pw, String prefix)104     void dump(PrintWriter pw, String prefix) {
105         pw.print(prefix);
106         pw.println("APP BIND SERVICE EVENT TRACKER:");
107         super.dump(pw, "  " + prefix);
108     }
109 
110     static final class AppBindServiceEventsPolicy
111             extends BaseAppStateTimeSlotEventsPolicy<AppBindServiceEventsTracker> {
112         /**
113          * Whether or not we should enable the monitoring on abusive service bindings requests.
114          */
115         static final String KEY_BG_BIND_SVC_MONITOR_ENABLED =
116                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "bind_svc_monitor_enabled";
117 
118         /**
119          * The size of the sliding window in which the number of service binding requests is checked
120          * against the threshold.
121          */
122         static final String KEY_BG_BIND_SVC_WINDOW =
123                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "bind_svc_window";
124 
125         /**
126          * The threshold at where the number of service binding requests are considered as
127          * "excessive" within the given window.
128          */
129         static final String KEY_BG_EX_BIND_SVC_THRESHOLD =
130                 DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "ex_bind_svc_threshold";
131 
132         /**
133          * Default value to {@link #mTrackerEnabled}.
134          */
135         static final boolean DEFAULT_BG_BIND_SVC_MONITOR_ENABLED = true;
136 
137         /**
138          * Default value to {@link #mMaxTrackingDuration}.
139          */
140         static final long DEFAULT_BG_BIND_SVC_WINDOW = ONE_DAY;
141 
142         /**
143          * Default value to {@link #mNumOfEventsThreshold}.
144          */
145         static final int DEFAULT_BG_EX_BIND_SVC_THRESHOLD = 10_000;
146 
AppBindServiceEventsPolicy(@onNull Injector injector, @NonNull AppBindServiceEventsTracker tracker)147         AppBindServiceEventsPolicy(@NonNull Injector injector,
148                 @NonNull AppBindServiceEventsTracker tracker) {
149             super(injector, tracker,
150                     KEY_BG_BIND_SVC_MONITOR_ENABLED, DEFAULT_BG_BIND_SVC_MONITOR_ENABLED,
151                     KEY_BG_BIND_SVC_WINDOW, DEFAULT_BG_BIND_SVC_WINDOW,
152                     KEY_BG_EX_BIND_SVC_THRESHOLD, DEFAULT_BG_EX_BIND_SVC_THRESHOLD);
153         }
154 
155         @Override
getEventName()156         String getEventName() {
157             return "bindservice";
158         }
159 
160         @Override
dump(PrintWriter pw, String prefix)161         void dump(PrintWriter pw, String prefix) {
162             pw.print(prefix);
163             pw.println("APP BIND SERVICE EVENT TRACKER POLICY SETTINGS:");
164             super.dump(pw, "  " + prefix);
165         }
166     }
167 }
168