WorkTimer.java revision accafea75309628ec2456574bcaff8c97411187b
1accafea75309628ec2456574bcaff8c97411187bJan Clarin/* 2accafea75309628ec2456574bcaff8c97411187bJan Clarin * Copyright 2018 The Android Open Source Project 3accafea75309628ec2456574bcaff8c97411187bJan Clarin * 4accafea75309628ec2456574bcaff8c97411187bJan Clarin * Licensed under the Apache License, Version 2.0 (the "License"); 5accafea75309628ec2456574bcaff8c97411187bJan Clarin * you may not use this file except in compliance with the License. 6accafea75309628ec2456574bcaff8c97411187bJan Clarin * You may obtain a copy of the License at 7accafea75309628ec2456574bcaff8c97411187bJan Clarin * 8accafea75309628ec2456574bcaff8c97411187bJan Clarin * http://www.apache.org/licenses/LICENSE-2.0 9accafea75309628ec2456574bcaff8c97411187bJan Clarin * 10accafea75309628ec2456574bcaff8c97411187bJan Clarin * Unless required by applicable law or agreed to in writing, software 11accafea75309628ec2456574bcaff8c97411187bJan Clarin * distributed under the License is distributed on an "AS IS" BASIS, 12accafea75309628ec2456574bcaff8c97411187bJan Clarin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13accafea75309628ec2456574bcaff8c97411187bJan Clarin * See the License for the specific language governing permissions and 14accafea75309628ec2456574bcaff8c97411187bJan Clarin * limitations under the License. 15accafea75309628ec2456574bcaff8c97411187bJan Clarin */ 16accafea75309628ec2456574bcaff8c97411187bJan Clarin 17accafea75309628ec2456574bcaff8c97411187bJan Clarinpackage android.arch.background.workmanager.impl.background.systemalarm; 18accafea75309628ec2456574bcaff8c97411187bJan Clarin 19accafea75309628ec2456574bcaff8c97411187bJan Clarinimport android.arch.background.workmanager.BaseWork; 20accafea75309628ec2456574bcaff8c97411187bJan Clarinimport android.arch.background.workmanager.impl.logger.Logger; 21accafea75309628ec2456574bcaff8c97411187bJan Clarinimport android.support.annotation.NonNull; 22accafea75309628ec2456574bcaff8c97411187bJan Clarinimport android.support.annotation.RestrictTo; 23accafea75309628ec2456574bcaff8c97411187bJan Clarin 24accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.Map; 25accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.concurrent.ConcurrentHashMap; 26accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.concurrent.Executors; 27accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.concurrent.Future; 28accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.concurrent.ScheduledExecutorService; 29accafea75309628ec2456574bcaff8c97411187bJan Clarinimport java.util.concurrent.TimeUnit; 30accafea75309628ec2456574bcaff8c97411187bJan Clarin 31accafea75309628ec2456574bcaff8c97411187bJan Clarin/** 32accafea75309628ec2456574bcaff8c97411187bJan Clarin * Manages timers to enforce a time limit for processing {@link BaseWork}. Notifies a 33accafea75309628ec2456574bcaff8c97411187bJan Clarin * {@link TimeLimitExceededListener} when the time limit is exceeded. 34accafea75309628ec2456574bcaff8c97411187bJan Clarin * 35accafea75309628ec2456574bcaff8c97411187bJan Clarin * @hide 36accafea75309628ec2456574bcaff8c97411187bJan Clarin */ 37accafea75309628ec2456574bcaff8c97411187bJan Clarin@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 38accafea75309628ec2456574bcaff8c97411187bJan Clarinpublic class WorkTimer { 39accafea75309628ec2456574bcaff8c97411187bJan Clarin private static final String TAG = "WorkTimer"; 40accafea75309628ec2456574bcaff8c97411187bJan Clarin 41accafea75309628ec2456574bcaff8c97411187bJan Clarin private final Map<String, Future<?>> mWorkIdTimerMap = new ConcurrentHashMap<>(); 42accafea75309628ec2456574bcaff8c97411187bJan Clarin private final ScheduledExecutorService mScheduledExecutorService = 43accafea75309628ec2456574bcaff8c97411187bJan Clarin Executors.newSingleThreadScheduledExecutor(); 44accafea75309628ec2456574bcaff8c97411187bJan Clarin 45accafea75309628ec2456574bcaff8c97411187bJan Clarin private TimeLimitExceededListener mListener; 46accafea75309628ec2456574bcaff8c97411187bJan Clarin 47accafea75309628ec2456574bcaff8c97411187bJan Clarin /** Must be public for mocking */ 48accafea75309628ec2456574bcaff8c97411187bJan Clarin public void setOnTimeLimitExceededListener(@NonNull TimeLimitExceededListener listener) { 49accafea75309628ec2456574bcaff8c97411187bJan Clarin mListener = listener; 50accafea75309628ec2456574bcaff8c97411187bJan Clarin } 51accafea75309628ec2456574bcaff8c97411187bJan Clarin 52accafea75309628ec2456574bcaff8c97411187bJan Clarin /** Must be public for mocking */ 53accafea75309628ec2456574bcaff8c97411187bJan Clarin public void startTimer(@NonNull final String workSpecId, long processingTimeMillis) { 54accafea75309628ec2456574bcaff8c97411187bJan Clarin stopTimer(workSpecId); // Clear any existing timers for the workSpecId. 55accafea75309628ec2456574bcaff8c97411187bJan Clarin 56accafea75309628ec2456574bcaff8c97411187bJan Clarin mWorkIdTimerMap.put(workSpecId, mScheduledExecutorService.schedule(new Runnable() { 57accafea75309628ec2456574bcaff8c97411187bJan Clarin @Override 58accafea75309628ec2456574bcaff8c97411187bJan Clarin public void run() { 59accafea75309628ec2456574bcaff8c97411187bJan Clarin Future<?> timer = mWorkIdTimerMap.remove(workSpecId); 60accafea75309628ec2456574bcaff8c97411187bJan Clarin if (timer != null && mListener != null) { 61accafea75309628ec2456574bcaff8c97411187bJan Clarin mListener.onTimeLimitExceeded(workSpecId); 62accafea75309628ec2456574bcaff8c97411187bJan Clarin Logger.debug(TAG, "Time limit exceeded for Work %s", workSpecId); 63accafea75309628ec2456574bcaff8c97411187bJan Clarin } 64accafea75309628ec2456574bcaff8c97411187bJan Clarin } 65accafea75309628ec2456574bcaff8c97411187bJan Clarin }, processingTimeMillis, TimeUnit.MILLISECONDS)); 66accafea75309628ec2456574bcaff8c97411187bJan Clarin 67accafea75309628ec2456574bcaff8c97411187bJan Clarin Logger.debug(TAG, "Started timer for Work %s", workSpecId); 68accafea75309628ec2456574bcaff8c97411187bJan Clarin } 69accafea75309628ec2456574bcaff8c97411187bJan Clarin 70accafea75309628ec2456574bcaff8c97411187bJan Clarin /** Must be public for mocking */ 71accafea75309628ec2456574bcaff8c97411187bJan Clarin public void stopTimer(@NonNull final String workSpecId) { 72accafea75309628ec2456574bcaff8c97411187bJan Clarin Future<?> timer = mWorkIdTimerMap.remove(workSpecId); 73accafea75309628ec2456574bcaff8c97411187bJan Clarin if (timer != null) { 74accafea75309628ec2456574bcaff8c97411187bJan Clarin timer.cancel(false); 75accafea75309628ec2456574bcaff8c97411187bJan Clarin Logger.debug(TAG, "Stopped timer for Work %s", workSpecId); 76accafea75309628ec2456574bcaff8c97411187bJan Clarin } 77accafea75309628ec2456574bcaff8c97411187bJan Clarin } 78accafea75309628ec2456574bcaff8c97411187bJan Clarin 79accafea75309628ec2456574bcaff8c97411187bJan Clarin interface TimeLimitExceededListener { 80accafea75309628ec2456574bcaff8c97411187bJan Clarin void onTimeLimitExceeded(@NonNull String workSpecId); 81accafea75309628ec2456574bcaff8c97411187bJan Clarin } 82accafea75309628ec2456574bcaff8c97411187bJan Clarin} 83