1 /**
2  * Copyright (C) 2020 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.power;
18 
19 import static java.util.Objects.requireNonNull;
20 
21 import android.annotation.NonNull;
22 import android.content.Context;
23 import android.os.RemoteException;
24 import android.os.ServiceManager;
25 import android.util.ArraySet;
26 import android.util.Pair;
27 import android.util.Slog;
28 
29 import com.android.internal.statusbar.IStatusBarService;
30 
31 import java.io.PrintWriter;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.Set;
36 
37 /**
38  * Communicates with System UI to suppress the ambient display.
39  */
40 public class AmbientDisplaySuppressionController {
41     private static final String TAG = "AmbientDisplaySuppressionController";
42 
43     private final Context mContext;
44     private final Set<Pair<String, Integer>> mSuppressionTokens;
45     private IStatusBarService mStatusBarService;
46 
AmbientDisplaySuppressionController(Context context)47     AmbientDisplaySuppressionController(Context context) {
48         mContext = requireNonNull(context);
49         mSuppressionTokens = Collections.synchronizedSet(new ArraySet<>());
50     }
51 
52     /**
53      * Suppresses ambient display.
54      *
55      * @param token A persistible identifier for the ambient display suppression.
56      * @param callingUid The uid of the calling application.
57      * @param suppress If true, suppresses the ambient display. Otherwise, unsuppresses it.
58      */
suppress(@onNull String token, int callingUid, boolean suppress)59     public void suppress(@NonNull String token, int callingUid, boolean suppress) {
60         Pair<String, Integer> suppressionToken = Pair.create(requireNonNull(token), callingUid);
61 
62         if (suppress) {
63             mSuppressionTokens.add(suppressionToken);
64         } else {
65             mSuppressionTokens.remove(suppressionToken);
66         }
67 
68         try {
69             synchronized (mSuppressionTokens) {
70                 getStatusBar().suppressAmbientDisplay(isSuppressed());
71             }
72         } catch (RemoteException e) {
73             Slog.e(TAG, "Failed to suppress ambient display", e);
74         }
75     }
76 
77     /**
78      * Returns the tokens used to suppress ambient display through
79      * {@link #suppress(String, int, boolean)}.
80      *
81      * @param callingUid The uid of the calling application.
82      */
getSuppressionTokens(int callingUid)83     List<String> getSuppressionTokens(int callingUid) {
84         List<String> result = new ArrayList<>();
85         synchronized (mSuppressionTokens) {
86             for (Pair<String, Integer> token : mSuppressionTokens) {
87                 if (token.second == callingUid) {
88                     result.add(token.first);
89                 }
90             }
91         }
92         return result;
93     }
94 
95     /**
96      * Returns whether ambient display is suppressed for the given token.
97      *
98      * @param token A persistible identifier for the ambient display suppression.
99      * @param callingUid The uid of the calling application.
100      */
isSuppressed(@onNull String token, int callingUid)101     public boolean isSuppressed(@NonNull String token, int callingUid) {
102         return mSuppressionTokens.contains(Pair.create(requireNonNull(token), callingUid));
103     }
104 
105     /**
106      * Returns whether ambient display is suppressed.
107      */
isSuppressed()108     public boolean isSuppressed() {
109         return !mSuppressionTokens.isEmpty();
110     }
111 
112     /**
113      * Dumps the state of ambient display suppression and the list of suppression tokens into
114      * {@code pw}.
115      */
dump(PrintWriter pw)116     public void dump(PrintWriter pw) {
117         pw.println("AmbientDisplaySuppressionController:");
118         pw.println(" ambientDisplaySuppressed=" + isSuppressed());
119         pw.println(" mSuppressionTokens=" + mSuppressionTokens);
120     }
121 
getStatusBar()122     private synchronized IStatusBarService getStatusBar() {
123         if (mStatusBarService == null) {
124             mStatusBarService = IStatusBarService.Stub.asInterface(
125                     ServiceManager.getService(Context.STATUS_BAR_SERVICE));
126         }
127         return mStatusBarService;
128     }
129 }
130