blob: b509008f31df5c697c2740d1e5192e408fc023de [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.am;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.AppRestrictionController.DEVICE_CONFIG_SUBNAMESPACE_PREFIX;
import static com.android.server.am.BaseAppStateTracker.ONE_DAY;
import android.annotation.NonNull;
import android.app.ActivityManagerInternal.BroadcastEventListener;
import android.content.Context;
import android.os.AppBackgroundRestrictionsInfo;
import android.os.SystemClock;
import android.util.proto.ProtoOutputStream;
import com.android.server.am.AppBroadcastEventsTracker.AppBroadcastEventsPolicy;
import com.android.server.am.AppRestrictionController.TrackerType;
import com.android.server.am.BaseAppStateTimeSlotEventsTracker.SimpleAppStateTimeslotEvents;
import com.android.server.am.BaseAppStateTracker.Injector;
import java.io.PrintWriter;
import java.lang.reflect.Constructor;
final class AppBroadcastEventsTracker extends BaseAppStateTimeSlotEventsTracker
<AppBroadcastEventsPolicy, SimpleAppStateTimeslotEvents> implements BroadcastEventListener {
static final String TAG = TAG_WITH_CLASS_NAME ? "AppBroadcastEventsTracker" : TAG_AM;
static final boolean DEBUG_APP_STATE_BROADCAST_EVENT_TRACKER = false;
AppBroadcastEventsTracker(Context context, AppRestrictionController controller) {
this(context, controller, null, null);
}
AppBroadcastEventsTracker(Context context, AppRestrictionController controller,
Constructor<? extends Injector<AppBroadcastEventsPolicy>> injector,
Object outerContext) {
super(context, controller, injector, outerContext);
mInjector.setPolicy(new AppBroadcastEventsPolicy(mInjector, this));
}
@Override
public void onSendingBroadcast(String packageName, int uid) {
if (mInjector.getPolicy().isEnabled()) {
onNewEvent(packageName, uid);
}
}
@Override
@TrackerType int getType() {
return AppRestrictionController.TRACKER_TYPE_BROADCAST_EVENTS;
}
@Override
void onSystemReady() {
super.onSystemReady();
mInjector.getActivityManagerInternal().addBroadcastEventListener(this);
}
@Override
public SimpleAppStateTimeslotEvents createAppStateEvents(int uid, String packageName) {
return new SimpleAppStateTimeslotEvents(uid, packageName,
mInjector.getPolicy().getTimeSlotSize(), TAG, mInjector.getPolicy());
}
@Override
public SimpleAppStateTimeslotEvents createAppStateEvents(SimpleAppStateTimeslotEvents other) {
return new SimpleAppStateTimeslotEvents(other);
}
@Override
byte[] getTrackerInfoForStatsd(int uid) {
final long now = SystemClock.elapsedRealtime();
final int numOfBroadcasts = getTotalEventsLocked(uid, now);
if (numOfBroadcasts == 0) {
// Not interested.
return null;
}
final ProtoOutputStream proto = new ProtoOutputStream();
proto.write(AppBackgroundRestrictionsInfo.BroadcastEventsTrackerInfo.BROADCASTS_SENT,
numOfBroadcasts);
proto.flush();
return proto.getBytes();
}
@Override
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println("APP BROADCAST EVENT TRACKER:");
super.dump(pw, " " + prefix);
}
static final class AppBroadcastEventsPolicy
extends BaseAppStateTimeSlotEventsPolicy<AppBroadcastEventsTracker> {
/**
* Whether or not we should enable the monitoring on abusive broadcasts.
*/
static final String KEY_BG_BROADCAST_MONITOR_ENABLED =
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "broadcast_monitor_enabled";
/**
* The size of the sliding window in which the number of broadcasts is checked
* against the threshold.
*/
static final String KEY_BG_BROADCAST_WINDOW =
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "broadcast_window";
/**
* The threshold at where the number of broadcasts are considered as "excessive"
* within the given window.
*/
static final String KEY_BG_EX_BROADCAST_THRESHOLD =
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "ex_broadcast_threshold";
/**
* Default value to {@link #mTrackerEnabled}.
*/
static final boolean DEFAULT_BG_BROADCAST_MONITOR_ENABLED = true;
/**
* Default value to {@link #mMaxTrackingDuration}.
*/
static final long DEFAULT_BG_BROADCAST_WINDOW = ONE_DAY;
/**
* Default value to {@link #mNumOfEventsThreshold}.
*/
static final int DEFAULT_BG_EX_BROADCAST_THRESHOLD = 10_000;
AppBroadcastEventsPolicy(@NonNull Injector injector,
@NonNull AppBroadcastEventsTracker tracker) {
super(injector, tracker,
KEY_BG_BROADCAST_MONITOR_ENABLED, DEFAULT_BG_BROADCAST_MONITOR_ENABLED,
KEY_BG_BROADCAST_WINDOW, DEFAULT_BG_BROADCAST_WINDOW,
KEY_BG_EX_BROADCAST_THRESHOLD, DEFAULT_BG_EX_BROADCAST_THRESHOLD);
}
@Override
String getEventName() {
return "broadcast";
}
@Override
void dump(PrintWriter pw, String prefix) {
pw.print(prefix);
pw.println("APP BROADCAST EVENT TRACKER POLICY SETTINGS:");
super.dump(pw, " " + prefix);
}
}
}