Loading core/java/android/os/UEventObserver.java +112 −84 Original line number Diff line number Diff line Loading @@ -37,14 +37,79 @@ import java.util.HashMap; * @hide */ public abstract class UEventObserver { private static final String TAG = UEventObserver.class.getSimpleName(); private static UEventThread sThread; private static native void native_setup(); private static native int next_event(byte[] buffer); public UEventObserver() { } protected void finalize() throws Throwable { try { stopObserving(); } finally { super.finalize(); } } private static UEventThread getThread() { synchronized (UEventObserver.class) { if (sThread == null) { sThread = new UEventThread(); sThread.start(); } return sThread; } } private static UEventThread peekThread() { synchronized (UEventObserver.class) { return sThread; } } /** * Begin observation of UEvent's.<p> * This method will cause the UEvent thread to start if this is the first * invocation of startObserving in this process.<p> * Once called, the UEvent thread will call onUEvent() when an incoming * UEvent matches the specified string.<p> * This method can be called multiple times to register multiple matches. * Only one call to stopObserving is required even with multiple registered * matches. * @param match A substring of the UEvent to match. Use "" to match all * UEvent's */ public final void startObserving(String match) { final UEventThread t = getThread(); t.addObserver(match, this); } /** * End observation of UEvent's.<p> * This process's UEvent thread will never call onUEvent() on this * UEventObserver after this call. Repeated calls have no effect. */ public final void stopObserving() { final UEventThread t = getThread(); if (t != null) { t.removeObserver(this); } } /** * Subclasses of UEventObserver should override this method to handle * UEvents. */ public abstract void onUEvent(UEvent event); /** * Representation of a UEvent. */ static public class UEvent { public static final class UEvent { // collection of key=value pairs parsed from the uevent message public HashMap<String,String> mMap = new HashMap<String,String>(); private final HashMap<String,String> mMap = new HashMap<String,String>(); public UEvent(String message) { int offset = 0; Loading Loading @@ -79,17 +144,17 @@ public abstract class UEventObserver { } } private static UEventThread sThread; private static boolean sThreadStarted = false; private static class UEventThread extends Thread { private static final class UEventThread extends Thread { /** Many to many mapping of string match to observer. * Multimap would be better, but not available in android, so use * an ArrayList where even elements are the String match and odd * elements the corresponding UEventObserver observer */ private ArrayList<Object> mObservers = new ArrayList<Object>(); private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>(); private final ArrayList<UEventObserver> mTempObserversToSignal = new ArrayList<UEventObserver>(); UEventThread() { public UEventThread() { super("UEventObserver"); } Loading @@ -101,91 +166,54 @@ public abstract class UEventObserver { while (true) { len = next_event(buffer); if (len > 0) { String bufferStr = new String(buffer, 0, len); // easier to search a String synchronized (mObservers) { for (int i = 0; i < mObservers.size(); i += 2) { if (bufferStr.indexOf((String)mObservers.get(i)) != -1) { ((UEventObserver)mObservers.get(i+1)) .onUEvent(new UEvent(bufferStr)); } } sendEvent(new String(buffer, 0, len)); } } } } public void addObserver(String match, UEventObserver observer) { synchronized(mObservers) { mObservers.add(match); mObservers.add(observer); } } /** Removes every key/value pair where value=observer from mObservers */ public void removeObserver(UEventObserver observer) { synchronized(mObservers) { boolean found = true; while (found) { found = false; for (int i = 0; i < mObservers.size(); i += 2) { if (mObservers.get(i+1) == observer) { mObservers.remove(i+1); mObservers.remove(i); found = true; break; private void sendEvent(String message) { synchronized (mKeysAndObservers) { final int N = mKeysAndObservers.size(); for (int i = 0; i < N; i += 2) { final String key = (String)mKeysAndObservers.get(i); if (message.indexOf(key) != -1) { final UEventObserver observer = (UEventObserver)mKeysAndObservers.get(i + 1); mTempObserversToSignal.add(observer); } } } if (!mTempObserversToSignal.isEmpty()) { final UEvent event = new UEvent(message); final int N = mTempObserversToSignal.size(); for (int i = 0; i < N; i++) { final UEventObserver observer = mTempObserversToSignal.get(i); observer.onUEvent(event); } mTempObserversToSignal.clear(); } } private static native void native_setup(); private static native int next_event(byte[] buffer); private static final synchronized void ensureThreadStarted() { if (sThreadStarted == false) { sThread = new UEventThread(); sThread.start(); sThreadStarted = true; public void addObserver(String match, UEventObserver observer) { synchronized (mKeysAndObservers) { mKeysAndObservers.add(match); mKeysAndObservers.add(observer); } } /** * Begin observation of UEvent's.<p> * This method will cause the UEvent thread to start if this is the first * invocation of startObserving in this process.<p> * Once called, the UEvent thread will call onUEvent() when an incoming * UEvent matches the specified string.<p> * This method can be called multiple times to register multiple matches. * Only one call to stopObserving is required even with multiple registered * matches. * @param match A substring of the UEvent to match. Use "" to match all * UEvent's */ public final synchronized void startObserving(String match) { ensureThreadStarted(); sThread.addObserver(match, this); /** Removes every key/value pair where value=observer from mObservers */ public void removeObserver(UEventObserver observer) { synchronized (mKeysAndObservers) { for (int i = 0; i < mKeysAndObservers.size(); ) { if (mKeysAndObservers.get(i + 1) == observer) { mKeysAndObservers.remove(i + 1); mKeysAndObservers.remove(i); } else { i += 2; } } /** * End observation of UEvent's.<p> * This process's UEvent thread will never call onUEvent() on this * UEventObserver after this call. Repeated calls have no effect. */ public final synchronized void stopObserving() { sThread.removeObserver(this); } /** * Subclasses of UEventObserver should override this method to handle * UEvents. */ public abstract void onUEvent(UEvent event); protected void finalize() throws Throwable { try { stopObserving(); } finally { super.finalize(); } } } services/java/com/android/server/DockObserver.java +121 −112 Original line number Diff line number Diff line Loading @@ -18,10 +18,6 @@ package com.android.server; import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK; import com.android.server.power.PowerManagerService; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -30,6 +26,7 @@ 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; Loading @@ -47,7 +44,7 @@ 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; Loading @@ -56,7 +53,9 @@ class DockObserver extends UEventObserver { private static final int DEFAULT_DOCK = 1; private static final int MSG_DOCK_STATE = 0; 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; Loading @@ -78,7 +77,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) { Loading @@ -96,7 +95,7 @@ class DockObserver extends UEventObserver { (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); pm.wakeUp(SystemClock.uptimeMillis()); } update(); updateLocked(); } } } catch (NumberFormatException e) { Loading @@ -105,46 +104,42 @@ class DockObserver extends UEventObserver { } } private final void init() { char[] buffer = new char[1024]; 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(); 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); } } } 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 static boolean isScreenSaverActivatedOnDock(Context context) { return 0 != Settings.Secure.getInt( context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK); 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) { private void handleDockStateChange() { synchronized (mLock) { Slog.i(TAG, "Dock state changed: " + mDockState); final ContentResolver cr = mContext.getContentResolver(); Loading @@ -154,6 +149,7 @@ class DockObserver extends UEventObserver { 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); Loading @@ -161,16 +157,16 @@ class DockObserver extends UEventObserver { // 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)); // 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) { Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1) { String whichSound = null; if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) || Loading Loading @@ -231,6 +227,19 @@ class DockObserver extends UEventObserver { mContext.sendStickyBroadcast(intent); } } } private static boolean isScreenSaverActivatedOnDock(Context context) { return Settings.Secure.getInt(context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK) != 0; } private final Handler mHandler = new Handler(Looper.myLooper(), null, true) { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_DOCK_STATE_CHANGED: handleDockStateChange(); break; } } Loading services/java/com/android/server/WiredAccessoryObserver.java +153 −152 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/os/UEventObserver.java +112 −84 Original line number Diff line number Diff line Loading @@ -37,14 +37,79 @@ import java.util.HashMap; * @hide */ public abstract class UEventObserver { private static final String TAG = UEventObserver.class.getSimpleName(); private static UEventThread sThread; private static native void native_setup(); private static native int next_event(byte[] buffer); public UEventObserver() { } protected void finalize() throws Throwable { try { stopObserving(); } finally { super.finalize(); } } private static UEventThread getThread() { synchronized (UEventObserver.class) { if (sThread == null) { sThread = new UEventThread(); sThread.start(); } return sThread; } } private static UEventThread peekThread() { synchronized (UEventObserver.class) { return sThread; } } /** * Begin observation of UEvent's.<p> * This method will cause the UEvent thread to start if this is the first * invocation of startObserving in this process.<p> * Once called, the UEvent thread will call onUEvent() when an incoming * UEvent matches the specified string.<p> * This method can be called multiple times to register multiple matches. * Only one call to stopObserving is required even with multiple registered * matches. * @param match A substring of the UEvent to match. Use "" to match all * UEvent's */ public final void startObserving(String match) { final UEventThread t = getThread(); t.addObserver(match, this); } /** * End observation of UEvent's.<p> * This process's UEvent thread will never call onUEvent() on this * UEventObserver after this call. Repeated calls have no effect. */ public final void stopObserving() { final UEventThread t = getThread(); if (t != null) { t.removeObserver(this); } } /** * Subclasses of UEventObserver should override this method to handle * UEvents. */ public abstract void onUEvent(UEvent event); /** * Representation of a UEvent. */ static public class UEvent { public static final class UEvent { // collection of key=value pairs parsed from the uevent message public HashMap<String,String> mMap = new HashMap<String,String>(); private final HashMap<String,String> mMap = new HashMap<String,String>(); public UEvent(String message) { int offset = 0; Loading Loading @@ -79,17 +144,17 @@ public abstract class UEventObserver { } } private static UEventThread sThread; private static boolean sThreadStarted = false; private static class UEventThread extends Thread { private static final class UEventThread extends Thread { /** Many to many mapping of string match to observer. * Multimap would be better, but not available in android, so use * an ArrayList where even elements are the String match and odd * elements the corresponding UEventObserver observer */ private ArrayList<Object> mObservers = new ArrayList<Object>(); private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>(); private final ArrayList<UEventObserver> mTempObserversToSignal = new ArrayList<UEventObserver>(); UEventThread() { public UEventThread() { super("UEventObserver"); } Loading @@ -101,91 +166,54 @@ public abstract class UEventObserver { while (true) { len = next_event(buffer); if (len > 0) { String bufferStr = new String(buffer, 0, len); // easier to search a String synchronized (mObservers) { for (int i = 0; i < mObservers.size(); i += 2) { if (bufferStr.indexOf((String)mObservers.get(i)) != -1) { ((UEventObserver)mObservers.get(i+1)) .onUEvent(new UEvent(bufferStr)); } } sendEvent(new String(buffer, 0, len)); } } } } public void addObserver(String match, UEventObserver observer) { synchronized(mObservers) { mObservers.add(match); mObservers.add(observer); } } /** Removes every key/value pair where value=observer from mObservers */ public void removeObserver(UEventObserver observer) { synchronized(mObservers) { boolean found = true; while (found) { found = false; for (int i = 0; i < mObservers.size(); i += 2) { if (mObservers.get(i+1) == observer) { mObservers.remove(i+1); mObservers.remove(i); found = true; break; private void sendEvent(String message) { synchronized (mKeysAndObservers) { final int N = mKeysAndObservers.size(); for (int i = 0; i < N; i += 2) { final String key = (String)mKeysAndObservers.get(i); if (message.indexOf(key) != -1) { final UEventObserver observer = (UEventObserver)mKeysAndObservers.get(i + 1); mTempObserversToSignal.add(observer); } } } if (!mTempObserversToSignal.isEmpty()) { final UEvent event = new UEvent(message); final int N = mTempObserversToSignal.size(); for (int i = 0; i < N; i++) { final UEventObserver observer = mTempObserversToSignal.get(i); observer.onUEvent(event); } mTempObserversToSignal.clear(); } } private static native void native_setup(); private static native int next_event(byte[] buffer); private static final synchronized void ensureThreadStarted() { if (sThreadStarted == false) { sThread = new UEventThread(); sThread.start(); sThreadStarted = true; public void addObserver(String match, UEventObserver observer) { synchronized (mKeysAndObservers) { mKeysAndObservers.add(match); mKeysAndObservers.add(observer); } } /** * Begin observation of UEvent's.<p> * This method will cause the UEvent thread to start if this is the first * invocation of startObserving in this process.<p> * Once called, the UEvent thread will call onUEvent() when an incoming * UEvent matches the specified string.<p> * This method can be called multiple times to register multiple matches. * Only one call to stopObserving is required even with multiple registered * matches. * @param match A substring of the UEvent to match. Use "" to match all * UEvent's */ public final synchronized void startObserving(String match) { ensureThreadStarted(); sThread.addObserver(match, this); /** Removes every key/value pair where value=observer from mObservers */ public void removeObserver(UEventObserver observer) { synchronized (mKeysAndObservers) { for (int i = 0; i < mKeysAndObservers.size(); ) { if (mKeysAndObservers.get(i + 1) == observer) { mKeysAndObservers.remove(i + 1); mKeysAndObservers.remove(i); } else { i += 2; } } /** * End observation of UEvent's.<p> * This process's UEvent thread will never call onUEvent() on this * UEventObserver after this call. Repeated calls have no effect. */ public final synchronized void stopObserving() { sThread.removeObserver(this); } /** * Subclasses of UEventObserver should override this method to handle * UEvents. */ public abstract void onUEvent(UEvent event); protected void finalize() throws Throwable { try { stopObserving(); } finally { super.finalize(); } } }
services/java/com/android/server/DockObserver.java +121 −112 Original line number Diff line number Diff line Loading @@ -18,10 +18,6 @@ package com.android.server; import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK; import com.android.server.power.PowerManagerService; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; Loading @@ -30,6 +26,7 @@ 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; Loading @@ -47,7 +44,7 @@ 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; Loading @@ -56,7 +53,9 @@ class DockObserver extends UEventObserver { private static final int DEFAULT_DOCK = 1; private static final int MSG_DOCK_STATE = 0; 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; Loading @@ -78,7 +77,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) { Loading @@ -96,7 +95,7 @@ class DockObserver extends UEventObserver { (PowerManager)mContext.getSystemService(Context.POWER_SERVICE); pm.wakeUp(SystemClock.uptimeMillis()); } update(); updateLocked(); } } } catch (NumberFormatException e) { Loading @@ -105,46 +104,42 @@ class DockObserver extends UEventObserver { } } private final void init() { char[] buffer = new char[1024]; 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(); 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); } } } 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 static boolean isScreenSaverActivatedOnDock(Context context) { return 0 != Settings.Secure.getInt( context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK); 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) { private void handleDockStateChange() { synchronized (mLock) { Slog.i(TAG, "Dock state changed: " + mDockState); final ContentResolver cr = mContext.getContentResolver(); Loading @@ -154,6 +149,7 @@ class DockObserver extends UEventObserver { 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); Loading @@ -161,16 +157,16 @@ class DockObserver extends UEventObserver { // 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)); // 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) { Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1) { String whichSound = null; if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) || Loading Loading @@ -231,6 +227,19 @@ class DockObserver extends UEventObserver { mContext.sendStickyBroadcast(intent); } } } private static boolean isScreenSaverActivatedOnDock(Context context) { return Settings.Secure.getInt(context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK) != 0; } private final Handler mHandler = new Handler(Looper.myLooper(), null, true) { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_DOCK_STATE_CHANGED: handleDockStateChange(); break; } } Loading
services/java/com/android/server/WiredAccessoryObserver.java +153 −152 File changed.Preview size limit exceeded, changes collapsed. Show changes