blob: 3c730f5485004f91470111fb090d690fb6bc668a [file] [log] [blame]
/*
* Copyright 2018 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 androidx.work.impl.background.systemalarm;
import static android.app.AlarmManager.RTC_WAKEUP;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.work.Logger;
import androidx.work.impl.WorkDatabase;
import androidx.work.impl.WorkManagerImpl;
import androidx.work.impl.model.SystemIdInfo;
import androidx.work.impl.model.SystemIdInfoDao;
import androidx.work.impl.utils.IdGenerator;
/**
* A common class for managing Alarms.
*
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
class Alarms {
private static final String TAG = Logger.tagWithPrefix("Alarms");
/**
* Sets an exact alarm after cancelling any existing alarms for the given id.
*
* @param context The application {@link Context}.
* @param workManager The instance of {@link WorkManagerImpl}.
* @param workSpecId The {@link androidx.work.impl.model.WorkSpec} identifier.
* @param triggerAtMillis Determines when to trigger the Alarm.
*/
public static void setAlarm(
@NonNull Context context,
@NonNull WorkManagerImpl workManager,
@NonNull String workSpecId,
long triggerAtMillis) {
WorkDatabase workDatabase = workManager.getWorkDatabase();
SystemIdInfoDao systemIdInfoDao = workDatabase.systemIdInfoDao();
SystemIdInfo systemIdInfo = systemIdInfoDao.getSystemIdInfo(workSpecId);
if (systemIdInfo != null) {
cancelExactAlarm(context, workSpecId, systemIdInfo.systemId);
setExactAlarm(context, workSpecId, systemIdInfo.systemId, triggerAtMillis);
} else {
IdGenerator idGenerator = new IdGenerator(workDatabase);
int alarmId = idGenerator.nextAlarmManagerId();
SystemIdInfo newSystemIdInfo = new SystemIdInfo(workSpecId, alarmId);
systemIdInfoDao.insertSystemIdInfo(newSystemIdInfo);
setExactAlarm(context, workSpecId, alarmId, triggerAtMillis);
}
}
/**
* Cancels an existing alarm and removes the {@link SystemIdInfo}.
*
* @param context The application {@link Context}.
* @param workManager The instance of {@link WorkManagerImpl}.
* @param workSpecId The {@link androidx.work.impl.model.WorkSpec} identifier.
*/
public static void cancelAlarm(
@NonNull Context context,
@NonNull WorkManagerImpl workManager,
@NonNull String workSpecId) {
WorkDatabase workDatabase = workManager.getWorkDatabase();
SystemIdInfoDao systemIdInfoDao = workDatabase.systemIdInfoDao();
SystemIdInfo systemIdInfo = systemIdInfoDao.getSystemIdInfo(workSpecId);
if (systemIdInfo != null) {
cancelExactAlarm(context, workSpecId, systemIdInfo.systemId);
Logger.get().debug(TAG,
String.format("Removing SystemIdInfo for workSpecId (%s)", workSpecId));
systemIdInfoDao.removeSystemIdInfo(workSpecId);
}
}
private static void cancelExactAlarm(
@NonNull Context context,
@NonNull String workSpecId,
int alarmId) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent delayMet = CommandHandler.createDelayMetIntent(context, workSpecId);
PendingIntent pendingIntent = PendingIntent.getService(
context, alarmId, delayMet, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
Logger.get().debug(TAG, String.format(
"Cancelling existing alarm with (workSpecId, systemId) (%s, %s)",
workSpecId,
alarmId));
alarmManager.cancel(pendingIntent);
}
}
private static void setExactAlarm(
@NonNull Context context,
@NonNull String workSpecId,
int alarmId,
long triggerAtMillis) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent delayMet = CommandHandler.createDelayMetIntent(context, workSpecId);
PendingIntent pendingIntent = PendingIntent.getService(
context, alarmId, delayMet, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarmManager != null) {
if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(RTC_WAKEUP, triggerAtMillis, pendingIntent);
} else {
alarmManager.set(RTC_WAKEUP, triggerAtMillis, pendingIntent);
}
}
}
private Alarms() {
}
}