1 /*
2  * Copyright (C) 2023 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.wifi;
18 
19 import android.content.BroadcastReceiver;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.IntentFilter;
23 import android.os.Handler;
24 import android.os.PowerManager;
25 import android.text.TextUtils;
26 import android.util.ArraySet;
27 
28 import java.util.Set;
29 
30 /** A centralized manager to handle all the device state changes */
31 public class WifiDeviceStateChangeManager {
32     private final Handler mHandler;
33     private final Context mContext;
34 
35     private final PowerManager mPowerManager;
36     private final Set<StateChangeCallback> mChangeCallbackList = new ArraySet<>();
37     private boolean mIsWifiServiceStarted = false;
38 
39     /**
40      * Callback to receive the device state change event. Caller should implement the method to
41      * listen to the interested event
42      */
43     public interface StateChangeCallback {
44         /**
45          * Called when the screen state changes
46          *
47          * @param screenOn true for ON, false otherwise
48          */
onScreenStateChanged(boolean screenOn)49         default void onScreenStateChanged(boolean screenOn) {}
50     }
51 
52     /** Create the instance of WifiDeviceStateChangeManager. */
WifiDeviceStateChangeManager(Context context, Handler handler)53     public WifiDeviceStateChangeManager(Context context, Handler handler) {
54         mHandler = handler;
55         mContext = context;
56         mPowerManager = mContext.getSystemService(PowerManager.class);
57     }
58 
59     /** Handle the boot completed event. Start to register the receiver and callback. */
handleBootCompleted()60     public void handleBootCompleted() {
61         IntentFilter filter = new IntentFilter();
62         filter.addAction(Intent.ACTION_SCREEN_ON);
63         filter.addAction(Intent.ACTION_SCREEN_OFF);
64         mContext.registerReceiver(
65                 new BroadcastReceiver() {
66                     @Override
67                     public void onReceive(Context context, Intent intent) {
68                         String action = intent.getAction();
69                         if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)
70                                 || TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)) {
71                             mHandler.post(() ->
72                                     handleScreenStateChanged(TextUtils.equals(action,
73                                             Intent.ACTION_SCREEN_ON)));
74                         }
75                     }
76                 },
77                 filter);
78         handleScreenStateChanged(mPowerManager.isInteractive());
79         mIsWifiServiceStarted = true;
80     }
81 
82     /**
83      * Register a state change callback. When the state is changed, caller with receive the callback
84      * event
85      */
registerStateChangeCallback(StateChangeCallback callback)86     public void registerStateChangeCallback(StateChangeCallback callback) {
87         mChangeCallbackList.add(callback);
88         if (!mIsWifiServiceStarted) return;
89         callback.onScreenStateChanged(mPowerManager.isInteractive());
90     }
91 
92     /**
93      * Unregister a state change callback when caller is not interested the state change anymore.
94      */
unregisterStateChangeCallback(StateChangeCallback callback)95     public void unregisterStateChangeCallback(StateChangeCallback callback) {
96         mChangeCallbackList.remove(callback);
97     }
98 
handleScreenStateChanged(boolean screenOn)99     private void handleScreenStateChanged(boolean screenOn) {
100         for (StateChangeCallback callback : mChangeCallbackList) {
101             callback.onScreenStateChanged(screenOn);
102         }
103     }
104 }
105