2014-07-29

How to call system service in ADB?

    We can call system service via ADB. For example below command can set system timezone in ADB.

$ adb shell service
Usage: service [-h|-?]
       service list
       service check SERVICE
       service call SERVICE CODE [i32 INT | s16 STR] ...
Options:
   i32: Write the integer INT into the send parcel.
   s16: Write the UTF-16 string STR into the send parcel.

$ adb shell service call alarm 5 s16 "Asia/Shanghai"

    For every "service call" command, you need to enter:
        - the service you want to call, in this case it is "alarm";
        - the "function" you want to call, in this case it is "5";
        - the function parameters.

    How we figure out above stuff? Here's more details...

1. Check all services available on your device;
$ adb shell service list
Found 81 services:
0    dun: [com.android.QualcommSettings.IDun]
1    sip: [android.net.sip.ISipService]
2    phone_msim: [com.android.internal.telephony.msim.ITelephonyMSim]
...
49    input: [android.hardware.input.IInputManager]
50    window: [android.view.IWindowManager]
51    alarm: [android.app.IAlarmManager]
52    vibrator: [android.os.IVibratorService]
...
79    media.audio_flinger: [android.media.IAudioFlinger]
80    drm.drmManager: [drm.IDrmManagerService]


    In above list, we know 'alarm' is the service name we want to use.

2. Check if the alarm service is up and running
$adb shell service check alarm
Service alarm: found


3. In Step 1, we can see there's alarm service supply by IAlarmManager? class. Find IAlarmManager? and its implementation.
$ find ./out -name IAlarmManager?.*
./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/app/IAlarmManager.P
./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/app/IAlarmManager.java
./out/host/common/obj/JAVA_LIBRARIES/layoutlib_intermediates/classes/android/app/IAlarmManager.class


   Check what alarm service interfaces we can call in command line(ADB)
$vim ./out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/app/IAlarmManager.java

   In the buttom of the source file, we can see alarm service provider below interfaces.

288 public void set(int type, long triggerAtTime, android.app.PendingIntent operation) throws android.os.RemoteException;
289 public void setRepeating(int type, long triggerAtTime, long interval, android.app.PendingIntent operation) throws android.os
290 public void setInexactRepeating(int type, long triggerAtTime, long interval, android.app.PendingIntent operation) throws and
291 public void setTime(long millis) throws android.os.RemoteException;
292 public void setTimeZone(java.lang.String zone) throws android.os.RemoteException;
293 public void remove(android.app.PendingIntent operation) throws android.os.RemoteException;

   setTimeZone API is what we need. The input parameter is java.lang.String(s16). Now check its order...

281 static final int TRANSACTION_set = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
282 static final int TRANSACTION_setRepeating = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
283 static final int TRANSACTION_setInexactRepeating = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
284 static final int TRANSACTION_setTime = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
285 static final int TRANSACTION_setTimeZone = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
286 static final int TRANSACTION_remove = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);


   The order of TRANSACTION_setTimeZone is 5(0-based).

 

No comments: