• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 android.app;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.RequiresPermission;
23 import android.annotation.SystemApi;
24 import android.annotation.SystemService;
25 import android.annotation.TestApi;
26 import android.annotation.UnsupportedAppUsage;
27 import android.content.Context;
28 import android.os.Binder;
29 import android.os.IBinder;
30 import android.os.RemoteException;
31 import android.os.ServiceManager;
32 import android.util.Pair;
33 import android.util.Slog;
34 import android.view.View;
35 
36 import com.android.internal.statusbar.IStatusBarService;
37 
38 import java.lang.annotation.Retention;
39 import java.lang.annotation.RetentionPolicy;
40 
41 /**
42  * Allows an app to control the status bar.
43  */
44 @SystemService(Context.STATUS_BAR_SERVICE)
45 public class StatusBarManager {
46 
47     /** @hide */
48     public static final int DISABLE_EXPAND = View.STATUS_BAR_DISABLE_EXPAND;
49     /** @hide */
50     public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
51     /** @hide */
52     public static final int DISABLE_NOTIFICATION_ALERTS
53             = View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
54 
55     /** @hide */
56     @Deprecated
57     @UnsupportedAppUsage
58     public static final int DISABLE_NOTIFICATION_TICKER
59             = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
60     /** @hide */
61     public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
62     /** @hide */
63     public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
64     /** @hide */
65     public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
66     /** @hide */
67     public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
68     /** @hide */
69     public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
70     /** @hide */
71     public static final int DISABLE_SEARCH = View.STATUS_BAR_DISABLE_SEARCH;
72 
73     /** @hide */
74     @Deprecated
75     public static final int DISABLE_NAVIGATION =
76             View.STATUS_BAR_DISABLE_HOME | View.STATUS_BAR_DISABLE_RECENT;
77 
78     /** @hide */
79     public static final int DISABLE_NONE = 0x00000000;
80 
81     /** @hide */
82     public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
83             | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
84             | DISABLE_SYSTEM_INFO | DISABLE_RECENT | DISABLE_HOME | DISABLE_BACK | DISABLE_CLOCK
85             | DISABLE_SEARCH;
86 
87     /** @hide */
88     @IntDef(flag = true, prefix = {"DISABLE_"}, value = {
89             DISABLE_NONE,
90             DISABLE_EXPAND,
91             DISABLE_NOTIFICATION_ICONS,
92             DISABLE_NOTIFICATION_ALERTS,
93             DISABLE_NOTIFICATION_TICKER,
94             DISABLE_SYSTEM_INFO,
95             DISABLE_HOME,
96             DISABLE_RECENT,
97             DISABLE_BACK,
98             DISABLE_CLOCK,
99             DISABLE_SEARCH
100     })
101     @Retention(RetentionPolicy.SOURCE)
102     public @interface DisableFlags {}
103 
104     /**
105      * Flag to disable quick settings.
106      *
107      * Setting this flag disables quick settings completely, but does not disable expanding the
108      * notification shade.
109      */
110     /** @hide */
111     public static final int DISABLE2_QUICK_SETTINGS = 1;
112     /** @hide */
113     public static final int DISABLE2_SYSTEM_ICONS = 1 << 1;
114     /** @hide */
115     public static final int DISABLE2_NOTIFICATION_SHADE = 1 << 2;
116     /** @hide */
117     public static final int DISABLE2_GLOBAL_ACTIONS = 1 << 3;
118     /** @hide */
119     public static final int DISABLE2_ROTATE_SUGGESTIONS = 1 << 4;
120 
121     /** @hide */
122     public static final int DISABLE2_NONE = 0x00000000;
123 
124     /** @hide */
125     public static final int DISABLE2_MASK = DISABLE2_QUICK_SETTINGS | DISABLE2_SYSTEM_ICONS
126             | DISABLE2_NOTIFICATION_SHADE | DISABLE2_GLOBAL_ACTIONS | DISABLE2_ROTATE_SUGGESTIONS;
127 
128     /** @hide */
129     @IntDef(flag = true, prefix = { "DISABLE2_" }, value = {
130             DISABLE2_NONE,
131             DISABLE2_MASK,
132             DISABLE2_QUICK_SETTINGS,
133             DISABLE2_SYSTEM_ICONS,
134             DISABLE2_NOTIFICATION_SHADE,
135             DISABLE2_GLOBAL_ACTIONS,
136             DISABLE2_ROTATE_SUGGESTIONS
137     })
138     @Retention(RetentionPolicy.SOURCE)
139     public @interface Disable2Flags {}
140 
141     /**
142      * Default disable flags for setup
143      *
144      * @hide
145      */
146     public static final int DEFAULT_SETUP_DISABLE_FLAGS = DISABLE_NOTIFICATION_ALERTS
147             | DISABLE_HOME | DISABLE_EXPAND | DISABLE_RECENT | DISABLE_CLOCK | DISABLE_SEARCH;
148 
149     /**
150      * Default disable2 flags for setup
151      *
152      * @hide
153      */
154     public static final int DEFAULT_SETUP_DISABLE2_FLAGS = DISABLE2_ROTATE_SUGGESTIONS;
155 
156     /** @hide */
157     public static final int NAVIGATION_HINT_BACK_ALT      = 1 << 0;
158     /** @hide */
159     public static final int NAVIGATION_HINT_IME_SHOWN     = 1 << 1;
160 
161     /** @hide */
162     public static final int WINDOW_STATUS_BAR = 1;
163     /** @hide */
164     public static final int WINDOW_NAVIGATION_BAR = 2;
165 
166     /** @hide */
167     @IntDef(flag = true, prefix = { "WINDOW_" }, value = {
168         WINDOW_STATUS_BAR,
169         WINDOW_NAVIGATION_BAR
170     })
171     @Retention(RetentionPolicy.SOURCE)
172     public @interface WindowType {}
173 
174     /** @hide */
175     public static final int WINDOW_STATE_SHOWING = 0;
176     /** @hide */
177     public static final int WINDOW_STATE_HIDING = 1;
178     /** @hide */
179     public static final int WINDOW_STATE_HIDDEN = 2;
180 
181     /** @hide */
182     @IntDef(flag = true, prefix = { "WINDOW_STATE_" }, value = {
183             WINDOW_STATE_SHOWING,
184             WINDOW_STATE_HIDING,
185             WINDOW_STATE_HIDDEN
186     })
187     @Retention(RetentionPolicy.SOURCE)
188     public @interface WindowVisibleState {}
189 
190     /** @hide */
191     public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
192     /** @hide */
193     public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
194     /** @hide */
195     public static final int CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER = 2;
196 
197     @UnsupportedAppUsage
198     private Context mContext;
199     private IStatusBarService mService;
200     @UnsupportedAppUsage
201     private IBinder mToken = new Binder();
202 
203     @UnsupportedAppUsage
StatusBarManager(Context context)204     StatusBarManager(Context context) {
205         mContext = context;
206     }
207 
208     @UnsupportedAppUsage
getService()209     private synchronized IStatusBarService getService() {
210         if (mService == null) {
211             mService = IStatusBarService.Stub.asInterface(
212                     ServiceManager.getService(Context.STATUS_BAR_SERVICE));
213             if (mService == null) {
214                 Slog.w("StatusBarManager", "warning: no STATUS_BAR_SERVICE");
215             }
216         }
217         return mService;
218     }
219 
220     /**
221      * Disable some features in the status bar.  Pass the bitwise-or of the DISABLE_* flags.
222      * To re-enable everything, pass {@link #DISABLE_NONE}.
223      *
224      * @hide
225      */
226     @UnsupportedAppUsage
disable(int what)227     public void disable(int what) {
228         try {
229             final int userId = Binder.getCallingUserHandle().getIdentifier();
230             final IStatusBarService svc = getService();
231             if (svc != null) {
232                 svc.disableForUser(what, mToken, mContext.getPackageName(), userId);
233             }
234         } catch (RemoteException ex) {
235             throw ex.rethrowFromSystemServer();
236         }
237     }
238 
239     /**
240      * Disable additional status bar features. Pass the bitwise-or of the DISABLE2_* flags.
241      * To re-enable everything, pass {@link #DISABLE_NONE}.
242      *
243      * Warning: Only pass DISABLE2_* flags into this function, do not use DISABLE_* flags.
244      *
245      * @hide
246      */
disable2(@isable2Flags int what)247     public void disable2(@Disable2Flags int what) {
248         try {
249             final int userId = Binder.getCallingUserHandle().getIdentifier();
250             final IStatusBarService svc = getService();
251             if (svc != null) {
252                 svc.disable2ForUser(what, mToken, mContext.getPackageName(), userId);
253             }
254         } catch (RemoteException ex) {
255             throw ex.rethrowFromSystemServer();
256         }
257     }
258 
259     /**
260      * Expand the notifications panel.
261      *
262      * @hide
263      */
264     @UnsupportedAppUsage
expandNotificationsPanel()265     public void expandNotificationsPanel() {
266         try {
267             final IStatusBarService svc = getService();
268             if (svc != null) {
269                 svc.expandNotificationsPanel();
270             }
271         } catch (RemoteException ex) {
272             throw ex.rethrowFromSystemServer();
273         }
274     }
275 
276     /**
277      * Collapse the notifications and settings panels.
278      *
279      * @hide
280      */
281     @UnsupportedAppUsage
collapsePanels()282     public void collapsePanels() {
283         try {
284             final IStatusBarService svc = getService();
285             if (svc != null) {
286                 svc.collapsePanels();
287             }
288         } catch (RemoteException ex) {
289             throw ex.rethrowFromSystemServer();
290         }
291     }
292 
293     /**
294      * Expand the settings panel.
295      *
296      * @hide
297      */
298     @UnsupportedAppUsage
expandSettingsPanel()299     public void expandSettingsPanel() {
300         expandSettingsPanel(null);
301     }
302 
303     /**
304      * Expand the settings panel and open a subPanel. If the subpanel is null or does not have a
305      * corresponding tile, the QS panel is simply expanded
306      *
307      * @hide
308      */
309     @UnsupportedAppUsage
expandSettingsPanel(@ullable String subPanel)310     public void expandSettingsPanel(@Nullable String subPanel) {
311         try {
312             final IStatusBarService svc = getService();
313             if (svc != null) {
314                 svc.expandSettingsPanel(subPanel);
315             }
316         } catch (RemoteException ex) {
317             throw ex.rethrowFromSystemServer();
318         }
319     }
320 
321     /** @hide */
322     @UnsupportedAppUsage
setIcon(String slot, int iconId, int iconLevel, String contentDescription)323     public void setIcon(String slot, int iconId, int iconLevel, String contentDescription) {
324         try {
325             final IStatusBarService svc = getService();
326             if (svc != null) {
327                 svc.setIcon(slot, mContext.getPackageName(), iconId, iconLevel,
328                     contentDescription);
329             }
330         } catch (RemoteException ex) {
331             throw ex.rethrowFromSystemServer();
332         }
333     }
334 
335     /** @hide */
336     @UnsupportedAppUsage
removeIcon(String slot)337     public void removeIcon(String slot) {
338         try {
339             final IStatusBarService svc = getService();
340             if (svc != null) {
341                 svc.removeIcon(slot);
342             }
343         } catch (RemoteException ex) {
344             throw ex.rethrowFromSystemServer();
345         }
346     }
347 
348     /** @hide */
349     @UnsupportedAppUsage
setIconVisibility(String slot, boolean visible)350     public void setIconVisibility(String slot, boolean visible) {
351         try {
352             final IStatusBarService svc = getService();
353             if (svc != null) {
354                 svc.setIconVisibility(slot, visible);
355             }
356         } catch (RemoteException ex) {
357             throw ex.rethrowFromSystemServer();
358         }
359     }
360 
361     /**
362      * Enable or disable status bar elements (notifications, clock) which are inappropriate during
363      * device setup.
364      *
365      * @param disabled whether to apply or remove the disabled flags
366      *
367      * @hide
368      */
369     @SystemApi
370     @TestApi
371     @RequiresPermission(android.Manifest.permission.STATUS_BAR)
setDisabledForSetup(boolean disabled)372     public void setDisabledForSetup(boolean disabled) {
373         try {
374             final int userId = Binder.getCallingUserHandle().getIdentifier();
375             final IStatusBarService svc = getService();
376             if (svc != null) {
377                 svc.disableForUser(disabled ? DEFAULT_SETUP_DISABLE_FLAGS : DISABLE_NONE,
378                         mToken, mContext.getPackageName(), userId);
379                 svc.disable2ForUser(disabled ? DEFAULT_SETUP_DISABLE2_FLAGS : DISABLE2_NONE,
380                         mToken, mContext.getPackageName(), userId);
381             }
382         } catch (RemoteException ex) {
383             throw ex.rethrowFromSystemServer();
384         }
385     }
386 
387     /**
388      * Get this app's currently requested disabled components
389      *
390      * @return a new DisableInfo
391      *
392      * @hide
393      */
394     @SystemApi
395     @TestApi
396     @RequiresPermission(android.Manifest.permission.STATUS_BAR)
397     @NonNull
getDisableInfo()398     public DisableInfo getDisableInfo() {
399         try {
400             final int userId = Binder.getCallingUserHandle().getIdentifier();
401             final IStatusBarService svc = getService();
402             int[] flags = new int[] {0, 0};
403             if (svc != null) {
404                 flags = svc.getDisableFlags(mToken, userId);
405             }
406 
407             return new DisableInfo(flags[0], flags[1]);
408         } catch (RemoteException ex) {
409             throw ex.rethrowFromSystemServer();
410         }
411     }
412 
413     /** @hide */
windowStateToString(int state)414     public static String windowStateToString(int state) {
415         if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
416         if (state == WINDOW_STATE_HIDDEN) return "WINDOW_STATE_HIDDEN";
417         if (state == WINDOW_STATE_SHOWING) return "WINDOW_STATE_SHOWING";
418         return "WINDOW_STATE_UNKNOWN";
419     }
420 
421     /**
422      * DisableInfo describes this app's requested state of the StatusBar with regards to which
423      * components are enabled/disabled
424      *
425      * @hide
426      */
427     @SystemApi
428     @TestApi
429     public static final class DisableInfo {
430 
431         private boolean mStatusBarExpansion;
432         private boolean mNavigateHome;
433         private boolean mNotificationPeeking;
434         private boolean mRecents;
435         private boolean mSearch;
436 
437         /** @hide */
DisableInfo(int flags1, int flags2)438         public DisableInfo(int flags1, int flags2) {
439             mStatusBarExpansion = (flags1 & DISABLE_EXPAND) != 0;
440             mNavigateHome = (flags1 & DISABLE_HOME) != 0;
441             mNotificationPeeking = (flags1 & DISABLE_NOTIFICATION_ALERTS) != 0;
442             mRecents = (flags1 & DISABLE_RECENT) != 0;
443             mSearch = (flags1 & DISABLE_SEARCH) != 0;
444         }
445 
446         /** @hide */
DisableInfo()447         public DisableInfo() {}
448 
449         /**
450          * @return {@code true} if expanding the notification shade is disabled
451          *
452          * @hide
453          */
454         @SystemApi
455         @TestApi
isStatusBarExpansionDisabled()456         public boolean isStatusBarExpansionDisabled() {
457             return mStatusBarExpansion;
458         }
459 
460         /** * @hide */
setStatusBarExpansionDisabled(boolean disabled)461         public void setStatusBarExpansionDisabled(boolean disabled) {
462             mStatusBarExpansion = disabled;
463         }
464 
465         /**
466          * @return {@code true} if navigation home is disabled
467          *
468          * @hide
469          */
470         @SystemApi
471         @TestApi
isNavigateToHomeDisabled()472         public boolean isNavigateToHomeDisabled() {
473             return mNavigateHome;
474         }
475 
476         /** * @hide */
setNagivationHomeDisabled(boolean disabled)477         public void setNagivationHomeDisabled(boolean disabled) {
478             mNavigateHome = disabled;
479         }
480 
481         /**
482          * @return {@code true} if notification peeking (heads-up notification) is disabled
483          *
484          * @hide
485          */
486         @SystemApi
487         @TestApi
isNotificationPeekingDisabled()488         public boolean isNotificationPeekingDisabled() {
489             return mNotificationPeeking;
490         }
491 
492         /** @hide */
setNotificationPeekingDisabled(boolean disabled)493         public void setNotificationPeekingDisabled(boolean disabled) {
494             mNotificationPeeking = disabled;
495         }
496 
497         /**
498          * @return {@code true} if mRecents/overview is disabled
499          *
500          * @hide
501          */
502         @SystemApi
503         @TestApi
isRecentsDisabled()504         public boolean isRecentsDisabled() {
505             return mRecents;
506         }
507 
508         /**  @hide */
setRecentsDisabled(boolean disabled)509         public void setRecentsDisabled(boolean disabled) {
510             mRecents = disabled;
511         }
512 
513         /**
514          * @return {@code true} if mSearch is disabled
515          *
516          * @hide
517          */
518         @SystemApi
519         @TestApi
isSearchDisabled()520         public boolean isSearchDisabled() {
521             return mSearch;
522         }
523 
524         /** @hide */
setSearchDisabled(boolean disabled)525         public void setSearchDisabled(boolean disabled) {
526             mSearch = disabled;
527         }
528 
529         /**
530          * @return {@code true} if no components are disabled (default state)
531          *
532          * @hide
533          */
534         @SystemApi
535         @TestApi
areAllComponentsEnabled()536         public boolean areAllComponentsEnabled() {
537             return !mStatusBarExpansion && !mNavigateHome && !mNotificationPeeking && !mRecents
538                     && !mSearch;
539         }
540 
541         /** @hide */
setEnableAll()542         public void setEnableAll() {
543             mStatusBarExpansion = false;
544             mNavigateHome = false;
545             mNotificationPeeking = false;
546             mRecents = false;
547             mSearch = false;
548         }
549 
550         /**
551          * @return {@code true} if all status bar components are disabled
552          *
553          * @hide
554          */
areAllComponentsDisabled()555         public boolean areAllComponentsDisabled() {
556             return mStatusBarExpansion && mNavigateHome && mNotificationPeeking
557                     && mRecents && mSearch;
558         }
559 
560         /** @hide */
setDisableAll()561         public void setDisableAll() {
562             mStatusBarExpansion = true;
563             mNavigateHome = true;
564             mNotificationPeeking = true;
565             mRecents = true;
566             mSearch = true;
567         }
568 
569         @Override
toString()570         public String toString() {
571             StringBuilder sb = new StringBuilder();
572             sb.append("DisableInfo: ");
573             sb.append(" mStatusBarExpansion=").append(mStatusBarExpansion ? "disabled" : "enabled");
574             sb.append(" mNavigateHome=").append(mNavigateHome ? "disabled" : "enabled");
575             sb.append(" mNotificationPeeking=")
576                     .append(mNotificationPeeking ? "disabled" : "enabled");
577             sb.append(" mRecents=").append(mRecents ? "disabled" : "enabled");
578             sb.append(" mSearch=").append(mSearch ? "disabled" : "enabled");
579 
580             return sb.toString();
581 
582         }
583 
584         /**
585          * Convert a DisableInfo to equivalent flags
586          * @return a pair of equivalent disable flags
587          *
588          * @hide
589          */
toFlags()590         public Pair<Integer, Integer> toFlags() {
591             int disable1 = DISABLE_NONE;
592             int disable2 = DISABLE2_NONE;
593 
594             if (mStatusBarExpansion) disable1 |= DISABLE_EXPAND;
595             if (mNavigateHome) disable1 |= DISABLE_HOME;
596             if (mNotificationPeeking) disable1 |= DISABLE_NOTIFICATION_ALERTS;
597             if (mRecents) disable1 |= DISABLE_RECENT;
598             if (mSearch) disable1 |= DISABLE_SEARCH;
599 
600             return new Pair<Integer, Integer>(disable1, disable2);
601         }
602     }
603 }
604