FileDocCategorySizeDatePackage
DockObserver.javaAPI DocAndroid 5.1 API11655Thu Mar 12 22:22:42 GMT 2015com.android.server

DockObserver

public final class DockObserver extends SystemService
DockObserver monitors for a docking station.

Fields Summary
private static final String
TAG
private static final String
DOCK_UEVENT_MATCH
private static final String
DOCK_STATE_PATH
private static final int
MSG_DOCK_STATE_CHANGED
private final android.os.PowerManager
mPowerManager
private final PowerManager.WakeLock
mWakeLock
private final Object
mLock
private boolean
mSystemReady
private int
mActualDockState
private int
mReportedDockState
private int
mPreviousDockState
private boolean
mUpdatesStopped
private final boolean
mAllowTheaterModeWakeFromDock
private final android.os.Handler
mHandler
private final android.os.UEventObserver
mObserver
Constructors Summary
public DockObserver(android.content.Context context)


       
        super(context);

        mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
        mAllowTheaterModeWakeFromDock = context.getResources().getBoolean(
                com.android.internal.R.bool.config_allowTheaterModeWakeFromDock);

        init();  // set initial status

        mObserver.startObserving(DOCK_UEVENT_MATCH);
    
Methods Summary
private voidhandleDockStateChange()

        synchronized (mLock) {
            Slog.i(TAG, "Dock state changed from " + mPreviousDockState + " to "
                    + mReportedDockState);
            final int previousDockState = mPreviousDockState;
            mPreviousDockState = mReportedDockState;

            // Skip the dock intent if not yet provisioned.
            final ContentResolver cr = getContext().getContentResolver();
            if (Settings.Global.getInt(cr,
                    Settings.Global.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, mReportedDockState);

            // Play a sound to provide feedback to confirm dock connection.
            // Particularly useful for flaky contact pins...
            if (Settings.Global.getInt(cr,
                    Settings.Global.DOCK_SOUNDS_ENABLED, 1) == 1) {
                String whichSound = null;
                if (mReportedDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                    if ((previousDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
                        (previousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
                        (previousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
                        whichSound = Settings.Global.DESK_UNDOCK_SOUND;
                    } else if (previousDockState == Intent.EXTRA_DOCK_STATE_CAR) {
                        whichSound = Settings.Global.CAR_UNDOCK_SOUND;
                    }
                } else {
                    if ((mReportedDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
                        (mReportedDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
                        (mReportedDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
                        whichSound = Settings.Global.DESK_DOCK_SOUND;
                    } else if (mReportedDockState == Intent.EXTRA_DOCK_STATE_CAR) {
                        whichSound = Settings.Global.CAR_DOCK_SOUND;
                    }
                }

                if (whichSound != null) {
                    final String soundPath = Settings.Global.getString(cr, whichSound);
                    if (soundPath != null) {
                        final Uri soundUri = Uri.parse("file://" + soundPath);
                        if (soundUri != null) {
                            final Ringtone sfx = RingtoneManager.getRingtone(
                                    getContext(), soundUri);
                            if (sfx != null) {
                                sfx.setStreamType(AudioManager.STREAM_SYSTEM);
                                sfx.play();
                            }
                        }
                    }
                }
            }

            // Send the dock event intent.
            // There are many components in the system watching for this so as to
            // adjust audio routing, screen orientation, etc.
            getContext().sendStickyBroadcastAsUser(intent, UserHandle.ALL);
        }
    
private voidinit()

        synchronized (mLock) {
            try {
                char[] buffer = new char[1024];
                FileReader file = new FileReader(DOCK_STATE_PATH);
                try {
                    int len = file.read(buffer, 0, 1024);
                    setActualDockStateLocked(Integer.valueOf((new String(buffer, 0, len)).trim()));
                    mPreviousDockState = mActualDockState;
                } finally {
                    file.close();
                }
            } catch (FileNotFoundException e) {
                Slog.w(TAG, "This kernel does not have dock station support");
            } catch (Exception e) {
                Slog.e(TAG, "" , e);
            }
        }
    
public voidonBootPhase(int phase)

        if (phase == PHASE_ACTIVITY_MANAGER_READY) {
            synchronized (mLock) {
                mSystemReady = true;

                // don't bother broadcasting undocked here
                if (mReportedDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
                    updateLocked();
                }
            }
        }
    
public voidonStart()

        publishBinderService(TAG, new BinderService());
    
private voidsetActualDockStateLocked(int newState)

        mActualDockState = newState;
        if (!mUpdatesStopped) {
            setDockStateLocked(newState);
        }
    
private voidsetDockStateLocked(int newState)

        if (newState != mReportedDockState) {
            mReportedDockState = newState;
            if (mSystemReady) {
                // Wake up immediately when docked or undocked except in theater mode.
                if (mAllowTheaterModeWakeFromDock
                        || Settings.Global.getInt(getContext().getContentResolver(),
                            Settings.Global.THEATER_MODE_ON, 0) == 0) {
                    mPowerManager.wakeUp(SystemClock.uptimeMillis());
                }
                updateLocked();
            }
        }
    
private voidupdateLocked()

        mWakeLock.acquire();
        mHandler.sendEmptyMessage(MSG_DOCK_STATE_CHANGED);