diff options
Diffstat (limited to 'services/java/com/android/server/UiModeManagerService.java')
-rw-r--r-- | services/java/com/android/server/UiModeManagerService.java | 608 |
1 files changed, 0 insertions, 608 deletions
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java deleted file mode 100644 index 062be01..0000000 --- a/services/java/com/android/server/UiModeManagerService.java +++ /dev/null @@ -1,608 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.ActivityManagerNative; -import android.app.IUiModeManager; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.StatusBarManager; -import android.app.UiModeManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.os.BatteryManager; -import android.os.Binder; -import android.os.Handler; -import android.os.PowerManager; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.UserHandle; -import android.provider.Settings; -import android.service.dreams.Sandman; -import android.util.Slog; - -import java.io.FileDescriptor; -import java.io.PrintWriter; - -import com.android.internal.R; -import com.android.internal.app.DisableCarModeActivity; -import com.android.server.TwilightService.TwilightState; - -final class UiModeManagerService extends IUiModeManager.Stub { - private static final String TAG = UiModeManager.class.getSimpleName(); - private static final boolean LOG = false; - - // Enable launching of applications when entering the dock. - private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true; - private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true; - - private final Context mContext; - private final TwilightService mTwilightService; - private final Handler mHandler = new Handler(); - - final Object mLock = new Object(); - - private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; - private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; - - private int mNightMode = UiModeManager.MODE_NIGHT_NO; - private boolean mCarModeEnabled = false; - private boolean mCharging = false; - private final int mDefaultUiModeType; - private final boolean mCarModeKeepsScreenOn; - private final boolean mDeskModeKeepsScreenOn; - private final boolean mTelevision; - - private boolean mComputedNightMode; - private int mCurUiMode = 0; - private int mSetUiMode = 0; - - private boolean mHoldingConfiguration = false; - private Configuration mConfiguration = new Configuration(); - - private boolean mSystemReady; - - private NotificationManager mNotificationManager; - - private StatusBarManager mStatusBarManager; - - private final PowerManager mPowerManager; - private final PowerManager.WakeLock mWakeLock; - - static Intent buildHomeIntent(String category) { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(category); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - return intent; - } - - // The broadcast receiver which receives the result of the ordered broadcast sent when - // the dock state changes. The original ordered broadcast is sent with an initial result - // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g., - // to RESULT_CANCELED, then the intent to start a dock app will not be sent. - private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (getResultCode() != Activity.RESULT_OK) { - if (LOG) { - Slog.v(TAG, "Handling broadcast result for action " + intent.getAction() - + ": canceled: " + getResultCode()); - } - return; - } - - final int enableFlags = intent.getIntExtra("enableFlags", 0); - final int disableFlags = intent.getIntExtra("disableFlags", 0); - synchronized (mLock) { - updateAfterBroadcastLocked(intent.getAction(), enableFlags, disableFlags); - } - } - }; - - private final BroadcastReceiver mDockModeReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, - Intent.EXTRA_DOCK_STATE_UNDOCKED); - updateDockState(state); - } - }; - - private final BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - mCharging = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0); - synchronized (mLock) { - if (mSystemReady) { - updateLocked(0, 0); - } - } - } - }; - - private final TwilightService.TwilightListener mTwilightListener = - new TwilightService.TwilightListener() { - @Override - public void onTwilightStateChanged() { - updateTwilight(); - } - }; - - public UiModeManagerService(Context context, TwilightService twilight) { - mContext = context; - mTwilightService = twilight; - - ServiceManager.addService(Context.UI_MODE_SERVICE, this); - - mContext.registerReceiver(mDockModeReceiver, - new IntentFilter(Intent.ACTION_DOCK_EVENT)); - mContext.registerReceiver(mBatteryReceiver, - new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - - mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); - - mConfiguration.setToDefaults(); - - mDefaultUiModeType = context.getResources().getInteger( - com.android.internal.R.integer.config_defaultUiModeType); - mCarModeKeepsScreenOn = (context.getResources().getInteger( - com.android.internal.R.integer.config_carDockKeepsScreenOn) == 1); - mDeskModeKeepsScreenOn = (context.getResources().getInteger( - com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1); - mTelevision = context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_TELEVISION); - - mNightMode = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO); - - mTwilightService.registerListener(mTwilightListener, mHandler); - } - - @Override // Binder call - public void disableCarMode(int flags) { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - setCarModeLocked(false); - if (mSystemReady) { - updateLocked(0, flags); - } - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override // Binder call - public void enableCarMode(int flags) { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - setCarModeLocked(true); - if (mSystemReady) { - updateLocked(flags, 0); - } - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override // Binder call - public int getCurrentModeType() { - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - return mCurUiMode & Configuration.UI_MODE_TYPE_MASK; - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override // Binder call - public void setNightMode(int mode) { - switch (mode) { - case UiModeManager.MODE_NIGHT_NO: - case UiModeManager.MODE_NIGHT_YES: - case UiModeManager.MODE_NIGHT_AUTO: - break; - default: - throw new IllegalArgumentException("Unknown mode: " + mode); - } - - final long ident = Binder.clearCallingIdentity(); - try { - synchronized (mLock) { - if (isDoingNightModeLocked() && mNightMode != mode) { - Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.UI_NIGHT_MODE, mode); - mNightMode = mode; - updateLocked(0, 0); - } - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - - @Override // Binder call - public int getNightMode() { - synchronized (mLock) { - return mNightMode; - } - } - - void systemReady() { - synchronized (mLock) { - mSystemReady = true; - mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; - updateComputedNightModeLocked(); - updateLocked(0, 0); - } - } - - private boolean isDoingNightModeLocked() { - return mCarModeEnabled || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED; - } - - private void setCarModeLocked(boolean enabled) { - if (mCarModeEnabled != enabled) { - mCarModeEnabled = enabled; - } - } - - private void updateDockState(int newState) { - synchronized (mLock) { - if (newState != mDockState) { - mDockState = newState; - setCarModeLocked(mDockState == Intent.EXTRA_DOCK_STATE_CAR); - if (mSystemReady) { - updateLocked(UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME, 0); - } - } - } - } - - private static boolean isDeskDockState(int state) { - switch (state) { - case Intent.EXTRA_DOCK_STATE_DESK: - case Intent.EXTRA_DOCK_STATE_LE_DESK: - case Intent.EXTRA_DOCK_STATE_HE_DESK: - return true; - default: - return false; - } - } - - private void updateConfigurationLocked() { - int uiMode = mTelevision ? Configuration.UI_MODE_TYPE_TELEVISION : mDefaultUiModeType; - if (mCarModeEnabled) { - uiMode = Configuration.UI_MODE_TYPE_CAR; - } else if (isDeskDockState(mDockState)) { - uiMode = Configuration.UI_MODE_TYPE_DESK; - } - if (mCarModeEnabled) { - if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { - updateComputedNightModeLocked(); - uiMode |= mComputedNightMode ? Configuration.UI_MODE_NIGHT_YES - : Configuration.UI_MODE_NIGHT_NO; - } else { - uiMode |= mNightMode << 4; - } - } else { - // Disabling the car mode clears the night mode. - uiMode = (uiMode & ~Configuration.UI_MODE_NIGHT_MASK) | Configuration.UI_MODE_NIGHT_NO; - } - - if (LOG) { - Slog.d(TAG, - "updateConfigurationLocked: mDockState=" + mDockState - + "; mCarMode=" + mCarModeEnabled - + "; mNightMode=" + mNightMode - + "; uiMode=" + uiMode); - } - - mCurUiMode = uiMode; - if (!mHoldingConfiguration) { - mConfiguration.uiMode = uiMode; - } - } - - private void sendConfigurationLocked() { - if (mSetUiMode != mConfiguration.uiMode) { - mSetUiMode = mConfiguration.uiMode; - - try { - ActivityManagerNative.getDefault().updateConfiguration(mConfiguration); - } catch (RemoteException e) { - Slog.w(TAG, "Failure communicating with activity manager", e); - } - } - } - - private void updateLocked(int enableFlags, int disableFlags) { - String action = null; - String oldAction = null; - if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) { - adjustStatusBarCarModeLocked(); - oldAction = UiModeManager.ACTION_EXIT_CAR_MODE; - } else if (isDeskDockState(mLastBroadcastState)) { - oldAction = UiModeManager.ACTION_EXIT_DESK_MODE; - } - - if (mCarModeEnabled) { - if (mLastBroadcastState != Intent.EXTRA_DOCK_STATE_CAR) { - adjustStatusBarCarModeLocked(); - - if (oldAction != null) { - mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); - } - mLastBroadcastState = Intent.EXTRA_DOCK_STATE_CAR; - action = UiModeManager.ACTION_ENTER_CAR_MODE; - } - } else if (isDeskDockState(mDockState)) { - if (!isDeskDockState(mLastBroadcastState)) { - if (oldAction != null) { - mContext.sendBroadcastAsUser(new Intent(oldAction), UserHandle.ALL); - } - mLastBroadcastState = mDockState; - action = UiModeManager.ACTION_ENTER_DESK_MODE; - } - } else { - mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; - action = oldAction; - } - - if (action != null) { - if (LOG) { - Slog.v(TAG, String.format( - "updateLocked: preparing broadcast: action=%s enable=0x%08x disable=0x%08x", - action, enableFlags, disableFlags)); - } - - // Send the ordered broadcast; the result receiver will receive after all - // broadcasts have been sent. If any broadcast receiver changes the result - // code from the initial value of RESULT_OK, then the result receiver will - // not launch the corresponding dock application. This gives apps a chance - // to override the behavior and stay in their app even when the device is - // placed into a dock. - Intent intent = new Intent(action); - intent.putExtra("enableFlags", enableFlags); - intent.putExtra("disableFlags", disableFlags); - mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, - mResultReceiver, null, Activity.RESULT_OK, null, null); - - // Attempting to make this transition a little more clean, we are going - // to hold off on doing a configuration change until we have finished - // the broadcast and started the home activity. - mHoldingConfiguration = true; - updateConfigurationLocked(); - } else { - String category = null; - if (mCarModeEnabled) { - if (ENABLE_LAUNCH_CAR_DOCK_APP - && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { - category = Intent.CATEGORY_CAR_DOCK; - } - } else if (isDeskDockState(mDockState)) { - if (ENABLE_LAUNCH_DESK_DOCK_APP - && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { - category = Intent.CATEGORY_DESK_DOCK; - } - } else { - if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) { - category = Intent.CATEGORY_HOME; - } - } - - if (LOG) { - Slog.v(TAG, "updateLocked: null action, mDockState=" - + mDockState +", category=" + category); - } - - sendConfigurationAndStartDreamOrDockAppLocked(category); - } - - // keep screen on when charging and in car mode - boolean keepScreenOn = mCharging && - ((mCarModeEnabled && mCarModeKeepsScreenOn) || - (mCurUiMode == Configuration.UI_MODE_TYPE_DESK && mDeskModeKeepsScreenOn)); - if (keepScreenOn != mWakeLock.isHeld()) { - if (keepScreenOn) { - mWakeLock.acquire(); - } else { - mWakeLock.release(); - } - } - } - - private void updateAfterBroadcastLocked(String action, int enableFlags, int disableFlags) { - // Launch a dock activity - String category = null; - if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(action)) { - // Only launch car home when car mode is enabled and the caller - // has asked us to switch to it. - if (ENABLE_LAUNCH_CAR_DOCK_APP - && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { - category = Intent.CATEGORY_CAR_DOCK; - } - } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(action)) { - // Only launch car home when desk mode is enabled and the caller - // has asked us to switch to it. Currently re-using the car - // mode flag since we don't have a formal API for "desk mode". - if (ENABLE_LAUNCH_DESK_DOCK_APP - && (enableFlags & UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) { - category = Intent.CATEGORY_DESK_DOCK; - } - } else { - // Launch the standard home app if requested. - if ((disableFlags & UiModeManager.DISABLE_CAR_MODE_GO_HOME) != 0) { - category = Intent.CATEGORY_HOME; - } - } - - if (LOG) { - Slog.v(TAG, String.format( - "Handling broadcast result for action %s: enable=0x%08x, disable=0x%08x, " - + "category=%s", - action, enableFlags, disableFlags, category)); - } - - sendConfigurationAndStartDreamOrDockAppLocked(category); - } - - private void sendConfigurationAndStartDreamOrDockAppLocked(String category) { - // Update the configuration but don't send it yet. - mHoldingConfiguration = false; - updateConfigurationLocked(); - - // Start the dock app, if there is one. - boolean dockAppStarted = false; - if (category != null) { - // Now we are going to be careful about switching the - // configuration and starting the activity -- we need to - // do this in a specific order under control of the - // activity manager, to do it cleanly. So compute the - // new config, but don't set it yet, and let the - // activity manager take care of both the start and config - // change. - Intent homeIntent = buildHomeIntent(category); - if (Sandman.shouldStartDockApp(mContext, homeIntent)) { - try { - int result = ActivityManagerNative.getDefault().startActivityWithConfig( - null, null, homeIntent, null, null, null, 0, 0, - mConfiguration, null, UserHandle.USER_CURRENT); - if (result >= ActivityManager.START_SUCCESS) { - dockAppStarted = true; - } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) { - Slog.e(TAG, "Could not start dock app: " + homeIntent - + ", startActivityWithConfig result " + result); - } - } catch (RemoteException ex) { - Slog.e(TAG, "Could not start dock app: " + homeIntent, ex); - } - } - } - - // Send the new configuration. - sendConfigurationLocked(); - - // If we did not start a dock app, then start dreaming if supported. - if (category != null && !dockAppStarted) { - Sandman.startDreamWhenDockedIfAppropriate(mContext); - } - } - - private void adjustStatusBarCarModeLocked() { - if (mStatusBarManager == null) { - mStatusBarManager = (StatusBarManager) - mContext.getSystemService(Context.STATUS_BAR_SERVICE); - } - - // Fear not: StatusBarManagerService manages a list of requests to disable - // features of the status bar; these are ORed together to form the - // active disabled list. So if (for example) the device is locked and - // the status bar should be totally disabled, the calls below will - // have no effect until the device is unlocked. - if (mStatusBarManager != null) { - mStatusBarManager.disable(mCarModeEnabled - ? StatusBarManager.DISABLE_NOTIFICATION_TICKER - : StatusBarManager.DISABLE_NONE); - } - - if (mNotificationManager == null) { - mNotificationManager = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - } - - if (mNotificationManager != null) { - if (mCarModeEnabled) { - Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class); - - Notification n = new Notification(); - n.icon = R.drawable.stat_notify_car_mode; - n.defaults = Notification.DEFAULT_LIGHTS; - n.flags = Notification.FLAG_ONGOING_EVENT; - n.when = 0; - n.setLatestEventInfo( - mContext, - mContext.getString(R.string.car_mode_disable_notification_title), - mContext.getString(R.string.car_mode_disable_notification_message), - PendingIntent.getActivityAsUser(mContext, 0, carModeOffIntent, 0, - null, UserHandle.CURRENT)); - mNotificationManager.notifyAsUser(null, - R.string.car_mode_disable_notification_title, n, UserHandle.ALL); - } else { - mNotificationManager.cancelAsUser(null, - R.string.car_mode_disable_notification_title, UserHandle.ALL); - } - } - } - - private void updateTwilight() { - synchronized (mLock) { - if (isDoingNightModeLocked() && mNightMode == UiModeManager.MODE_NIGHT_AUTO) { - updateComputedNightModeLocked(); - updateLocked(0, 0); - } - } - } - - private void updateComputedNightModeLocked() { - TwilightState state = mTwilightService.getCurrentState(); - if (state != null) { - mComputedNightMode = state.isNight(); - } - } - - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - - pw.println("Permission Denial: can't dump uimode service from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - synchronized (mLock) { - pw.println("Current UI Mode Service state:"); - pw.print(" mDockState="); pw.print(mDockState); - pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); - pw.print(" mNightMode="); pw.print(mNightMode); - pw.print(" mCarModeEnabled="); pw.print(mCarModeEnabled); - pw.print(" mComputedNightMode="); pw.println(mComputedNightMode); - pw.print(" mCurUiMode=0x"); pw.print(Integer.toHexString(mCurUiMode)); - pw.print(" mSetUiMode=0x"); pw.println(Integer.toHexString(mSetUiMode)); - pw.print(" mHoldingConfiguration="); pw.print(mHoldingConfiguration); - pw.print(" mSystemReady="); pw.println(mSystemReady); - pw.print(" mTwilightService.getCurrentState()="); - pw.println(mTwilightService.getCurrentState()); - } - } -} |