1 /*
2  * Copyright (C) 2010 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.content.Context;
20 import android.content.res.Configuration;
21 import android.os.RemoteException;
22 import android.os.ServiceManager;
23 import android.util.Log;
24 
25 /**
26  * This class provides access to the system uimode services.  These services
27  * allow applications to control UI modes of the device.
28  * It provides functionality to disable the car mode and it gives access to the
29  * night mode settings.
30  *
31  * <p>These facilities are built on top of the underlying
32  * {@link android.content.Intent#ACTION_DOCK_EVENT} broadcasts that are sent when the user
33  * physical places the device into and out of a dock.  When that happens,
34  * the UiModeManager switches the system {@link android.content.res.Configuration}
35  * to the appropriate UI mode, sends broadcasts about the mode switch, and
36  * starts the corresponding mode activity if appropriate.  See the
37  * broadcasts {@link #ACTION_ENTER_CAR_MODE} and
38  * {@link #ACTION_ENTER_DESK_MODE} for more information.
39  *
40  * <p>In addition, the user may manually switch the system to car mode without
41  * physically being in a dock.  While in car mode -- whether by manual action
42  * from the user or being physically placed in a dock -- a notification is
43  * displayed allowing the user to exit dock mode.  Thus the dock mode
44  * represented here may be different than the current state of the underlying
45  * dock event broadcast.
46  *
47  * <p>You do not instantiate this class directly; instead, retrieve it through
48  * {@link android.content.Context#getSystemService
49  * Context.getSystemService(Context.UI_MODE_SERVICE)}.
50  */
51 public class UiModeManager {
52     private static final String TAG = "UiModeManager";
53 
54     /**
55      * Broadcast sent when the device's UI has switched to car mode, either
56      * by being placed in a car dock or explicit action of the user.  After
57      * sending the broadcast, the system will start the intent
58      * {@link android.content.Intent#ACTION_MAIN} with category
59      * {@link android.content.Intent#CATEGORY_CAR_DOCK}
60      * to display the car UI, which typically what an application would
61      * implement to provide their own interface.  However, applications can
62      * also monitor this Intent in order to be informed of mode changes or
63      * prevent the normal car UI from being displayed by setting the result
64      * of the broadcast to {@link Activity#RESULT_CANCELED}.
65      */
66     public static String ACTION_ENTER_CAR_MODE = "android.app.action.ENTER_CAR_MODE";
67 
68     /**
69      * Broadcast sent when the device's UI has switch away from car mode back
70      * to normal mode.  Typically used by a car mode app, to dismiss itself
71      * when the user exits car mode.
72      */
73     public static String ACTION_EXIT_CAR_MODE = "android.app.action.EXIT_CAR_MODE";
74 
75     /**
76      * Broadcast sent when the device's UI has switched to desk mode,
77      * by being placed in a desk dock.  After
78      * sending the broadcast, the system will start the intent
79      * {@link android.content.Intent#ACTION_MAIN} with category
80      * {@link android.content.Intent#CATEGORY_DESK_DOCK}
81      * to display the desk UI, which typically what an application would
82      * implement to provide their own interface.  However, applications can
83      * also monitor this Intent in order to be informed of mode changes or
84      * prevent the normal desk UI from being displayed by setting the result
85      * of the broadcast to {@link Activity#RESULT_CANCELED}.
86      */
87     public static String ACTION_ENTER_DESK_MODE = "android.app.action.ENTER_DESK_MODE";
88 
89     /**
90      * Broadcast sent when the device's UI has switched away from desk mode back
91      * to normal mode.  Typically used by a desk mode app, to dismiss itself
92      * when the user exits desk mode.
93      */
94     public static String ACTION_EXIT_DESK_MODE = "android.app.action.EXIT_DESK_MODE";
95 
96     /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
97      * automatically switch night mode on and off based on the time.
98      */
99     public static final int MODE_NIGHT_AUTO = Configuration.UI_MODE_NIGHT_UNDEFINED >> 4;
100 
101     /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
102      * never run in night mode.
103      */
104     public static final int MODE_NIGHT_NO = Configuration.UI_MODE_NIGHT_NO >> 4;
105 
106     /** Constant for {@link #setNightMode(int)} and {@link #getNightMode()}:
107      * always run in night mode.
108      */
109     public static final int MODE_NIGHT_YES = Configuration.UI_MODE_NIGHT_YES >> 4;
110 
111     private IUiModeManager mService;
112 
UiModeManager()113     /*package*/ UiModeManager() {
114         mService = IUiModeManager.Stub.asInterface(
115                 ServiceManager.getService(Context.UI_MODE_SERVICE));
116     }
117 
118     /**
119      * Flag for use with {@link #enableCarMode(int)}: go to the car
120      * home activity as part of the enable.  Enabling this way ensures
121      * a clean transition between the current activity (in non-car-mode) and
122      * the car home activity that will serve as home while in car mode.  This
123      * will switch to the car home activity even if we are already in car mode.
124      */
125     public static final int ENABLE_CAR_MODE_GO_CAR_HOME = 0x0001;
126 
127     /**
128      * Flag for use with {@link #enableCarMode(int)}: allow sleep mode while in car mode.
129      * By default, when this flag is not set, the system may hold a full wake lock to keep the
130      * screen turned on and prevent the system from entering sleep mode while in car mode.
131      * Setting this flag disables such behavior and the system may enter sleep mode
132      * if there is no other user activity and no other wake lock held.
133      * Setting this flag can be relevant for a car dock application that does not require the
134      * screen kept on.
135      */
136     public static final int ENABLE_CAR_MODE_ALLOW_SLEEP = 0x0002;
137 
138     /**
139      * Force device into car mode, like it had been placed in the car dock.
140      * This will cause the device to switch to the car home UI as part of
141      * the mode switch.
142      * @param flags Must be 0.
143      */
enableCarMode(int flags)144     public void enableCarMode(int flags) {
145         if (mService != null) {
146             try {
147                 mService.enableCarMode(flags);
148             } catch (RemoteException e) {
149                 Log.e(TAG, "disableCarMode: RemoteException", e);
150             }
151         }
152     }
153 
154     /**
155      * Flag for use with {@link #disableCarMode(int)}: go to the normal
156      * home activity as part of the disable.  Disabling this way ensures
157      * a clean transition between the current activity (in car mode) and
158      * the original home activity (which was typically last running without
159      * being in car mode).
160      */
161     public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
162 
163     /**
164      * Turn off special mode if currently in car mode.
165      * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}.
166      */
disableCarMode(int flags)167     public void disableCarMode(int flags) {
168         if (mService != null) {
169             try {
170                 mService.disableCarMode(flags);
171             } catch (RemoteException e) {
172                 Log.e(TAG, "disableCarMode: RemoteException", e);
173             }
174         }
175     }
176 
177     /**
178      * Return the current running mode type.  May be one of
179      * {@link Configuration#UI_MODE_TYPE_NORMAL Configuration.UI_MODE_TYPE_NORMAL},
180      * {@link Configuration#UI_MODE_TYPE_DESK Configuration.UI_MODE_TYPE_DESK},
181      * {@link Configuration#UI_MODE_TYPE_CAR Configuration.UI_MODE_TYPE_CAR},
182      * {@link Configuration#UI_MODE_TYPE_TELEVISION Configuration.UI_MODE_TYPE_TELEVISION},
183      * {@link Configuration#UI_MODE_TYPE_APPLIANCE Configuration.UI_MODE_TYPE_APPLIANCE}, or
184      * {@link Configuration#UI_MODE_TYPE_WATCH Configuration.UI_MODE_TYPE_WATCH}.
185      */
getCurrentModeType()186     public int getCurrentModeType() {
187         if (mService != null) {
188             try {
189                 return mService.getCurrentModeType();
190             } catch (RemoteException e) {
191                 Log.e(TAG, "getCurrentModeType: RemoteException", e);
192             }
193         }
194         return Configuration.UI_MODE_TYPE_NORMAL;
195     }
196 
197     /**
198      * Sets the night mode.  Changes to the night mode are only effective when
199      * the car or desk mode is enabled on a device.
200      *
201      * <p>The mode can be one of:
202      * <ul>
203      *   <li><em>{@link #MODE_NIGHT_NO}<em> - sets the device into notnight
204      *       mode.</li>
205      *   <li><em>{@link #MODE_NIGHT_YES}</em> - sets the device into night mode.
206      *   </li>
207      *   <li><em>{@link #MODE_NIGHT_AUTO}</em> - automatic night/notnight switching
208      *       depending on the location and certain other sensors.</li>
209      * </ul>
210      */
setNightMode(int mode)211     public void setNightMode(int mode) {
212         if (mService != null) {
213             try {
214                 mService.setNightMode(mode);
215             } catch (RemoteException e) {
216                 Log.e(TAG, "setNightMode: RemoteException", e);
217             }
218         }
219     }
220 
221     /**
222      * @return the currently configured night mode. May be one of
223      *         {@link #MODE_NIGHT_NO}, {@link #MODE_NIGHT_YES},
224      *         {@link #MODE_NIGHT_AUTO}, or -1 on error.
225      */
getNightMode()226     public int getNightMode() {
227         if (mService != null) {
228             try {
229                 return mService.getNightMode();
230             } catch (RemoteException e) {
231                 Log.e(TAG, "getNightMode: RemoteException", e);
232             }
233         }
234         return -1;
235     }
236 }
237