1 /*
2  * Copyright (C) 2021 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.soundtrigger_middleware;
18 
19 import android.annotation.NonNull;
20 import android.os.Handler;
21 import android.os.HandlerThread;
22 
23 /**
24  * A simple timer, similar to java.util.Timer, but using the "uptime clock".
25  *
26  * Example usage:
27  * UptimeTimer timer = new UptimeTimer("TimerThread");
28  * UptimeTimer.Task task = timer.createTask(() -> { ... }, 100);
29  * ...
30  * // optionally, some time later:
31  * task.cancel();
32  */
33 class UptimeTimer {
34     private final Handler mHandler;
35     private final HandlerThread mHandlerThread;
36 
37     interface Task {
cancel()38         void cancel();
39     }
40 
UptimeTimer(String threadName)41     UptimeTimer(String threadName) {
42         mHandlerThread = new HandlerThread(threadName);
43         mHandlerThread.start();
44         // Blocks until looper init
45         mHandler = new Handler(mHandlerThread.getLooper());
46     }
47 
48     // Note, this method is not internally synchronized.
49     // This is safe since Handlers are internally synchronized.
createTask(@onNull Runnable runnable, long uptimeMs)50     Task createTask(@NonNull Runnable runnable, long uptimeMs) {
51         Object token = new Object();
52         TaskImpl task = new TaskImpl(mHandler, token);
53         mHandler.postDelayed(runnable, token, uptimeMs);
54         return task;
55     }
56 
quit()57     void quit() {
58         mHandlerThread.quitSafely();
59     }
60 
61     private static class TaskImpl implements Task {
62         private final Handler mHandler;
63         private final Object mToken;
64 
TaskImpl(Handler handler, Object token)65         public TaskImpl(Handler handler, Object token) {
66             mHandler = handler;
67             mToken = token;
68         }
69 
70         @Override
cancel()71         public void cancel() {
72             mHandler.removeCallbacksAndMessages(mToken);
73         }
74     };
75 }
76