From ac06111695e71f704d263f9c42af0b28faf3a43f Mon Sep 17 00:00:00 2001 From: Ricardo Cerqueira Date: Sun, 17 Oct 2010 13:59:25 +0100 Subject: Add RingerSwitch support This patch adds support for the Geeksphone ONE's MUTE hard key. I don't know of any other device with such a key, so this will defaults to disabled. It's enabled by setting the "ro.config.ringerswitch" property to 1 Change-Id: Ica18f3f3ee872b4b911ddd79b95ba569cb13f4e8 --- .../com/android/server/RingerSwitchObserver.java | 141 +++++++++++++++++++++ services/java/com/android/server/SystemServer.java | 12 ++ 2 files changed, 153 insertions(+) create mode 100644 services/java/com/android/server/RingerSwitchObserver.java (limited to 'services/java/com/android/server') diff --git a/services/java/com/android/server/RingerSwitchObserver.java b/services/java/com/android/server/RingerSwitchObserver.java new file mode 100644 index 0000000..54a6526 --- /dev/null +++ b/services/java/com/android/server/RingerSwitchObserver.java @@ -0,0 +1,141 @@ +/* + * 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.os.UEventObserver; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; +import android.os.ServiceManager; +import android.os.RemoteException; +import android.os.Vibrator; + +import android.view.VolumePanel; + +import android.media.AudioService; +import android.media.IAudioService; +import android.media.AudioManager; + +import java.io.FileReader; +import java.io.FileNotFoundException; + +/** + *

RingerSwitchObserver monitors the ONE's mute switch + */ +class RingerSwitchObserver extends UEventObserver { + private static final String TAG = RingerSwitchObserver.class.getSimpleName(); + private static final boolean LOG = false; + + private static final String RINGER_SWITCH_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/ringer_switch"; + private static final String RINGER_SWITCH_STATE_PATH = "/sys/class/switch/ringer_switch/state"; + private static final String RINGER_SWITCH_NAME_PATH = "/sys/class/switch/ringer_switch/name"; + + private int mRingerswitchState; + private String mRingerswitchName; + private IAudioService mAudioService; + private Context mContext; + private VolumePanel mVolumePanel; + + private final WakeLock mWakeLock; // held while there is a pending route change + + public RingerSwitchObserver(Context context) { + + mContext = context; + + PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "RingerSwitchObserver"); + mWakeLock.setReferenceCounted(false); + + startObserving(RINGER_SWITCH_UEVENT_MATCH); + + init(); // set initial status + } + + @Override + public void onUEvent(UEventObserver.UEvent event) { + if (LOG) Log.v(TAG, "Ringerswitch UEVENT: " + event.toString()); + + try { + update(event.get("SWITCH_NAME"), 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]; + + String newName = mRingerswitchName; + int newState = mRingerswitchState; + try { + FileReader file = new FileReader(RINGER_SWITCH_STATE_PATH); + int len = file.read(buffer, 0, 1024); + newState = Integer.valueOf((new String(buffer, 0, len)).trim()); + + file = new FileReader(RINGER_SWITCH_NAME_PATH); + len = file.read(buffer, 0, 1024); + newName = new String(buffer, 0, len).trim(); + + } catch (FileNotFoundException e) { + Log.w(TAG, "This kernel does not have ringer switch support"); + return; + } catch (Exception e) { + Log.e(TAG, "" , e); + } + + mAudioService = IAudioService.Stub.asInterface(ServiceManager.checkService(Context.AUDIO_SERVICE)); + mVolumePanel = new VolumePanel(mContext, (AudioService) mAudioService); + } + + private synchronized final void update(String newName, int newState) { + if (newName != mRingerswitchName || newState != mRingerswitchState) { + boolean isRingerOn = (newState == 0 && mRingerswitchState == 1); + + mRingerswitchName = newName; + mRingerswitchState = newState; + + + try { + + if (isRingerOn) { + //Log.w(TAG,"Got ringer on"); + mAudioService.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + } else { + //Log.w(TAG,"Got ringer off"); + AudioManager mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + boolean vibrateSetting = mAudioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER) == AudioManager.VIBRATE_SETTING_ON; + + + // We probably lowered the volume on the way "down", so + // raise it a notch before muting + mAudioService.adjustStreamVolume(AudioManager.STREAM_RING, AudioManager.ADJUST_RAISE, 0 ); + mAudioService.setRingerMode(vibrateSetting ? AudioManager.RINGER_MODE_VIBRATE : AudioManager.RINGER_MODE_SILENT); + + } + + // Raise UI + mVolumePanel.postVolumeChanged(AudioManager.STREAM_RING,AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE); + + } catch (RemoteException e) { + } + } + } + + +} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b7a7bbf..7efee6e 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -102,6 +102,7 @@ class ServerThread extends Thread { UiModeManagerService uiMode = null; RecognitionManagerService recognition = null; ThrottleService throttle = null; + RingerSwitchObserver ringer = null; // Critical services... try { @@ -372,6 +373,16 @@ class ServerThread extends Thread { } try { + if (SystemProperties.get("ro.config.ringerswitch").equals("1")) { + Slog.i(TAG, "RingerSwitch Observer"); + // Listen for hard ringer switch changes + ringer = new RingerSwitchObserver(context); + } + } catch (Throwable e) { + Slog.e(TAG, "Failure starting RingerSwitchObserver", e); + } + + try { Slog.i(TAG, "Dock Observer"); // Listen for dock station changes dock = new DockObserver(context, power); @@ -422,6 +433,7 @@ class ServerThread extends Thread { } catch (Throwable e) { Slog.e(TAG, "Failure starting DiskStats Service", e); } + } // make sure the ADB_ENABLED setting value matches the secure property value -- cgit v1.1