1 /*
2  * Copyright (C) 2014 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.systemui.statusbar.policy;
18 
19 import android.app.AlarmManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.os.UserHandle;
25 
26 import androidx.annotation.NonNull;
27 
28 import com.android.systemui.Dumpable;
29 import com.android.systemui.broadcast.BroadcastDispatcher;
30 import com.android.systemui.dagger.SysUISingleton;
31 import com.android.systemui.dagger.qualifiers.Main;
32 import com.android.systemui.dump.DumpManager;
33 import com.android.systemui.settings.UserTracker;
34 
35 import java.io.PrintWriter;
36 import java.util.ArrayList;
37 import java.util.Date;
38 import java.util.concurrent.Executor;
39 
40 import javax.inject.Inject;
41 
42 /**
43  * Implementation of {@link NextAlarmController}
44  */
45 @SysUISingleton
46 public class NextAlarmControllerImpl extends BroadcastReceiver
47         implements NextAlarmController, Dumpable {
48 
49     private final ArrayList<NextAlarmChangeCallback> mChangeCallbacks = new ArrayList<>();
50 
51     private final UserTracker mUserTracker;
52     private AlarmManager mAlarmManager;
53     private AlarmManager.AlarmClockInfo mNextAlarm;
54 
55     private final UserTracker.Callback mUserChangedCallback =
56             new UserTracker.Callback() {
57                 @Override
58                 public void onUserChanged(int newUser, @NonNull Context userContext) {
59                     updateNextAlarm();
60                 }
61             };
62 
63     /**
64      */
65     @Inject
NextAlarmControllerImpl( @ain Executor mainExecutor, AlarmManager alarmManager, BroadcastDispatcher broadcastDispatcher, DumpManager dumpManager, UserTracker userTracker)66     public NextAlarmControllerImpl(
67             @Main Executor mainExecutor,
68             AlarmManager alarmManager,
69             BroadcastDispatcher broadcastDispatcher,
70             DumpManager dumpManager,
71             UserTracker userTracker) {
72         dumpManager.registerDumpable("NextAlarmController", this);
73         mAlarmManager = alarmManager;
74         mUserTracker = userTracker;
75         IntentFilter filter = new IntentFilter();
76         filter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
77         broadcastDispatcher.registerReceiver(this, filter, null, UserHandle.ALL);
78         mUserTracker.addCallback(mUserChangedCallback, mainExecutor);
79         updateNextAlarm();
80     }
81 
82     @Override
dump(PrintWriter pw, String[] args)83     public void dump(PrintWriter pw, String[] args) {
84         pw.print("mNextAlarm=");
85         if (mNextAlarm != null) {
86             pw.println(new Date(mNextAlarm.getTriggerTime()));
87             pw.print("  PendingIntentPkg=");
88             if (mNextAlarm.getShowIntent() != null) {
89                 pw.println(mNextAlarm.getShowIntent().getCreatorPackage());
90             } else {
91                 pw.println("showIntent=null");
92             }
93         } else {
94             pw.println("null");
95         }
96 
97         pw.println("Registered Callbacks:");
98         for (NextAlarmChangeCallback callback : mChangeCallbacks) {
99             pw.print("    "); pw.println(callback.toString());
100         }
101     }
102 
103     @Override
addCallback(@onNull NextAlarmChangeCallback cb)104     public void addCallback(@NonNull NextAlarmChangeCallback cb) {
105         mChangeCallbacks.add(cb);
106         cb.onNextAlarmChanged(mNextAlarm);
107     }
108 
109     @Override
removeCallback(@onNull NextAlarmChangeCallback cb)110     public void removeCallback(@NonNull NextAlarmChangeCallback cb) {
111         mChangeCallbacks.remove(cb);
112     }
113 
onReceive(Context context, Intent intent)114     public void onReceive(Context context, Intent intent) {
115         final String action = intent.getAction();
116         if (action.equals(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED)) {
117             updateNextAlarm();
118         }
119     }
120 
updateNextAlarm()121     private void updateNextAlarm() {
122         mNextAlarm = mAlarmManager.getNextAlarmClock(mUserTracker.getUserId());
123         fireNextAlarmChanged();
124     }
125 
fireNextAlarmChanged()126     private void fireNextAlarmChanged() {
127         int n = mChangeCallbacks.size();
128         for (int i = 0; i < n; i++) {
129             mChangeCallbacks.get(i).onNextAlarmChanged(mNextAlarm);
130         }
131     }
132 }
133