17299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn/*
27299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * Copyright (C) 2008 The Android Open Source Project
37299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn *
47299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
57299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * you may not use this file except in compliance with the License.
67299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * You may obtain a copy of the License at
77299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn *
87299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
97299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn *
107299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
117299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
127299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * See the License for the specific language governing permissions and
147299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn * limitations under the License.
157299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn */
167299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
177299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornpackage com.android.server;
187299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
197299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.Activity;
2062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brownimport android.app.ActivityManager;
217299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.ActivityManagerNative;
227299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.IUiModeManager;
237299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.Notification;
247299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.NotificationManager;
257299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.PendingIntent;
267299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.StatusBarManager;
277299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.app.UiModeManager;
287299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.BroadcastReceiver;
297299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.Context;
307299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.Intent;
317299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.IntentFilter;
327299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.pm.PackageManager;
337299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.content.res.Configuration;
34e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwoodimport android.os.BatteryManager;
357299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.os.Binder;
367299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.os.Handler;
37e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwoodimport android.os.PowerManager;
387299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.os.RemoteException;
397299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.os.ServiceManager;
405ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle;
412ccda4dc8d800c3592b4bd4d1d70a064d98dd4feDianne Hackbornimport android.provider.Settings;
4211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brownimport android.service.dreams.Sandman;
437299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport android.util.Slog;
447299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
457299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport java.io.FileDescriptor;
467299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport java.io.PrintWriter;
477299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
487299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport com.android.internal.R;
497299c41630935a2b106e73e5603579a7747f7535Dianne Hackbornimport com.android.internal.app.DisableCarModeActivity;
502416e09649eb6ab767eba458796e126196c77a34Jeff Brownimport com.android.server.TwilightService.TwilightState;
517299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
52487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brownfinal class UiModeManagerService extends IUiModeManager.Stub {
537299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private static final String TAG = UiModeManager.class.getSimpleName();
547299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private static final boolean LOG = false;
557299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5611ddf533a2165ca68002d3b48e312271b3d0dedbDaniel Sandler    // Enable launching of applications when entering the dock.
5711ddf533a2165ca68002d3b48e312271b3d0dedbDaniel Sandler    private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
58960779d3bbc6f2c767432ce48aca1e12cb0093b7John Spurlock    private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
5911ddf533a2165ca68002d3b48e312271b3d0dedbDaniel Sandler
607299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private final Context mContext;
612416e09649eb6ab767eba458796e126196c77a34Jeff Brown    private final TwilightService mTwilightService;
622416e09649eb6ab767eba458796e126196c77a34Jeff Brown    private final Handler mHandler = new Handler();
637299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
647299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    final Object mLock = new Object();
65ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
667299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
677299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
68ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
697299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private int mNightMode = UiModeManager.MODE_NIGHT_NO;
707299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private boolean mCarModeEnabled = false;
71e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    private boolean mCharging = false;
7244fcb83b38b062a650ddf556fe7f5e34905df9eaJoe Onorato    private final int mDefaultUiModeType;
73e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    private final boolean mCarModeKeepsScreenOn;
74e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    private final boolean mDeskModeKeepsScreenOn;
750cf2c8a53350a800055e76c1c9bf0a6d44480768Dianne Hackborn    private final boolean mTelevision;
767299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
777299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private boolean mComputedNightMode;
787299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private int mCurUiMode = 0;
79b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn    private int mSetUiMode = 0;
80ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
81b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn    private boolean mHoldingConfiguration = false;
827299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private Configuration mConfiguration = new Configuration();
83ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
847299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private boolean mSystemReady;
857299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
867299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private NotificationManager mNotificationManager;
877299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
887299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private StatusBarManager mStatusBarManager;
899fca9e96989bb70c3a5fa9de37681c9228c88ae6Jeff Brown
909fca9e96989bb70c3a5fa9de37681c9228c88ae6Jeff Brown    private final PowerManager mPowerManager;
91e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    private final PowerManager.WakeLock mWakeLock;
927299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
93f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn    static Intent buildHomeIntent(String category) {
94f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn        Intent intent = new Intent(Intent.ACTION_MAIN);
95f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn        intent.addCategory(category);
96f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
97f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
98f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn        return intent;
99f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn    }
100960779d3bbc6f2c767432ce48aca1e12cb0093b7John Spurlock
1017299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    // The broadcast receiver which receives the result of the ordered broadcast sent when
1027299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    // the dock state changes. The original ordered broadcast is sent with an initial result
1037299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
1047299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    // to RESULT_CANCELED, then the intent to start a dock app will not be sent.
1057299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
1067299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        @Override
1077299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        public void onReceive(Context context, Intent intent) {
1087299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            if (getResultCode() != Activity.RESULT_OK) {
10969a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                if (LOG) {
110960779d3bbc6f2c767432ce48aca1e12cb0093b7John Spurlock                    Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
11169a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                            + ": canceled: " + getResultCode());
11269a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                }
1137299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                return;
1147299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
1157299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
11662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            final int enableFlags = intent.getIntExtra("enableFlags", 0);
11762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            final int disableFlags = intent.getIntExtra("disableFlags", 0);
118b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            synchronized (mLock) {
11962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                updateAfterBroadcastLocked(intent.getAction(), enableFlags, disableFlags);
1207299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
1217299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
1227299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    };
1237299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
1247299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private final BroadcastReceiver mDockModeReceiver = new BroadcastReceiver() {
1257299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        @Override
1267299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        public void onReceive(Context context, Intent intent) {
1277299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
1287299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    Intent.EXTRA_DOCK_STATE_UNDOCKED);
1297299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            updateDockState(state);
1307299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
1317299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    };
1327299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
133e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    private final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
134e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        @Override
135e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        public void onReceive(Context context, Intent intent) {
136e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood            mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0);
137e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood            synchronized (mLock) {
138e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood                if (mSystemReady) {
139f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn                    updateLocked(0, 0);
140e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood                }
141e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood            }
142e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        }
143e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood    };
144e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood
1452416e09649eb6ab767eba458796e126196c77a34Jeff Brown    private final TwilightService.TwilightListener mTwilightListener =
1462416e09649eb6ab767eba458796e126196c77a34Jeff Brown            new TwilightService.TwilightListener() {
14757f4503e1a129d6a648f2378d36a060998a577a0Dianne Hackborn        @Override
1482416e09649eb6ab767eba458796e126196c77a34Jeff Brown        public void onTwilightStateChanged() {
1492416e09649eb6ab767eba458796e126196c77a34Jeff Brown            updateTwilight();
1507299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
1517299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    };
1527299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
1532416e09649eb6ab767eba458796e126196c77a34Jeff Brown    public UiModeManagerService(Context context, TwilightService twilight) {
1547299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        mContext = context;
1552416e09649eb6ab767eba458796e126196c77a34Jeff Brown        mTwilightService = twilight;
1567299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
1577299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        ServiceManager.addService(Context.UI_MODE_SERVICE, this);
158ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
1597299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        mContext.registerReceiver(mDockModeReceiver,
1607299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                new IntentFilter(Intent.ACTION_DOCK_EVENT));
161e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        mContext.registerReceiver(mBatteryReceiver,
162e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
163e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood
1649fca9e96989bb70c3a5fa9de37681c9228c88ae6Jeff Brown        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
1659fca9e96989bb70c3a5fa9de37681c9228c88ae6Jeff Brown        mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
1667299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
1677299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        mConfiguration.setToDefaults();
168e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood
16944fcb83b38b062a650ddf556fe7f5e34905df9eaJoe Onorato        mDefaultUiModeType = context.getResources().getInteger(
17044fcb83b38b062a650ddf556fe7f5e34905df9eaJoe Onorato                com.android.internal.R.integer.config_defaultUiModeType);
171e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        mCarModeKeepsScreenOn = (context.getResources().getInteger(
172e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood                com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1);
173e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood        mDeskModeKeepsScreenOn = (context.getResources().getInteger(
174e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood                com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
1750cf2c8a53350a800055e76c1c9bf0a6d44480768Dianne Hackborn        mTelevision = context.getPackageManager().hasSystemFeature(
1760cf2c8a53350a800055e76c1c9bf0a6d44480768Dianne Hackborn                PackageManager.FEATURE_TELEVISION);
1770cf2c8a53350a800055e76c1c9bf0a6d44480768Dianne Hackborn
1782ccda4dc8d800c3592b4bd4d1d70a064d98dd4feDianne Hackborn        mNightMode = Settings.Secure.getInt(mContext.getContentResolver(),
1792ccda4dc8d800c3592b4bd4d1d70a064d98dd4feDianne Hackborn                Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
1802416e09649eb6ab767eba458796e126196c77a34Jeff Brown
1812416e09649eb6ab767eba458796e126196c77a34Jeff Brown        mTwilightService.registerListener(mTwilightListener, mHandler);
1827299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
1837299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
184487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    @Override // Binder call
185d49258fed489bcd72a2b2a6ce3a3c38d4b2531e6Dianne Hackborn    public void disableCarMode(int flags) {
186487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        final long ident = Binder.clearCallingIdentity();
187487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        try {
188487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            synchronized (mLock) {
189487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                setCarModeLocked(false);
190487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (mSystemReady) {
191487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    updateLocked(0, flags);
192487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                }
193924e164a83056600642a3181f19094b3ecb5262dMike Lockwood            }
194487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } finally {
195487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            Binder.restoreCallingIdentity(ident);
1967299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
1977299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
1987299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
199487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    @Override // Binder call
200f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn    public void enableCarMode(int flags) {
201487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        final long ident = Binder.clearCallingIdentity();
202487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        try {
203487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            synchronized (mLock) {
204487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                setCarModeLocked(true);
205487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (mSystemReady) {
206487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    updateLocked(flags, 0);
207487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                }
208924e164a83056600642a3181f19094b3ecb5262dMike Lockwood            }
209487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } finally {
210487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            Binder.restoreCallingIdentity(ident);
2117299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2127299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
2137299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
214487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    @Override // Binder call
2157299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    public int getCurrentModeType() {
216487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        final long ident = Binder.clearCallingIdentity();
217487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        try {
218487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            synchronized (mLock) {
219487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                return mCurUiMode & Configuration.UI_MODE_TYPE_MASK;
220487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            }
221487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } finally {
222487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            Binder.restoreCallingIdentity(ident);
2237299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2247299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
225ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
226487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    @Override // Binder call
227487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    public void setNightMode(int mode) {
228487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        switch (mode) {
229487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            case UiModeManager.MODE_NIGHT_NO:
230487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            case UiModeManager.MODE_NIGHT_YES:
231487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            case UiModeManager.MODE_NIGHT_AUTO:
232487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                break;
233487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            default:
234487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                throw new IllegalArgumentException("Unknown mode: " + mode);
235487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        }
236ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
237487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        final long ident = Binder.clearCallingIdentity();
238487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        try {
239487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            synchronized (mLock) {
240487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (isDoingNightModeLocked() && mNightMode != mode) {
241487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    Settings.Secure.putInt(mContext.getContentResolver(),
242487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                            Settings.Secure.UI_NIGHT_MODE, mode);
243487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    mNightMode = mode;
244487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    updateLocked(0, 0);
245487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                }
2467299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
247487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } finally {
248487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            Binder.restoreCallingIdentity(ident);
2497299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2507299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
251ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
252487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    @Override // Binder call
253487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    public int getNightMode() {
254487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        synchronized (mLock) {
255487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            return mNightMode;
256487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        }
2577299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
258ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
2597299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    void systemReady() {
2607299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        synchronized (mLock) {
2617299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            mSystemReady = true;
2627299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
2632416e09649eb6ab767eba458796e126196c77a34Jeff Brown            updateComputedNightModeLocked();
264f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn            updateLocked(0, 0);
2657299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2667299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
2677299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
268487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private boolean isDoingNightModeLocked() {
2697299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        return mCarModeEnabled || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
2707299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
271ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
272487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private void setCarModeLocked(boolean enabled) {
2737299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mCarModeEnabled != enabled) {
2747299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            mCarModeEnabled = enabled;
2757299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2767299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
2777299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
278487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private void updateDockState(int newState) {
2797299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        synchronized (mLock) {
2807299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            if (newState != mDockState) {
2817299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                mDockState = newState;
282924e164a83056600642a3181f19094b3ecb5262dMike Lockwood                setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR);
2837299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                if (mSystemReady) {
284f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn                    updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0);
2857299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                }
2867299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
2877299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
2887299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
289e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood
290487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private static boolean isDeskDockState(int state) {
29169a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler        switch (state) {
29269a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler            case Intent.EXTRA_DOCK_STATE_DESK:
29369a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler            case Intent.EXTRA_DOCK_STATE_LE_DESK:
29469a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler            case Intent.EXTRA_DOCK_STATE_HE_DESK:
29569a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                return true;
29669a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler            default:
29769a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                return false;
29869a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler        }
29969a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler    }
30069a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler
301487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private void updateConfigurationLocked() {
30262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION : mDefaultUiModeType;
303b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        if (mCarModeEnabled) {
304b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            uiMode = Configuration.UI_MODE_TYPE_CAR;
30569a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler        } else if (isDeskDockState(mDockState)) {
306b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            uiMode = Configuration.UI_MODE_TYPE_DESK;
307b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        }
3089c9c532d3625ba2485eb4ea6924ed0a0163fd958Dianne Hackborn        if (mCarModeEnabled) {
309b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
3102416e09649eb6ab767eba458796e126196c77a34Jeff Brown                updateComputedNightModeLocked();
311b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn                uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES
312b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn                        : Configuration.UI_MODE_NIGHT_NO;
3137299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            } else {
314b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn                uiMode |= mNightMode << 4;
3157299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
316b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        } else {
317b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            // Disabling the car mode clears the night mode.
3188daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler            uiMode = (uiMode & ~Configuration.UI_MODE_NIGHT_MASK) | Configuration.UI_MODE_NIGHT_NO;
3198daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler        }
3208daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler
3218daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler        if (LOG) {
322960779d3bbc6f2c767432ce48aca1e12cb0093b7John Spurlock            Slog.d(TAG,
323960779d3bbc6f2c767432ce48aca1e12cb0093b7John Spurlock                "updateConfigurationLocked: mDockState=" + mDockState
3248daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler                + "; mCarMode=" + mCarModeEnabled
3258daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler                + "; mNightMode=" + mNightMode
3268daf2a47995b4522bceb38eef8c310268b1d91b0Daniel Sandler                + "; uiMode=" + uiMode);
327b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        }
328ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
329b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        mCurUiMode = uiMode;
33062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (!mHoldingConfiguration) {
3312ccda4dc8d800c3592b4bd4d1d70a064d98dd4feDianne Hackborn            mConfiguration.uiMode = uiMode;
33262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
33362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
334ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
335487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private void sendConfigurationLocked() {
33662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (mSetUiMode != mConfiguration.uiMode) {
33762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            mSetUiMode = mConfiguration.uiMode;
33862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
33962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            try {
34062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                ActivityManagerNative.getDefault().updateConfiguration(mConfiguration);
34162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            } catch (RemoteException e) {
34262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                Slog.w(TAG, "Failure communicating with activity manager", e);
3437299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
344b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn        }
345b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn    }
346ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
347487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown    private void updateLocked(int enableFlags, int disableFlags) {
348487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        String action = null;
349487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        String oldAction = null;
350487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
351487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            adjustStatusBarCarModeLocked();
352487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
353487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } else if (isDeskDockState(mLastBroadcastState)) {
354487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
355487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        }
356ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
357487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        if (mCarModeEnabled) {
358487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) {
359780b2603041a56800ff6e49fb14535c1b1ca8907Tobias Haamel                adjustStatusBarCarModeLocked();
360ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
361487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (oldAction != null) {
362487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
3637299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                }
364487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR;
365487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                action = UiModeManager.ACTION_ENTER_CAR_MODE;
366487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            }
367487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } else if (isDeskDockState(mDockState)) {
368487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (!isDeskDockState(mLastBroadcastState)) {
369487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (oldAction != null) {
370487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL);
3717299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                }
372487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                mLastBroadcastState = mDockState;
373487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                action = UiModeManager.ACTION_ENTER_DESK_MODE;
3747299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
375487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } else {
376487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
377487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            action = oldAction;
378487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        }
379ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
380487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        if (action != null) {
381487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (LOG) {
382487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                Slog.v(TAG, String.format(
383487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    "updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x",
384487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    action, enableFlags, disableFlags));
385487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            }
38669a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler
387487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // Send the ordered broadcast; the result receiver will receive after all
388487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // broadcasts have been sent. If any broadcast receiver changes the result
389487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // code from the initial value of RESULT_OK, then the result receiver will
390487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // not launch the corresponding dock application. This gives apps a chance
391487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // to override the behavior and stay in their app even when the device is
392487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // placed into a dock.
393487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            Intent intent = new Intent(action);
394487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            intent.putExtra("enableFlags", enableFlags);
395487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            intent.putExtra("disableFlags", disableFlags);
396487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null,
397487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    mResultReceiver, null, Activity.RESULT_OK, null, null);
398487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown
399487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // Attempting to make this transition a little more clean, we are going
400487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // to hold off on doing a configuration change until we have finished
401487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            // the broadcast and started the home activity.
402487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            mHoldingConfiguration = true;
403487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            updateConfigurationLocked();
404487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        } else {
405487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            String category = null;
406487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (mCarModeEnabled) {
407487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (ENABLE_LAUNCH_CAR_DOCK_APP
408487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                        && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
409487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    category = Intent.CATEGORY_CAR_DOCK;
410f5c5d22c471f399f215662a8e471bf02b5b6bcfaDianne Hackborn                }
411487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            } else if (isDeskDockState(mDockState)) {
412487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if (ENABLE_LAUNCH_DESK_DOCK_APP
413487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                        && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
414487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    category = Intent.CATEGORY_DESK_DOCK;
415487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                }
416487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            } else {
417487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
418487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    category = Intent.CATEGORY_HOME;
41969a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler                }
420487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            }
42169a1da4ddec90db501a54f0c4de94e9557aebd2eDaniel Sandler
422487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (LOG) {
423487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                Slog.v(TAG, "updateLocked: null action, mDockState="
424487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                        + mDockState +", category=" + category);
425d49258fed489bcd72a2b2a6ce3a3c38d4b2531e6Dianne Hackborn            }
426e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood
427487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            sendConfigurationAndStartDreamOrDockAppLocked(category);
428487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        }
429487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown
430487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        // keep screen on when charging and in car mode
431487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        boolean keepScreenOn = mCharging &&
432487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                ((mCarModeEnabled && mCarModeKeepsScreenOn) ||
433487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                 (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn));
434487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown        if (keepScreenOn != mWakeLock.isHeld()) {
435487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (keepScreenOn) {
436487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                mWakeLock.acquire();
437487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            } else {
438487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                mWakeLock.release();
439e29db6a2d2ba8d9458c88fe6c6dbb2164462773eMike Lockwood            }
4407299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
4417299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
4427299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
44362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void updateAfterBroadcastLocked(String action, int enableFlags, int disableFlags) {
44462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        // Launch a dock activity
44562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        String category = null;
44662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) {
44762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // Only launch car home when car mode is enabled and the caller
44862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // has asked us to switch to it.
44962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            if (ENABLE_LAUNCH_CAR_DOCK_APP
45062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
45162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                category = Intent.CATEGORY_CAR_DOCK;
45262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
45362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(action)) {
45462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // Only launch car home when desk mode is enabled and the caller
45562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // has asked us to switch to it.  Currently re-using the car
45662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // mode flag since we don't have a formal API for "desk mode".
45762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            if (ENABLE_LAUNCH_DESK_DOCK_APP
45862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
45962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                category = Intent.CATEGORY_DESK_DOCK;
46062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
46162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        } else {
46262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // Launch the standard home app if requested.
46362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) {
46462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                category = Intent.CATEGORY_HOME;
46562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
46662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
46762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
46862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (LOG) {
46962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            Slog.v(TAG, String.format(
47062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                "Handling broadcast result for action %s: enable=0x%08x, disable=0x%08x, "
47162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                    + "category=%s",
47262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                action, enableFlags, disableFlags, category));
47362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
47462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
47562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        sendConfigurationAndStartDreamOrDockAppLocked(category);
47662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
47762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
47862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    private void sendConfigurationAndStartDreamOrDockAppLocked(String category) {
47962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        // Update the configuration but don't send it yet.
48062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        mHoldingConfiguration = false;
48162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        updateConfigurationLocked();
48262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
48362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        // Start the dock app, if there is one.
48462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        boolean dockAppStarted = false;
48562c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        if (category != null) {
48662c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // Now we are going to be careful about switching the
48762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // configuration and starting the activity -- we need to
48862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // do this in a specific order under control of the
48962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // activity manager, to do it cleanly.  So compute the
49062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // new config, but don't set it yet, and let the
49162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // activity manager take care of both the start and config
49262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            // change.
49362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            Intent homeIntent = buildHomeIntent(category);
49411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown            if (Sandman.shouldStartDockApp(mContext, homeIntent)) {
49511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                try {
49611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                    int result = ActivityManagerNative.getDefault().startActivityWithConfig(
497f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn                            null, null, homeIntent, null, null, null, 0, 0,
49811159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                            mConfiguration, null, UserHandle.USER_CURRENT);
49911159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                    if (result >= ActivityManager.START_SUCCESS) {
50011159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                        dockAppStarted = true;
50111159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                    } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
50211159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                        Slog.e(TAG, "Could not start dock app: " + homeIntent
50311159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                                + ", startActivityWithConfig result " + result);
50411159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                    }
50511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                } catch (RemoteException ex) {
50611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown                    Slog.e(TAG, "Could not start dock app: " + homeIntent, ex);
50762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown                }
50862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown            }
50962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
51062c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
51162c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        // Send the new configuration.
51262c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        sendConfigurationLocked();
51362c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
51462c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        // If we did not start a dock app, then start dreaming if supported.
51511159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown        if (category != null && !dockAppStarted) {
51611159e9a785a143c9f3765bdf5a5ccfd77842d7aJeff Brown            Sandman.startDreamWhenDockedIfAppropriate(mContext);
51762c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown        }
51862c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown    }
51962c82e4d92cc0b856059f905d81885f7808a0e7dJeff Brown
5207299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    private void adjustStatusBarCarModeLocked() {
5217299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mStatusBarManager == null) {
522487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            mStatusBarManager = (StatusBarManager)
523487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown                    mContext.getSystemService(Context.STATUS_BAR_SERVICE);
5247299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5257299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
526089de88fc2f08d284cf8031aa33cff06011a4162Joe Onorato        // Fear not: StatusBarManagerService manages a list of requests to disable
5277299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        // features of the status bar; these are ORed together to form the
5287299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        // active disabled list. So if (for example) the device is locked and
5297299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        // the status bar should be totally disabled, the calls below will
5307299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        // have no effect until the device is unlocked.
5317299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mStatusBarManager != null) {
5327299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            mStatusBarManager.disable(mCarModeEnabled
5337299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
5347299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                : StatusBarManager.DISABLE_NONE);
5357299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5367299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5377299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mNotificationManager == null) {
5387299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            mNotificationManager = (NotificationManager)
5397299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    mContext.getSystemService(Context.NOTIFICATION_SERVICE);
5407299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5417299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5427299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mNotificationManager != null) {
5437299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            if (mCarModeEnabled) {
5447299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class);
5457299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5467299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                Notification n = new Notification();
5477299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                n.icon = R.drawable.stat_notify_car_mode;
5487299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                n.defaults = Notification.DEFAULT_LIGHTS;
5497299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                n.flags = Notification.FLAG_ONGOING_EVENT;
5507299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                n.when = 0;
5517299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                n.setLatestEventInfo(
5527299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                        mContext,
5537299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                        mContext.getString(R.string.car_mode_disable_notification_title),
5547299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                        mContext.getString(R.string.car_mode_disable_notification_message),
55550cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                        PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0,
55650cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                                null, UserHandle.CURRENT));
55750cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                mNotificationManager.notifyAsUser(null,
55850cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                        R.string.car_mode_disable_notification_title, n, UserHandle.ALL);
5597299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            } else {
56050cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                mNotificationManager.cancelAsUser(null,
56150cdf7c3069eb2cf82acbad73c322b7a5f3af4b1Dianne Hackborn                        R.string.car_mode_disable_notification_title, UserHandle.ALL);
5627299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
5637299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5647299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
5657299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5662416e09649eb6ab767eba458796e126196c77a34Jeff Brown    private void updateTwilight() {
5672416e09649eb6ab767eba458796e126196c77a34Jeff Brown        synchronized (mLock) {
568487bb6e20b96aa6920e08669a260118a40e604d5Jeff Brown            if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
5692416e09649eb6ab767eba458796e126196c77a34Jeff Brown                updateComputedNightModeLocked();
5702416e09649eb6ab767eba458796e126196c77a34Jeff Brown                updateLocked(0, 0);
5717299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            }
5727299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5732416e09649eb6ab767eba458796e126196c77a34Jeff Brown    }
5747299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn
5752416e09649eb6ab767eba458796e126196c77a34Jeff Brown    private void updateComputedNightModeLocked() {
5762416e09649eb6ab767eba458796e126196c77a34Jeff Brown        TwilightState state = mTwilightService.getCurrentState();
5772416e09649eb6ab767eba458796e126196c77a34Jeff Brown        if (state != null) {
5782416e09649eb6ab767eba458796e126196c77a34Jeff Brown            mComputedNightMode = state.isNight();
5797299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
5807299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
581ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
5827299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    @Override
5837299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
5847299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
5857299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
586ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
5877299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            pw.println("Permission Denial: can't dump uimode service from from pid="
5887299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    + Binder.getCallingPid()
5897299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    + ", uid=" + Binder.getCallingUid());
5907299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            return;
5917299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
592ba9ab183186cb2ef704759485a8481d5b8c8a650Bernd Holzhey
5937299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        synchronized (mLock) {
5947299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            pw.println("Current UI Mode Service state:");
5957299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            pw.print("  mDockState="); pw.print(mDockState);
5967299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState);
5977299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            pw.print("  mNightMode="); pw.print(mNightMode);
5987299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled);
5997299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    pw.print(" mComputedNightMode="); pw.println(mComputedNightMode);
6007299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn            pw.print("  mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode));
601b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn                    pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode));
602b8b11a0b1d82e24f7a79f2e1672e7f5cf1611a55Dianne Hackborn            pw.print("  mHoldingConfiguration="); pw.print(mHoldingConfiguration);
6037299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn                    pw.print(" mSystemReady="); pw.println(mSystemReady);
6042416e09649eb6ab767eba458796e126196c77a34Jeff Brown            pw.print("  mTwilightService.getCurrentState()=");
6052416e09649eb6ab767eba458796e126196c77a34Jeff Brown                    pw.println(mTwilightService.getCurrentState());
6067299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn        }
6077299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn    }
6087299c41630935a2b106e73e5603579a7747f7535Dianne Hackborn}
609