blob: 9f7701d609d86684476cc494518f63539b7e113a [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
19import android.app.ActivityManagerNative;
20import android.content.Context;
21import android.content.Intent;
22import android.os.UEventObserver;
23import android.util.Log;
24import android.media.AudioManager;
25
26import java.io.FileReader;
27import java.io.FileNotFoundException;
28
29/**
30 * <p>HeadsetObserver monitors for a wired headset.
31 */
32class HeadsetObserver extends UEventObserver {
33 private static final String TAG = HeadsetObserver.class.getSimpleName();
34
35 private static final String HEADSET_UEVENT_MATCH = "DEVPATH=/class/switch/h2w";
36 private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state";
37 private static final String HEADSET_NAME_PATH = "/sys/class/switch/h2w/name";
38
39 private Context mContext;
40
41 private int mHeadsetState;
42 private String mHeadsetName;
43
44 public HeadsetObserver(Context context) {
45 mContext = context;
46
47 startObserving(HEADSET_UEVENT_MATCH);
48
49 init(); // set initial status
50 }
51
52 @Override
53 public void onUEvent(UEventObserver.UEvent event) {
54 Log.v(TAG, "Headset UEVENT: " + event.toString());
55
56 try {
57 update(event.get("SWITCH_NAME"), Integer.parseInt(event.get("SWITCH_STATE")));
58 } catch (NumberFormatException e) {
59 Log.e(TAG, "Could not parse switch state from event " + event);
60 }
61 }
62
63 private final void init() {
64 char[] buffer = new char[1024];
65
66 String newName = mHeadsetName;
67 int newState = mHeadsetState;
68 try {
69 FileReader file = new FileReader(HEADSET_STATE_PATH);
70 int len = file.read(buffer, 0, 1024);
71 newState = Integer.valueOf((new String(buffer, 0, len)).trim());
72
73 file = new FileReader(HEADSET_NAME_PATH);
74 len = file.read(buffer, 0, 1024);
75 newName = new String(buffer, 0, len).trim();
76
77 } catch (FileNotFoundException e) {
78 Log.w(TAG, "This kernel does not have wired headset support");
79 } catch (Exception e) {
80 Log.e(TAG, "" , e);
81 }
82
83 update(newName, newState);
84 }
85
86 private synchronized final void update(String newName, int newState) {
87 if (newName != mHeadsetName || newState != mHeadsetState) {
88 mHeadsetName = newName;
89 mHeadsetState = newState;
90 AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
91
92 if (mHeadsetState == 1) {
93 audioManager.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_HEADSET,
94 AudioManager.ROUTE_ALL);
95 audioManager.setRouting(AudioManager.MODE_RINGTONE,
96 AudioManager.ROUTE_HEADSET | AudioManager.ROUTE_SPEAKER,
97 AudioManager.ROUTE_ALL);
98 audioManager.setRouting(AudioManager.MODE_IN_CALL, AudioManager.ROUTE_HEADSET,
99 AudioManager.ROUTE_ALL);
100 } else {
101 audioManager.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_SPEAKER,
102 AudioManager.ROUTE_ALL);
103 audioManager.setRouting(AudioManager.MODE_RINGTONE, AudioManager.ROUTE_SPEAKER,
104 AudioManager.ROUTE_ALL);
105 audioManager.setRouting(AudioManager.MODE_IN_CALL, AudioManager.ROUTE_EARPIECE,
106 AudioManager.ROUTE_ALL);
107 }
108 sendIntent();
109 }
110 }
111
112 private synchronized final void sendIntent() {
113 // Pack up the values and broadcast them to everyone
114 Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
115 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
116
117 intent.putExtra("state", mHeadsetState);
118 intent.putExtra("name", mHeadsetName);
119
120 // TODO: Should we require a permission?
121 ActivityManagerNative.broadcastStickyIntent(intent, null);
122 }
123}