Pages

Wednesday, February 12, 2014

Android Resources

This is not a guide or an article. It is mainly an observation that I can no longer ignorer. The issue is that most Android developers have a habit of working out custom solutions using the few tools that they know, rather than looking to see if Android has a pee-built tool for that specific task.

In this case, the issue is regarding Android's Resources class. Let's say that we want to create a dynamic string using placeholders. If you try to google this, you will mostly find the same solution on each page that you visit. I have written this solution below.

<resources>
    <string name="dynamic_string">Let\'s insert the number %1$d</string>
</resources>

Integer numberToInsert = 1;
String dynamicString = String.format( getResources().getString(R.string.welcome_messages), numberToInsert );

The problem here is that there is no point in including String.format into this, because Resources.getString is already able to do this for you.

Integer numberToInsert = 1;
String dynamicString = getResources().getString(R.string.welcome_messages, numberToInsert );

If you took a look at the documentation for this method, you would see that it does not only take [String] as an argument. It actually takes [String, Object...], where each Object parsed will be used to replace the placeholders of the string.

Please have a look at the Resources Documentation. This class contains a lot of useful tools for when working with the resources in Android. Many of which is not seen being used very much, if even at all.

Friday, November 8, 2013

Custom System Service using XposedBridge

For those of you who don't know XposedBridge, you should really have a look at it. By enabling you to hook any Class and Method within Android, system classes as well as normal application classes, this is just as powerful a tool as a root shell session. This however operates within the Java VM instead of hacking your way in from a shell.

After working with XposedBridge for awhile, I started stumbling across a few limitations. The Xposed Framework might be able to hook any method in any class, but it can of cause only add a hook before and after execution of the original method. This means that you cannot change anything within a method, but instead either replace it, change the arguments being parsed to it or change the result from it. In most cases this will be enough, however since Android parses a lot of things between multiple processes in JVM and Native code (which you cannot hook), there are circumstances where this will not be enough. For an example, if you decide to add a hook to PhoneWindowManager's interceptKeyBeforeQueueing or interceptKeyBeforeDispatching methods to change the incoming key code or some policy flags, that hook will not be enough. The two original methods will be executed with these new values, but after they have executed, the Native Event Handler will parse the original values to the application dispatchers, and your hook changes will not affect that part. This means that you would also have to add a hook to the KeyEvent's dispatch method. But, since that one will run in different processes than your first hook(s), you cannot share data between them, not even if you add all hooks to one single class instance or use a static class.

In some cases, you can use Broadcasts to send data from one process to another. But the problem with Broadcasts is that you cannot be sure about when the receiver will be invoked or when it is done processing your data. Also, sending a Broadcast or adding a Receiver requires access to a Context, and when working with Xposed you will not always have one of those. The best option in these cases is adding a custom System Service that you can use to share data between processes. The positive thing about System Services, unlike normal Application Services, is that they are available always, from the beginning of System Boot and until the System is shut down. Also they are much easier to connect to. Normally you would not be able to create such a service, but since we are working with XposedBridge, you can actually add whatever you'd like since you can operate as being part of Android.

The first thing that we will need, is an AIDL interface file. You cannot have a System Service without this. In your project, create a new package named android.os and in that package create a new file named ICustomService.aidl that looks like the below example.

android.os.ICustomService.aidl:
package android.os;
/** {@hide} */
interface IXAService {

}

We will also need a class in our regular project package that will be used to hook the service into Android. Create a class named CustomServiceHook.java somewhere in your project package.

CustomServiceHook.java:
public final class CustomServiceHook implements IXposedHookZygoteInit {
 @Override
 public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {
  CustomService.inject();
 }
}

Since you should already be familiar with XposedBridge, you should already know how to add this hook to be invoked by Xposed during boot.

The CustomService class that we call in our hook above is our System Service Class. The inject() method is a static method from where we will inject the Service into Android so that it can be used by our module. Create a new package named com.android.server and create a new class in that package named CustomService.java.

com.android.server.CustomService.java:
public class CustomService extends ICustomService.Stub {
 public static void inject() {

 }
}

This is our basic classes. Now it's time to extend CustomService.java to actually make it work. All of Android's original services are created and registered from com.android.server.SystemServer.java. However, all of the creation and registration is done from within a Thread. The problem here is that this Thread keeps the System Context as a normal variable, so we have no way to access it outside the Run() method. And since we cannot hook our way into the method but only add a hook before or after, this method and class is of no use to us.

However, the first thing that this method does, is invoke the main() method of com.android.server.am.ActivityManagerService in order to get the System Context. So if we add a hook after that method, the hook will be invoked in the beginning of the SystemServer thread, and we will also have access to the System Context which will be in the result from the main() method that we added our hook to. Let's change our CustomService.java file and add this hook to it.

com.android.server.CustomService.java:
public class CustomService extends ICustomService.Stub {

 private Context mContext;

 private static CustomService oInstance;

 public static void inject() {
  final Class ActivityManagerServiceClazz = XposedHelpers.findClass("com.android.server.am.ActivityManagerService", null);
  
  XposedBridge.hookAllMethods(
   ActivityManagerServiceClazz, 
   "main", 
   new XC_MethodHook() {
    @Override
    protected final void afterHookedMethod(final MethodHookParam param) {
     Context context = (Context) param.getResult();
     
     oInstance = new CustomService(context);
     
     XposedHelpers.callMethod(
       XposedTools.findClass("android.os.ServiceManager"), 
       "addService", 
       new Class[]{String.class, IBinder.class}, 
       "custom.service", 
       oInstance
     );
    }
   }
  );
 }

 public XAService(Context context) {
  mContext = context;
 }
}

The service will now be created and registered with Android during boot, but we are not quite done yet. At the time this service is created, no other services are available. So if you want to do some initializing, the constructor is not the place to do it. What we need is yet another hook that will be invoked once the system is ready. The ActivityManagerService class also has a good place for this. It has a systemReady() method that is invoked once all of the services has been created and is up and running. Let's add this to our CustomService class.

com.android.server.CustomService.java:
public class CustomService extends ICustomService.Stub {

 private Context mContext;

 private static CustomService oInstance;

 public static void inject() {
  final Class ActivityManagerServiceClazz = XposedHelpers.findClass("com.android.server.am.ActivityManagerService", null);
  
  XposedBridge.hookAllMethods(
   ActivityManagerServiceClazz, 
   "main", 
   new XC_MethodHook() {
    @Override
    protected final void afterHookedMethod(final MethodHookParam param) {
     Context context = (Context) param.getResult();
     
     oInstance = new CustomService(context);
     
     XposedHelpers.callMethod(
       XposedTools.findClass("android.os.ServiceManager"), 
       "addService", 
       new Class[]{String.class, IBinder.class}, 
       "custom.service", 
       oInstance
     );
    }
   }
  );

  XposedBridge.hookAllMethods(
   ActivityManagerServiceClazz, 
   "systemReady", 
   new XC_MethodHook() {
    @Override
    protected final void afterHookedMethod(final MethodHookParam param) {
     oInstance.systemReady();
    }
   }
  );
 }

 public XAService(Context context) {
  mContext = context;
 }

 private void systemReady() {
  // Make your initialization here
 }
}

Now you are done. Your new service will now be loaded into Android's ServiceManager during boot via our first hook to the ActivityServiceManager.main() method and it will be initialized once all services is ready via our second hook to ActivityServiceManager.systemReady().

After the initialization, you can access the binder using ServiceManager.getService( name ) just like with any other System Service provided by Android.

All that is left is to implement whatever options you would like this service to provide and start using it in your module.

Example of usage:
public class SomeClass {
 ICustomService mService;
 
 public void someMethod() {
  if (mService == null) {
   mService = ICustomService.Stub.asInterface(
     ServiceManager.getService("custom.service")
   );
  }
  
  mService.someServiceMethod();
 }
}

Friday, August 23, 2013

Controlled Environment

You are building a library of some sort, and you want to have a primary class with additional "extender" classes which all should be accessed through your primary one. Why? Don't know, hopefully you do since your the one making it. However, what is to stop anyone from accessing your "extender" classes directly? You could add your "extender" classes as sub-classes to the primary and make your constructors private or protected. But if your planing on expanding this library a great deal, you will end up with a pretty large file at the end. And splitting your "extender" classes into single files with private and protected constructors will just ensure that not even your primary class will be able to create instances of them. So what's left? I know that some languages actually has a feature which allows you to lock a class and define whom has access to create an instance. I have not worked with Java for long, so I don't know whether or not this feature exists in Java. But there are other ways of doing this, which will actually work in other OOP capable languages as well.

The trick here is Data Types. This is something that Java is very strict about, which makes this so much easier. What you need to do, is have a small class that only your primary can create an instance from. The easiest way is to place this as a sub-class to the primary class. This small class will be used to parse along as an argument to a static method in each "extender" class, who’s job is to return an instance of themselves. Meanwhile we will keep each "extender" constructor private, so that no other can access it. And we will make each class final, so that they cannot be extended in order to bypass this protection.

This is our primary class:
public final class MyPrimary {
    public MyExtender extender(String param) {
        MyTransport transport = new MyTransport();
        transport.arguments = new Object[] { (Object) param };

        return (MyExtender) MyExtender.getInstance( transport ).instance;
    }

    public final static interface MyDataType {}

    public final static class MyTransport {
        private MyTransport() {}

        Object[] arguments;
        MyDataType instance;
    }
}

This is one of our extenders:
public final class MyExtender implements MyDataType {
    public static MyTransport getInstance(MyTransport transport) {
        transport.instance = (MyDataType) new MyExtender( (String) transport.arguments[0] );

        return transport;
    }

    private MyExtender(String param) {
        ...
    }
}

In order to get an instance from MyExtender, you will need to parse through it's getInstance method. However, this method requires a MyTransport argument, which only the primary class can create. From the getInstance method, it will attach an instance of itself and then return the MyTransport object to the primary class. And by implementing MyDataType, you can use the same MyTransport class for any extender classes as they will all be able to be casted to the same data type.

That is all that there is to it. And like mentioned above, this can be used in any OOP language. In some however, you will need some manual checking of data types. PHP for an example does not really care about data types, so you will need to do a manual instanceOf check in the extender getInstance methods to make sure that the argument really is a MyTransport object. But that is not all that difficult to implement.