aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README27
-rw-r--r--src/android/os/IPowerManager.java14
-rw-r--r--src/android/os/ServiceManager.java7
-rw-r--r--src/android/view/IWindowManager.java15
-rw-r--r--src/net/hoopajoo/android/RemoteContext.java139
5 files changed, 202 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..8f822c2
--- /dev/null
+++ b/README
@@ -0,0 +1,27 @@
+To set up the project:
+
+Go to properties -> add external jar -> path to android/platforms/4/android.jar
+
+
+To create the jar:
+
+Right-click the RootContext.java in eclipse -> export -> jar
+
+This will exclude the stub files needed to compile, creating a normal java
+jar, then you need to make it a dex jar:
+
+dx --dex --outfile output.jar RootContext.jar
+
+Include the output.jar file for the app_process jar
+
+This jar needs to be dx'ed so it will run from android, normally if you
+include a jar in your project and build an apk it will be dx'ed when it is
+put in the apk. Since we use this as an asset and spool it out to run
+natively we must dx it ourself.
+
+The dx tool can also create a jar from a single .class file, so if you
+compiled using a command line tool you can just create the jar from the
+.class:
+
+dx --dex --output=RemoteContext.jar net/hoopajoo/android/RemoteContext.class
+
diff --git a/src/android/os/IPowerManager.java b/src/android/os/IPowerManager.java
new file mode 100644
index 0000000..3ad417b
--- /dev/null
+++ b/src/android/os/IPowerManager.java
@@ -0,0 +1,14 @@
+package android.os;
+
+import android.os.Binder;
+import android.os.IBinder;
+
+public interface IPowerManager {
+ public static class Stub {
+ public static IPowerManager asInterface( IBinder binder ) {
+ return null;
+ }
+ }
+
+ public void goToSleep( long time );
+}
diff --git a/src/android/os/ServiceManager.java b/src/android/os/ServiceManager.java
new file mode 100644
index 0000000..b67d5b3
--- /dev/null
+++ b/src/android/os/ServiceManager.java
@@ -0,0 +1,7 @@
+package android.os;
+
+public class ServiceManager {
+ public static IBinder getService( String serviceName ) throws RemoteException {
+ return null;
+ }
+}
diff --git a/src/android/view/IWindowManager.java b/src/android/view/IWindowManager.java
new file mode 100644
index 0000000..5bba8ca
--- /dev/null
+++ b/src/android/view/IWindowManager.java
@@ -0,0 +1,15 @@
+package android.view;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.KeyEvent;
+
+public interface IWindowManager {
+ public static class Stub {
+ public static IWindowManager asInterface( IBinder binder ) {
+ return null;
+ }
+ }
+
+ public boolean injectKeyEvent( KeyEvent keyEvent, boolean f );
+} \ No newline at end of file
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() );
+ }
+ }
+}