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
17package android.app;
18
19import android.content.Context;
20import android.content.res.Configuration;
21import android.os.RemoteException;
22import android.os.ServiceManager;
23import 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 */
51public 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
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     * Force device into car mode, like it had been placed in the car dock.
129     * This will cause the device to switch to the car home UI as part of
130     * the mode switch.
131     * @param flags Must be 0.
132     */
133    public void enableCarMode(int flags) {
134        if (mService != null) {
135            try {
136                mService.enableCarMode(flags);
137            } catch (RemoteException e) {
138                Log.e(TAG, "disableCarMode: RemoteException", e);
139            }
140        }
141    }
142
143    /**
144     * Flag for use with {@link #disableCarMode(int)}: go to the normal
145     * home activity as part of the disable.  Disabling this way ensures
146     * a clean transition between the current activity (in car mode) and
147     * the original home activity (which was typically last running without
148     * being in car mode).
149     */
150    public static final int DISABLE_CAR_MODE_GO_HOME = 0x0001;
151
152    /**
153     * Turn off special mode if currently in car mode.
154     * @param flags May be 0 or {@link #DISABLE_CAR_MODE_GO_HOME}.
155     */
156    public void disableCarMode(int flags) {
157        if (mService != null) {
158            try {
159                mService.disableCarMode(flags);
160            } catch (RemoteException e) {
161                Log.e(TAG, "disableCarMode: RemoteException", e);
162            }
163        }
164    }
165
166    /**
167     * Return the current running mode type.  May be one of
168     * {@link Configuration#UI_MODE_TYPE_NORMAL Configuration.UI_MODE_TYPE_NORMAL},
169     * {@link Configuration#UI_MODE_TYPE_DESK Configuration.UI_MODE_TYPE_DESK}, or
170     * {@link Configuration#UI_MODE_TYPE_CAR Configuration.UI_MODE_TYPE_CAR}, or
171     * {@link Configuration#UI_MODE_TYPE_TELEVISION Configuration.UI_MODE_TYPE_APPLIANCE}.
172     */
173    public int getCurrentModeType() {
174        if (mService != null) {
175            try {
176                return mService.getCurrentModeType();
177            } catch (RemoteException e) {
178                Log.e(TAG, "getCurrentModeType: RemoteException", e);
179            }
180        }
181        return Configuration.UI_MODE_TYPE_NORMAL;
182    }
183
184    /**
185     * Sets the night mode.  Changes to the night mode are only effective when
186     * the car or desk mode is enabled on a device.
187     *
188     * <p>The mode can be one of:
189     * <ul>
190     *   <li><em>{@link #MODE_NIGHT_NO}<em> - sets the device into notnight
191     *       mode.</li>
192     *   <li><em>{@link #MODE_NIGHT_YES}</em> - sets the device into night mode.
193     *   </li>
194     *   <li><em>{@link #MODE_NIGHT_AUTO}</em> - automatic night/notnight switching
195     *       depending on the location and certain other sensors.</li>
196     * </ul>
197     */
198    public void setNightMode(int mode) {
199        if (mService != null) {
200            try {
201                mService.setNightMode(mode);
202            } catch (RemoteException e) {
203                Log.e(TAG, "setNightMode: RemoteException", e);
204            }
205        }
206    }
207
208    /**
209     * Returns the currently configured night mode.
210     *
211     * @return {@link #MODE_NIGHT_NO}, {@link #MODE_NIGHT_YES}, or
212     *  {@link #MODE_NIGHT_AUTO}.  When an error occurred -1 is returned.
213     */
214    public int getNightMode() {
215        if (mService != null) {
216            try {
217                return mService.getNightMode();
218            } catch (RemoteException e) {
219                Log.e(TAG, "getNightMode: RemoteException", e);
220            }
221        }
222        return -1;
223    }
224}
225