aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/hoopajoo/android/RemoteContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/hoopajoo/android/RemoteContext.java')
-rw-r--r--src/net/hoopajoo/android/RemoteContext.java139
1 files changed, 139 insertions, 0 deletions
diff --git a/src/net/hoopajoo/android/RemoteContext.java b/src/net/hoopajoo/android/RemoteContext.java
new file mode 100644
index 0000000..bf44cad
--- /dev/null
+++ b/src/net/hoopajoo/android/RemoteContext.java
@@ -0,0 +1,139 @@
+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() );
+ }
+ }
+}