I have not been a Windows user since XP was the new big thing, and even before that time, I was not a big fan of Windows. Why? Well Windows have always had a thing where it was trying to push every single one of my buttons, which often resulted in hardware pieces (Mouse, Keyboard, Monitors, etc.) being thrown across a room. This ended up becoming to expensive, and I decided to give Linux a try instead, which have saved me a lot on hardware purchases.
But living in a Microsoft world while being the guy known to have IT knowledge, it is not so easy to get rid of Windows 100%, although you might not use it at home. Once in awhile, people you know will come to you with their Windows problems. Most of the time I tell them to use a system that I want to support, if they require me to do so. I did not switch away from my Windows problems just to take on every one else's.
But for some reason I did not say no when I friend of mine came to me to get help formatting he's laptop. I thought that since Windows is now at version 8, a lot must have changed since the old XP. A quick format and a few driver installs would properly not take up to much of my time, especially since all the drivers was stored on a USB pen drive. But just as I remember it, things are never that easy with Windows. The installation went fine, the newly installed Windows booted without issues, only a few driver installs remained. I plugged-in the USB pen drive and opened 'My Computer', just like I would do on my Linux machines, which takes about half a second to load USB devices. But Windows did not load it, instead it pops up with a small yellow driver install notification in the button right corner? Well okay. But then it fails to locate a driver? A simple UNIVERSAL Mass Storage device with a Microsoft msdos partition table containing a Microsoft Fat32 file system, fails to load on a brand new Microsoft Windows 8 operating system?
I plugged-in the USB pen drive into my own laptop, running on Fedora 20, and my file manager opened right away, displaying the content of the drive. Now which of these operating system is known for being so user friendly?
I cannot specify how I managed to get this drive working. I spent about an hour playing around in the control panel, unloading/loading drivers, plug/unplugging the USB pen drive, trouble shooting and much more. Finally at some point, for some reason, it started working. But I would really not call this user friendly, especially since this is just one small example of the many issues one will stumble upon, when working with Windows. This operating system takes to much of once time on ridicules tasks like this and it increases your blood pressure to a very dangerous level. Why people keep insisting on using it, I really don't know. I find *nix systems like Linux, OSX and such, much more friendly to work with. Use those and you might even live longer.
Thursday, October 9, 2014
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.
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.
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.
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:
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:
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:
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:
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:
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:
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();
}
}
Subscribe to:
Posts (Atom)