diff options
Diffstat (limited to 'services/java/com/android/server/DockObserver.java')
| -rw-r--r-- | services/java/com/android/server/DockObserver.java | 232 |
1 files changed, 143 insertions, 89 deletions
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java index 64789d3..65c39f2 100644 --- a/services/java/com/android/server/DockObserver.java +++ b/services/java/com/android/server/DockObserver.java @@ -16,8 +16,9 @@ package com.android.server; -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; +import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK; +import static android.provider.Settings.Secure.SCREENSAVER_ENABLED; + import android.content.ContentResolver; import android.content.Context; import android.content.Intent; @@ -26,11 +27,16 @@ import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Handler; +import android.os.Looper; import android.os.Message; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.PowerManager; import android.os.SystemClock; import android.os.UEventObserver; +import android.os.UserHandle; import android.provider.Settings; -import android.server.BluetoothService; +import android.service.dreams.IDreamManager; import android.util.Log; import android.util.Slog; @@ -40,14 +46,19 @@ import java.io.FileReader; /** * <p>DockObserver monitors for a docking station. */ -class DockObserver extends UEventObserver { +final class DockObserver extends UEventObserver { private static final String TAG = DockObserver.class.getSimpleName(); private static final boolean LOG = false; private static final String DOCK_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/dock"; private static final String DOCK_STATE_PATH = "/sys/class/switch/dock/state"; - private static final int MSG_DOCK_STATE = 0; + private static final int DEFAULT_SCREENSAVER_ENABLED = 1; + private static final int DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK = 1; + + private static final int MSG_DOCK_STATE_CHANGED = 0; + + private final Object mLock = new Object(); private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mPreviousDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED; @@ -56,11 +67,8 @@ class DockObserver extends UEventObserver { private final Context mContext; - private PowerManagerService mPowerManager; - - public DockObserver(Context context, PowerManagerService pm) { + public DockObserver(Context context) { mContext = context; - mPowerManager = pm; init(); // set initial status startObserving(DOCK_UEVENT_MATCH); @@ -72,7 +80,7 @@ class DockObserver extends UEventObserver { Slog.v(TAG, "Dock UEVENT: " + event.toString()); } - synchronized (this) { + synchronized (mLock) { try { int newState = Integer.parseInt(event.get("SWITCH_STATE")); if (newState != mDockState) { @@ -86,10 +94,11 @@ class DockObserver extends UEventObserver { && mPreviousDockState != Intent.EXTRA_DOCK_STATE_LE_DESK && mPreviousDockState != Intent.EXTRA_DOCK_STATE_HE_DESK) || mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) { - mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), - false, true); + PowerManager pm = + (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); + pm.wakeUp(SystemClock.uptimeMillis()); } - update(); + updateLocked(); } } } catch (NumberFormatException e) { @@ -98,102 +107,147 @@ class DockObserver extends UEventObserver { } } - private final void init() { - char[] buffer = new char[1024]; - - try { - FileReader file = new FileReader(DOCK_STATE_PATH); - int len = file.read(buffer, 0, 1024); - file.close(); - mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim()); - } catch (FileNotFoundException e) { - Slog.w(TAG, "This kernel does not have dock station support"); - } catch (Exception e) { - Slog.e(TAG, "" , e); + private void init() { + synchronized (mLock) { + try { + char[] buffer = new char[1024]; + FileReader file = new FileReader(DOCK_STATE_PATH); + try { + int len = file.read(buffer, 0, 1024); + mDockState = Integer.valueOf((new String(buffer, 0, len)).trim()); + mPreviousDockState = mDockState; + } finally { + file.close(); + } + } catch (FileNotFoundException e) { + Slog.w(TAG, "This kernel does not have dock station support"); + } catch (Exception e) { + Slog.e(TAG, "" , e); + } } } void systemReady() { - synchronized (this) { + synchronized (mLock) { // don't bother broadcasting undocked here if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) { - update(); + updateLocked(); } mSystemReady = true; } } - private final void update() { - mHandler.sendEmptyMessage(MSG_DOCK_STATE); + private void updateLocked() { + mHandler.sendEmptyMessage(MSG_DOCK_STATE_CHANGED); } - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_DOCK_STATE: - synchronized (this) { - Slog.i(TAG, "Dock state changed: " + mDockState); + private void handleDockStateChange() { + synchronized (mLock) { + Slog.i(TAG, "Dock state changed: " + mDockState); - final ContentResolver cr = mContext.getContentResolver(); + final ContentResolver cr = mContext.getContentResolver(); - if (Settings.Secure.getInt(cr, - Settings.Secure.DEVICE_PROVISIONED, 0) == 0) { - Slog.i(TAG, "Device not provisioned, skipping dock broadcast"); - return; - } - // Pack up the values and broadcast them to everyone - Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); - - // Check if this is Bluetooth Dock - String address = BluetoothService.readDockBluetoothAddress(); - if (address != null) - intent.putExtra(BluetoothDevice.EXTRA_DEVICE, - BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address)); - - // User feedback to confirm dock connection. Particularly - // useful for flaky contact pins... - if (Settings.System.getInt(cr, - Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1) - { - String whichSound = null; - if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { - if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) || - (mPreviousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || - (mPreviousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { - whichSound = Settings.System.DESK_UNDOCK_SOUND; - } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) { - whichSound = Settings.System.CAR_UNDOCK_SOUND; - } - } else { - if ((mDockState == Intent.EXTRA_DOCK_STATE_DESK) || - (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || - (mDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { - whichSound = Settings.System.DESK_DOCK_SOUND; - } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) { - whichSound = Settings.System.CAR_DOCK_SOUND; - } - } + if (Settings.Secure.getInt(cr, + Settings.Secure.DEVICE_PROVISIONED, 0) == 0) { + Slog.i(TAG, "Device not provisioned, skipping dock broadcast"); + return; + } + + // Pack up the values and broadcast them to everyone + Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); + + // Check if this is Bluetooth Dock + // TODO(BT): Get Dock address. + // String address = null; + // if (address != null) { + // intent.putExtra(BluetoothDevice.EXTRA_DEVICE, + // BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address)); + // } + + // User feedback to confirm dock connection. Particularly + // useful for flaky contact pins... + if (Settings.System.getInt(cr, + Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1) { + String whichSound = null; + if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { + if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) || + (mPreviousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || + (mPreviousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { + whichSound = Settings.System.DESK_UNDOCK_SOUND; + } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) { + whichSound = Settings.System.CAR_UNDOCK_SOUND; + } + } else { + if ((mDockState == Intent.EXTRA_DOCK_STATE_DESK) || + (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) || + (mDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) { + whichSound = Settings.System.DESK_DOCK_SOUND; + } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) { + whichSound = Settings.System.CAR_DOCK_SOUND; + } + } - if (whichSound != null) { - final String soundPath = Settings.System.getString(cr, whichSound); - if (soundPath != null) { - final Uri soundUri = Uri.parse("file://" + soundPath); - if (soundUri != null) { - final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); - if (sfx != null) { - sfx.setStreamType(AudioManager.STREAM_SYSTEM); - sfx.play(); - } - } - } + if (whichSound != null) { + final String soundPath = Settings.System.getString(cr, whichSound); + if (soundPath != null) { + final Uri soundUri = Uri.parse("file://" + soundPath); + if (soundUri != null) { + final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); + if (sfx != null) { + sfx.setStreamType(AudioManager.STREAM_SYSTEM); + sfx.play(); } } + } + } + } - mContext.sendStickyBroadcast(intent); + IDreamManager mgr = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams")); + if (mgr != null) { + // dreams feature enabled + boolean undocked = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED; + if (undocked) { + try { + if (mgr.isDreaming()) { + mgr.awaken(); + } + } catch (RemoteException e) { + Slog.w(TAG, "Unable to awaken!", e); } + } else { + if (isScreenSaverEnabled(mContext) && isScreenSaverActivatedOnDock(mContext)) { + try { + mgr.dream(); + } catch (RemoteException e) { + Slog.w(TAG, "Unable to dream!", e); + } + } + } + } else { + // dreams feature not enabled, send legacy intent + mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); + } + } + } + + private static boolean isScreenSaverEnabled(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + SCREENSAVER_ENABLED, DEFAULT_SCREENSAVER_ENABLED) != 0; + } + + private static boolean isScreenSaverActivatedOnDock(Context context) { + return Settings.Secure.getInt(context.getContentResolver(), + SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_SCREENSAVER_ACTIVATED_ON_DOCK) != 0; + } + + private final Handler mHandler = new Handler(true /*async*/) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_DOCK_STATE_CHANGED: + handleDockStateChange(); break; } } |
