blob: 4c2f8d124566ecec069cf55d2092f7799df375f9 [file] [log] [blame]
/*
* Copyright (C) 2021 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.alarm;
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST;
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED;
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__NOT_APPLICABLE;
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PERMISSION;
import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.StatsManager;
import android.content.Context;
import android.os.SystemClock;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FrameworkStatsLog;
import java.util.function.Supplier;
/**
* A helper class to write logs to statsd.
*/
class MetricsHelper {
private final Context mContext;
private final Object mLock;
MetricsHelper(Context context, Object lock) {
mContext = context;
mLock = lock;
}
void registerPuller(Supplier<AlarmStore> alarmStoreSupplier) {
final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
statsManager.setPullAtomCallback(FrameworkStatsLog.PENDING_ALARM_INFO, null,
BackgroundThread.getExecutor(), (atomTag, data) -> {
if (atomTag != FrameworkStatsLog.PENDING_ALARM_INFO) {
throw new UnsupportedOperationException("Unknown tag" + atomTag);
}
final long now = SystemClock.elapsedRealtime();
synchronized (mLock) {
final AlarmStore alarmStore = alarmStoreSupplier.get();
data.add(FrameworkStatsLog.buildStatsEvent(atomTag,
alarmStore.size(),
alarmStore.getCount(a -> a.windowLength == 0),
alarmStore.getCount(a -> a.wakeup),
alarmStore.getCount(
a -> (a.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0),
alarmStore.getCount(
a -> (a.flags & AlarmManager.FLAG_PRIORITIZE) != 0),
alarmStore.getCount(a -> (a.operation != null
&& a.operation.isForegroundService())),
alarmStore.getCount(
a -> (a.operation != null && a.operation.isActivity())),
alarmStore.getCount(
a -> (a.operation != null && a.operation.isService())),
alarmStore.getCount(a -> (a.listener != null)),
alarmStore.getCount(
a -> (a.getRequestedElapsed() > now + INDEFINITE_DELAY)),
alarmStore.getCount(a -> (a.repeatInterval != 0)),
alarmStore.getCount(a -> (a.alarmClock != null)),
alarmStore.getCount(a -> AlarmManagerService.isRtc(a.type))
));
return StatsManager.PULL_SUCCESS;
}
});
}
private static int reasonToStatsReason(int reasonCode) {
switch (reasonCode) {
case Alarm.EXACT_ALLOW_REASON_ALLOW_LIST:
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST;
case Alarm.EXACT_ALLOW_REASON_PERMISSION:
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PERMISSION;
case Alarm.EXACT_ALLOW_REASON_COMPAT:
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED;
default:
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__NOT_APPLICABLE;
}
}
static void pushAlarmScheduled(Alarm a, int callerProcState) {
FrameworkStatsLog.write(
FrameworkStatsLog.ALARM_SCHEDULED,
a.uid,
a.windowLength == 0,
a.wakeup,
(a.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0,
a.alarmClock != null,
a.repeatInterval != 0,
reasonToStatsReason(a.mExactAllowReason),
AlarmManagerService.isRtc(a.type),
ActivityManager.processStateAmToProto(callerProcState));
}
static void pushAlarmBatchDelivered(int numAlarms, int wakeups) {
FrameworkStatsLog.write(
FrameworkStatsLog.ALARM_BATCH_DELIVERED,
numAlarms,
wakeups);
}
}