diff options
| -rw-r--r-- | core/java/android/content/Intent.java | 39 | ||||
| -rw-r--r-- | services/java/com/android/server/DockObserver.java | 115 | ||||
| -rw-r--r-- | services/java/com/android/server/SystemServer.java | 9 |
3 files changed, 163 insertions, 0 deletions
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index f9b082fecadf..a3517f859859 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1838,6 +1838,14 @@ public class Intent implements Parcelable { */ public static final String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST = "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"; + + /** + * Broadcast Action: The phone was docked or undocked. Includes the extra + * field {@link #EXTRA_DOCK_STATE}, containing the current dock state. + * @hide + */ + public static final String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT"; + // --------------------------------------------------------------------- // --------------------------------------------------------------------- // Standard extra data keys. @@ -1960,6 +1968,37 @@ public class Intent implements Parcelable { public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT"; /** + * Used as an int extra field in {@link android.content.Intent#ACTION_DOCK_EVENT} + * intents to request the dock state. Possible values are + * {@link android.content.Intent#ACTION_DOCK_STATE_UNDOCKED}, + * {@link android.content.Intent#ACTION_DOCK_STATE_DESK}, or + * {@link android.content.Intent#ACTION_DOCK_STATE_CAR}. + * @hide + */ + public static final String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; + + /** + * Used as an int value for {@link android.content.Intent#EXTRA_DOCK_STATE} + * to represent that the phone is not in any dock. + * @hide + */ + public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; + + /** + * Used as an int value for {@link android.content.Intent#EXTRA_DOCK_STATE} + * to represent that the phone is in a desk dock. + * @hide + */ + public static final int EXTRA_DOCK_STATE_DESK = 1; + + /** + * Used as an int value for {@link android.content.Intent#EXTRA_DOCK_STATE} + * to represent that the phone is in a car dock. + * @hide + */ + public static final int EXTRA_DOCK_STATE_CAR = 2; + + /** * Used as a parcelable extra field in {@link #ACTION_APP_ERROR}, containing * the bug report. * diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java new file mode 100644 index 000000000000..68ff416a8791 --- /dev/null +++ b/services/java/com/android/server/DockObserver.java @@ -0,0 +1,115 @@ +/* + * 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.ActivityManagerNative; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.Message; +import android.os.UEventObserver; +import android.util.Log; + +import java.io.FileReader; +import java.io.FileNotFoundException; + +/** + * <p>DockObserver monitors for a docking station. + */ +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 int mDockState; + private boolean mPendingIntent; + + private final Context mContext; + + public DockObserver(Context context) { + mContext = context; + + startObserving(DOCK_UEVENT_MATCH); + + init(); // set initial status + } + + @Override + public void onUEvent(UEventObserver.UEvent event) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "Dock UEVENT: " + event.toString()); + } + + try { + update(Integer.parseInt(event.get("SWITCH_STATE"))); + } catch (NumberFormatException e) { + Log.e(TAG, "Could not parse switch state from event " + event); + } + } + + private synchronized final void init() { + char[] buffer = new char[1024]; + + int newState = mDockState; + try { + FileReader file = new FileReader(DOCK_STATE_PATH); + int len = file.read(buffer, 0, 1024); + newState = Integer.valueOf((new String(buffer, 0, len)).trim()); + + } catch (FileNotFoundException e) { + Log.w(TAG, "This kernel does not have dock station support"); + } catch (Exception e) { + Log.e(TAG, "" , e); + } + + update(newState); + } + + private synchronized final void update(int newState) { + if (newState != mDockState) { + mDockState = newState; + + mPendingIntent = true; + mHandler.sendEmptyMessage(0); + } + } + + private synchronized final void sendIntent() { + // Pack up the values and broadcast them to everyone + Intent intent = new Intent(Intent.ACTION_DOCK_EVENT); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState); + + // TODO: Should we require a permission? + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "Broadcasting dock state " + mDockState); + } + ActivityManagerNative.broadcastStickyIntent(intent, null); + } + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (mPendingIntent) { + sendIntent(); + mPendingIntent = false; + } + } + }; +} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 38bf63affaca..ce476ebc4e33 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -92,6 +92,7 @@ class ServerThread extends Thread { BluetoothDeviceService bluetooth = null; BluetoothA2dpService bluetoothA2dp = null; HeadsetObserver headset = null; + DockObserver dock = null; // Critical services... try { @@ -326,6 +327,14 @@ class ServerThread extends Thread { } try { + Log.i(TAG, "Starting DockObserver"); + // Listen for dock station changes + dock = new DockObserver(context); + } catch (Throwable e) { + Log.e(TAG, "Failure starting DockObserver", e); + } + + try { Log.i(TAG, "Starting Backup Service"); ServiceManager.addService(Context.BACKUP_SERVICE, new BackupManagerService(context)); } catch (Throwable e) { |