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 package com.android.launcher3.util; 17 18 import static android.content.Intent.ACTION_SCREEN_OFF; 19 import static android.content.Intent.ACTION_SCREEN_ON; 20 import static android.content.Intent.ACTION_USER_PRESENT; 21 22 import android.content.Context; 23 import android.content.Intent; 24 25 import java.util.concurrent.CopyOnWriteArrayList; 26 27 /** 28 * Utility class for tracking if the screen is currently on or off 29 */ 30 public class ScreenOnTracker { 31 32 public static final MainThreadInitializedObject<ScreenOnTracker> INSTANCE = 33 new MainThreadInitializedObject<>(ScreenOnTracker::new); 34 35 private final SimpleBroadcastReceiver mReceiver = new SimpleBroadcastReceiver(this::onReceive); 36 private final CopyOnWriteArrayList<ScreenOnListener> mListeners = new CopyOnWriteArrayList<>(); 37 38 private boolean mIsScreenOn; 39 ScreenOnTracker(Context context)40 private ScreenOnTracker(Context context) { 41 // Assume that the screen is on to begin with 42 mIsScreenOn = true; 43 mReceiver.register(context, ACTION_SCREEN_ON, ACTION_SCREEN_OFF, ACTION_USER_PRESENT); 44 } 45 onReceive(Intent intent)46 private void onReceive(Intent intent) { 47 String action = intent.getAction(); 48 if (ACTION_SCREEN_ON.equals(action)) { 49 mIsScreenOn = true; 50 dispatchScreenOnChanged(); 51 } else if (ACTION_SCREEN_OFF.equals(action)) { 52 mIsScreenOn = false; 53 dispatchScreenOnChanged(); 54 } else if (ACTION_USER_PRESENT.equals(action)) { 55 mListeners.forEach(ScreenOnListener::onUserPresent); 56 } 57 } 58 dispatchScreenOnChanged()59 private void dispatchScreenOnChanged() { 60 mListeners.forEach(l -> l.onScreenOnChanged(mIsScreenOn)); 61 } 62 63 /** Returns if the screen is on or not */ isScreenOn()64 public boolean isScreenOn() { 65 return mIsScreenOn; 66 } 67 68 /** Adds a listener for screen on changes */ addListener(ScreenOnListener listener)69 public void addListener(ScreenOnListener listener) { 70 mListeners.add(listener); 71 } 72 73 /** Removes a previously added listener */ removeListener(ScreenOnListener listener)74 public void removeListener(ScreenOnListener listener) { 75 mListeners.remove(listener); 76 } 77 78 /** 79 * Interface to listen for screen on changes 80 */ 81 public interface ScreenOnListener { 82 83 /** 84 * Called when the screen turns on/off 85 */ onScreenOnChanged(boolean isOn)86 void onScreenOnChanged(boolean isOn); 87 88 /** 89 * Called when the keyguard goes away 90 */ onUserPresent()91 default void onUserPresent() { } 92 } 93 } 94