package net.hoopajoo.android; import java.io.BufferedReader; import java.io.InputStreamReader; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemClock; import android.util.Log; import android.view.IWindowManager; import android.view.KeyEvent; import android.os.IPowerManager; import android.content.Context; /* * Inject events as root in to the android framework, accepts commands on stdin, * * This gives finer access control to keydown/up and also to put the device to sleep * * Other things that are blocked from normal apps that have an interface could be added here * like pointer control */ public class RemoteContext { private boolean debug = false; private final String LOG = "RootContext"; public static void main( String[] args ) { (new RemoteContext()).run( args ); } private void run( String[] args ) { if( args.length > 0 ) { debug = true; d( "Debugging enabled" ); } BufferedReader input = new BufferedReader( new InputStreamReader( System.in ), 2 * 1024 ); String cmd; try { while( true ) { cmd = input.readLine(); d( "Read: " + cmd ); String[] parts = cmd.split( " " ); if( debug ) { for( String s : parts ) { d( "Part: " + s ); } } boolean processed = false; if( parts.length > 0 ) { if( parts[ 0 ].startsWith( "key") ) { int code = Integer.parseInt( parts[ 1 ] ); if( parts[ 0 ].equals( "keycode" ) ) { // key down, up d( "Sending keycode: " + code ); sendKeyCode( code, KeyEvent.ACTION_DOWN ); sendKeyCode( code, KeyEvent.ACTION_UP ); processed = true; }else if( parts[ 0 ].equals( "keycodedown" ) ) { d( "Sending keycode DOWN: " + code ); sendKeyCode( code, KeyEvent.ACTION_DOWN ); processed = true; }else if( parts[ 0 ].equals( "keycodeup" ) ) { d( "Sending keycode UP: " + code ); sendKeyCode( code, KeyEvent.ACTION_UP ); processed = true; } } if( parts[ 0 ].equals( "sleep" ) ) { d( "Going to sleep" ); goToSleep(); processed = true; } if( parts[ 0 ].equals( "null" ) ) { d( "null command" ); processed = true; } if( parts[ 0 ].equals( "system" ) ) { Runtime r = Runtime.getRuntime(); String exec = cmd.substring( "system ".length() ); d( "Executing shell command: '" + exec + "'" ); r.exec( exec ); processed = true; } } if( ! processed ) { Log.e( LOG, "Failed to process input: " + cmd ); d( "Failed to process input: " + cmd ); } } }catch( Exception e ) { Log.i( LOG, e.toString() ); } d( "Finished" ); } private void d( String s ) { if( debug ) { //System.out.println( s ); Log.d( LOG, s ); } } private void sendKeyCode( int code, int action ) { long now = SystemClock.uptimeMillis(); KeyEvent k = new KeyEvent(now, now, action, code, 0); try { ( IWindowManager.Stub .asInterface( ServiceManager.getService( Context.WINDOW_SERVICE) ) ) .injectKeyEvent( k , true ); } catch (RemoteException e) { Log.i( LOG, e.toString() ); } } private void goToSleep() { try { ( IPowerManager.Stub .asInterface( ServiceManager.getService( Context.POWER_SERVICE ) ) ) .goToSleep( SystemClock.uptimeMillis() ); } catch (RemoteException e) { Log.i( LOG, e.toString() ); } } }