Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app;
     18 
     19 import android.content.ComponentName;
     20 import android.content.Intent;
     21 import android.content.IIntentReceiver;
     22 import android.content.pm.ActivityInfo;
     23 import android.content.pm.ApplicationInfo;
     24 import android.content.pm.ProviderInfo;
     25 import android.content.pm.ServiceInfo;
     26 import android.content.res.Configuration;
     27 import android.os.Binder;
     28 import android.os.Bundle;
     29 import android.os.Debug;
     30 import android.os.Parcelable;
     31 import android.os.RemoteException;
     32 import android.os.IBinder;
     33 import android.os.Parcel;
     34 import android.os.ParcelFileDescriptor;
     35 
     36 import java.io.FileDescriptor;
     37 import java.io.IOException;
     38 import java.util.HashMap;
     39 import java.util.List;
     40 import java.util.Map;
     41 
     42 /** {@hide} */
     43 public abstract class ApplicationThreadNative extends Binder
     44         implements IApplicationThread {
     45     /**
     46      * Cast a Binder object into an application thread interface, generating
     47      * a proxy if needed.
     48      */
     49     static public IApplicationThread asInterface(IBinder obj) {
     50         if (obj == null) {
     51             return null;
     52         }
     53         IApplicationThread in =
     54             (IApplicationThread)obj.queryLocalInterface(descriptor);
     55         if (in != null) {
     56             return in;
     57         }
     58 
     59         return new ApplicationThreadProxy(obj);
     60     }
     61 
     62     public ApplicationThreadNative() {
     63         attachInterface(this, descriptor);
     64     }
     65 
     66     @Override
     67     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
     68             throws RemoteException {
     69         switch (code) {
     70         case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
     71         {
     72             data.enforceInterface(IApplicationThread.descriptor);
     73             IBinder b = data.readStrongBinder();
     74             boolean finished = data.readInt() != 0;
     75             boolean userLeaving = data.readInt() != 0;
     76             int configChanges = data.readInt();
     77             schedulePauseActivity(b, finished, userLeaving, configChanges);
     78             return true;
     79         }
     80 
     81         case SCHEDULE_STOP_ACTIVITY_TRANSACTION:
     82         {
     83             data.enforceInterface(IApplicationThread.descriptor);
     84             IBinder b = data.readStrongBinder();
     85             boolean show = data.readInt() != 0;
     86             int configChanges = data.readInt();
     87             scheduleStopActivity(b, show, configChanges);
     88             return true;
     89         }
     90 
     91         case SCHEDULE_WINDOW_VISIBILITY_TRANSACTION:
     92         {
     93             data.enforceInterface(IApplicationThread.descriptor);
     94             IBinder b = data.readStrongBinder();
     95             boolean show = data.readInt() != 0;
     96             scheduleWindowVisibility(b, show);
     97             return true;
     98         }
     99 
    100         case SCHEDULE_RESUME_ACTIVITY_TRANSACTION:
    101         {
    102             data.enforceInterface(IApplicationThread.descriptor);
    103             IBinder b = data.readStrongBinder();
    104             boolean isForward = data.readInt() != 0;
    105             scheduleResumeActivity(b, isForward);
    106             return true;
    107         }
    108 
    109         case SCHEDULE_SEND_RESULT_TRANSACTION:
    110         {
    111             data.enforceInterface(IApplicationThread.descriptor);
    112             IBinder b = data.readStrongBinder();
    113             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
    114             scheduleSendResult(b, ri);
    115             return true;
    116         }
    117 
    118         case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
    119         {
    120             data.enforceInterface(IApplicationThread.descriptor);
    121             Intent intent = Intent.CREATOR.createFromParcel(data);
    122             IBinder b = data.readStrongBinder();
    123             int ident = data.readInt();
    124             ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
    125             Bundle state = data.readBundle();
    126             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
    127             List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
    128             boolean notResumed = data.readInt() != 0;
    129             boolean isForward = data.readInt() != 0;
    130             scheduleLaunchActivity(intent, b, ident, info, state, ri, pi,
    131                     notResumed, isForward);
    132             return true;
    133         }
    134 
    135         case SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION:
    136         {
    137             data.enforceInterface(IApplicationThread.descriptor);
    138             IBinder b = data.readStrongBinder();
    139             List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
    140             List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
    141             int configChanges = data.readInt();
    142             boolean notResumed = data.readInt() != 0;
    143             Configuration config = null;
    144             if (data.readInt() != 0) {
    145                 config = Configuration.CREATOR.createFromParcel(data);
    146             }
    147             scheduleRelaunchActivity(b, ri, pi, configChanges, notResumed, config);
    148             return true;
    149         }
    150 
    151         case SCHEDULE_NEW_INTENT_TRANSACTION:
    152         {
    153             data.enforceInterface(IApplicationThread.descriptor);
    154             List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
    155             IBinder b = data.readStrongBinder();
    156             scheduleNewIntent(pi, b);
    157             return true;
    158         }
    159 
    160         case SCHEDULE_FINISH_ACTIVITY_TRANSACTION:
    161         {
    162             data.enforceInterface(IApplicationThread.descriptor);
    163             IBinder b = data.readStrongBinder();
    164             boolean finishing = data.readInt() != 0;
    165             int configChanges = data.readInt();
    166             scheduleDestroyActivity(b, finishing, configChanges);
    167             return true;
    168         }
    169 
    170         case SCHEDULE_RECEIVER_TRANSACTION:
    171         {
    172             data.enforceInterface(IApplicationThread.descriptor);
    173             Intent intent = Intent.CREATOR.createFromParcel(data);
    174             ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
    175             int resultCode = data.readInt();
    176             String resultData = data.readString();
    177             Bundle resultExtras = data.readBundle();
    178             boolean sync = data.readInt() != 0;
    179             scheduleReceiver(intent, info, resultCode, resultData,
    180                     resultExtras, sync);
    181             return true;
    182         }
    183 
    184         case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
    185             data.enforceInterface(IApplicationThread.descriptor);
    186             IBinder token = data.readStrongBinder();
    187             ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
    188             scheduleCreateService(token, info);
    189             return true;
    190         }
    191 
    192         case SCHEDULE_BIND_SERVICE_TRANSACTION: {
    193             data.enforceInterface(IApplicationThread.descriptor);
    194             IBinder token = data.readStrongBinder();
    195             Intent intent = Intent.CREATOR.createFromParcel(data);
    196             boolean rebind = data.readInt() != 0;
    197             scheduleBindService(token, intent, rebind);
    198             return true;
    199         }
    200 
    201         case SCHEDULE_UNBIND_SERVICE_TRANSACTION: {
    202             data.enforceInterface(IApplicationThread.descriptor);
    203             IBinder token = data.readStrongBinder();
    204             Intent intent = Intent.CREATOR.createFromParcel(data);
    205             scheduleUnbindService(token, intent);
    206             return true;
    207         }
    208 
    209         case SCHEDULE_SERVICE_ARGS_TRANSACTION:
    210         {
    211             data.enforceInterface(IApplicationThread.descriptor);
    212             IBinder token = data.readStrongBinder();
    213             int startId = data.readInt();
    214             int fl = data.readInt();
    215             Intent args;
    216             if (data.readInt() != 0) {
    217                 args = Intent.CREATOR.createFromParcel(data);
    218             } else {
    219                 args = null;
    220             }
    221             scheduleServiceArgs(token, startId, fl, args);
    222             return true;
    223         }
    224 
    225         case SCHEDULE_STOP_SERVICE_TRANSACTION:
    226         {
    227             data.enforceInterface(IApplicationThread.descriptor);
    228             IBinder token = data.readStrongBinder();
    229             scheduleStopService(token);
    230             return true;
    231         }
    232 
    233         case BIND_APPLICATION_TRANSACTION:
    234         {
    235             data.enforceInterface(IApplicationThread.descriptor);
    236             String packageName = data.readString();
    237             ApplicationInfo info =
    238                 ApplicationInfo.CREATOR.createFromParcel(data);
    239             List<ProviderInfo> providers =
    240                 data.createTypedArrayList(ProviderInfo.CREATOR);
    241             ComponentName testName = (data.readInt() != 0)
    242                 ? new ComponentName(data) : null;
    243             String profileName = data.readString();
    244             Bundle testArgs = data.readBundle();
    245             IBinder binder = data.readStrongBinder();
    246             IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
    247             int testMode = data.readInt();
    248             boolean restrictedBackupMode = (data.readInt() != 0);
    249             Configuration config = Configuration.CREATOR.createFromParcel(data);
    250             HashMap<String, IBinder> services = data.readHashMap(null);
    251             bindApplication(packageName, info,
    252                             providers, testName, profileName,
    253                             testArgs, testWatcher, testMode, restrictedBackupMode,
    254                             config, services);
    255             return true;
    256         }
    257 
    258         case SCHEDULE_EXIT_TRANSACTION:
    259         {
    260             data.enforceInterface(IApplicationThread.descriptor);
    261             scheduleExit();
    262             return true;
    263         }
    264 
    265         case SCHEDULE_SUICIDE_TRANSACTION:
    266         {
    267             data.enforceInterface(IApplicationThread.descriptor);
    268             scheduleSuicide();
    269             return true;
    270         }
    271 
    272         case REQUEST_THUMBNAIL_TRANSACTION:
    273         {
    274             data.enforceInterface(IApplicationThread.descriptor);
    275             IBinder b = data.readStrongBinder();
    276             requestThumbnail(b);
    277             return true;
    278         }
    279 
    280         case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
    281         {
    282             data.enforceInterface(IApplicationThread.descriptor);
    283             Configuration config = Configuration.CREATOR.createFromParcel(data);
    284             scheduleConfigurationChanged(config);
    285             return true;
    286         }
    287 
    288         case UPDATE_TIME_ZONE_TRANSACTION: {
    289             data.enforceInterface(IApplicationThread.descriptor);
    290             updateTimeZone();
    291             return true;
    292         }
    293 
    294         case PROCESS_IN_BACKGROUND_TRANSACTION: {
    295             data.enforceInterface(IApplicationThread.descriptor);
    296             processInBackground();
    297             return true;
    298         }
    299 
    300         case DUMP_SERVICE_TRANSACTION: {
    301             data.enforceInterface(IApplicationThread.descriptor);
    302             ParcelFileDescriptor fd = data.readFileDescriptor();
    303             final IBinder service = data.readStrongBinder();
    304             final String[] args = data.readStringArray();
    305             if (fd != null) {
    306                 dumpService(fd.getFileDescriptor(), service, args);
    307                 try {
    308                     fd.close();
    309                 } catch (IOException e) {
    310                 }
    311             }
    312             return true;
    313         }
    314 
    315         case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
    316             data.enforceInterface(IApplicationThread.descriptor);
    317             IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
    318                     data.readStrongBinder());
    319             Intent intent = Intent.CREATOR.createFromParcel(data);
    320             int resultCode = data.readInt();
    321             String dataStr = data.readString();
    322             Bundle extras = data.readBundle();
    323             boolean ordered = data.readInt() != 0;
    324             boolean sticky = data.readInt() != 0;
    325             scheduleRegisteredReceiver(receiver, intent,
    326                     resultCode, dataStr, extras, ordered, sticky);
    327             return true;
    328         }
    329 
    330         case SCHEDULE_LOW_MEMORY_TRANSACTION:
    331         {
    332             scheduleLowMemory();
    333             return true;
    334         }
    335 
    336         case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
    337         {
    338             data.enforceInterface(IApplicationThread.descriptor);
    339             IBinder b = data.readStrongBinder();
    340             scheduleActivityConfigurationChanged(b);
    341             return true;
    342         }
    343 
    344         case PROFILER_CONTROL_TRANSACTION:
    345         {
    346             data.enforceInterface(IApplicationThread.descriptor);
    347             boolean start = data.readInt() != 0;
    348             String path = data.readString();
    349             ParcelFileDescriptor fd = data.readInt() != 0
    350                     ? data.readFileDescriptor() : null;
    351             profilerControl(start, path, fd);
    352             return true;
    353         }
    354 
    355         case SET_SCHEDULING_GROUP_TRANSACTION:
    356         {
    357             data.enforceInterface(IApplicationThread.descriptor);
    358             int group = data.readInt();
    359             setSchedulingGroup(group);
    360             return true;
    361         }
    362 
    363         case SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION:
    364         {
    365             data.enforceInterface(IApplicationThread.descriptor);
    366             ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
    367             int backupMode = data.readInt();
    368             scheduleCreateBackupAgent(appInfo, backupMode);
    369             return true;
    370         }
    371 
    372         case SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION:
    373         {
    374             data.enforceInterface(IApplicationThread.descriptor);
    375             ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
    376             scheduleDestroyBackupAgent(appInfo);
    377             return true;
    378         }
    379 
    380         case GET_MEMORY_INFO_TRANSACTION:
    381         {
    382             data.enforceInterface(IApplicationThread.descriptor);
    383             Debug.MemoryInfo mi = new Debug.MemoryInfo();
    384             getMemoryInfo(mi);
    385             reply.writeNoException();
    386             mi.writeToParcel(reply, 0);
    387             return true;
    388         }
    389 
    390         case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
    391         {
    392             data.enforceInterface(IApplicationThread.descriptor);
    393             int cmd = data.readInt();
    394             String[] packages = data.readStringArray();
    395             dispatchPackageBroadcast(cmd, packages);
    396             return true;
    397         }
    398 
    399         case SCHEDULE_CRASH_TRANSACTION:
    400         {
    401             data.enforceInterface(IApplicationThread.descriptor);
    402             String msg = data.readString();
    403             scheduleCrash(msg);
    404             return true;
    405         }
    406         }
    407 
    408         return super.onTransact(code, data, reply, flags);
    409     }
    410 
    411     public IBinder asBinder()
    412     {
    413         return this;
    414     }
    415 }
    416 
    417 class ApplicationThreadProxy implements IApplicationThread {
    418     private final IBinder mRemote;
    419 
    420     public ApplicationThreadProxy(IBinder remote) {
    421         mRemote = remote;
    422     }
    423 
    424     public final IBinder asBinder() {
    425         return mRemote;
    426     }
    427 
    428     public final void schedulePauseActivity(IBinder token, boolean finished,
    429             boolean userLeaving, int configChanges) throws RemoteException {
    430         Parcel data = Parcel.obtain();
    431         data.writeInterfaceToken(IApplicationThread.descriptor);
    432         data.writeStrongBinder(token);
    433         data.writeInt(finished ? 1 : 0);
    434         data.writeInt(userLeaving ? 1 :0);
    435         data.writeInt(configChanges);
    436         mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
    437                 IBinder.FLAG_ONEWAY);
    438         data.recycle();
    439     }
    440 
    441     public final void scheduleStopActivity(IBinder token, boolean showWindow,
    442             int configChanges) throws RemoteException {
    443         Parcel data = Parcel.obtain();
    444         data.writeInterfaceToken(IApplicationThread.descriptor);
    445         data.writeStrongBinder(token);
    446         data.writeInt(showWindow ? 1 : 0);
    447         data.writeInt(configChanges);
    448         mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
    449                 IBinder.FLAG_ONEWAY);
    450         data.recycle();
    451     }
    452 
    453     public final void scheduleWindowVisibility(IBinder token,
    454             boolean showWindow) throws RemoteException {
    455         Parcel data = Parcel.obtain();
    456         data.writeInterfaceToken(IApplicationThread.descriptor);
    457         data.writeStrongBinder(token);
    458         data.writeInt(showWindow ? 1 : 0);
    459         mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
    460                 IBinder.FLAG_ONEWAY);
    461         data.recycle();
    462     }
    463 
    464     public final void scheduleResumeActivity(IBinder token, boolean isForward)
    465             throws RemoteException {
    466         Parcel data = Parcel.obtain();
    467         data.writeInterfaceToken(IApplicationThread.descriptor);
    468         data.writeStrongBinder(token);
    469         data.writeInt(isForward ? 1 : 0);
    470         mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
    471                 IBinder.FLAG_ONEWAY);
    472         data.recycle();
    473     }
    474 
    475     public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
    476     		throws RemoteException {
    477         Parcel data = Parcel.obtain();
    478         data.writeInterfaceToken(IApplicationThread.descriptor);
    479         data.writeStrongBinder(token);
    480         data.writeTypedList(results);
    481         mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
    482                 IBinder.FLAG_ONEWAY);
    483         data.recycle();
    484     }
    485 
    486     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
    487             ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
    488     		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
    489     		throws RemoteException {
    490         Parcel data = Parcel.obtain();
    491         data.writeInterfaceToken(IApplicationThread.descriptor);
    492         intent.writeToParcel(data, 0);
    493         data.writeStrongBinder(token);
    494         data.writeInt(ident);
    495         info.writeToParcel(data, 0);
    496         data.writeBundle(state);
    497         data.writeTypedList(pendingResults);
    498         data.writeTypedList(pendingNewIntents);
    499         data.writeInt(notResumed ? 1 : 0);
    500         data.writeInt(isForward ? 1 : 0);
    501         mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
    502                 IBinder.FLAG_ONEWAY);
    503         data.recycle();
    504     }
    505 
    506     public final void scheduleRelaunchActivity(IBinder token,
    507             List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
    508             int configChanges, boolean notResumed, Configuration config)
    509             throws RemoteException {
    510         Parcel data = Parcel.obtain();
    511         data.writeInterfaceToken(IApplicationThread.descriptor);
    512         data.writeStrongBinder(token);
    513         data.writeTypedList(pendingResults);
    514         data.writeTypedList(pendingNewIntents);
    515         data.writeInt(configChanges);
    516         data.writeInt(notResumed ? 1 : 0);
    517         if (config != null) {
    518             data.writeInt(1);
    519             config.writeToParcel(data, 0);
    520         } else {
    521             data.writeInt(0);
    522         }
    523         mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
    524                 IBinder.FLAG_ONEWAY);
    525         data.recycle();
    526     }
    527 
    528     public void scheduleNewIntent(List<Intent> intents, IBinder token)
    529             throws RemoteException {
    530         Parcel data = Parcel.obtain();
    531         data.writeInterfaceToken(IApplicationThread.descriptor);
    532         data.writeTypedList(intents);
    533         data.writeStrongBinder(token);
    534         mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
    535                 IBinder.FLAG_ONEWAY);
    536         data.recycle();
    537     }
    538 
    539     public final void scheduleDestroyActivity(IBinder token, boolean finishing,
    540             int configChanges) throws RemoteException {
    541         Parcel data = Parcel.obtain();
    542         data.writeInterfaceToken(IApplicationThread.descriptor);
    543         data.writeStrongBinder(token);
    544         data.writeInt(finishing ? 1 : 0);
    545         data.writeInt(configChanges);
    546         mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
    547                 IBinder.FLAG_ONEWAY);
    548         data.recycle();
    549     }
    550 
    551     public final void scheduleReceiver(Intent intent, ActivityInfo info,
    552             int resultCode, String resultData,
    553             Bundle map, boolean sync) throws RemoteException {
    554         Parcel data = Parcel.obtain();
    555         data.writeInterfaceToken(IApplicationThread.descriptor);
    556         intent.writeToParcel(data, 0);
    557         info.writeToParcel(data, 0);
    558         data.writeInt(resultCode);
    559         data.writeString(resultData);
    560         data.writeBundle(map);
    561         data.writeInt(sync ? 1 : 0);
    562         mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
    563                 IBinder.FLAG_ONEWAY);
    564         data.recycle();
    565     }
    566 
    567     public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode)
    568             throws RemoteException {
    569         Parcel data = Parcel.obtain();
    570         data.writeInterfaceToken(IApplicationThread.descriptor);
    571         app.writeToParcel(data, 0);
    572         data.writeInt(backupMode);
    573         mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null,
    574                 IBinder.FLAG_ONEWAY);
    575         data.recycle();
    576     }
    577 
    578     public final void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException {
    579         Parcel data = Parcel.obtain();
    580         data.writeInterfaceToken(IApplicationThread.descriptor);
    581         app.writeToParcel(data, 0);
    582         mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null,
    583                 IBinder.FLAG_ONEWAY);
    584         data.recycle();
    585     }
    586 
    587     public final void scheduleCreateService(IBinder token, ServiceInfo info)
    588             throws RemoteException {
    589         Parcel data = Parcel.obtain();
    590         data.writeInterfaceToken(IApplicationThread.descriptor);
    591         data.writeStrongBinder(token);
    592         info.writeToParcel(data, 0);
    593         mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
    594                 IBinder.FLAG_ONEWAY);
    595         data.recycle();
    596     }
    597 
    598     public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
    599             throws RemoteException {
    600         Parcel data = Parcel.obtain();
    601         data.writeInterfaceToken(IApplicationThread.descriptor);
    602         data.writeStrongBinder(token);
    603         intent.writeToParcel(data, 0);
    604         data.writeInt(rebind ? 1 : 0);
    605         mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
    606                 IBinder.FLAG_ONEWAY);
    607         data.recycle();
    608     }
    609 
    610     public final void scheduleUnbindService(IBinder token, Intent intent)
    611             throws RemoteException {
    612         Parcel data = Parcel.obtain();
    613         data.writeInterfaceToken(IApplicationThread.descriptor);
    614         data.writeStrongBinder(token);
    615         intent.writeToParcel(data, 0);
    616         mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
    617                 IBinder.FLAG_ONEWAY);
    618         data.recycle();
    619     }
    620 
    621     public final void scheduleServiceArgs(IBinder token, int startId,
    622 	    int flags, Intent args) throws RemoteException {
    623         Parcel data = Parcel.obtain();
    624         data.writeInterfaceToken(IApplicationThread.descriptor);
    625         data.writeStrongBinder(token);
    626         data.writeInt(startId);
    627         data.writeInt(flags);
    628         if (args != null) {
    629             data.writeInt(1);
    630             args.writeToParcel(data, 0);
    631         } else {
    632             data.writeInt(0);
    633         }
    634         mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
    635                 IBinder.FLAG_ONEWAY);
    636         data.recycle();
    637     }
    638 
    639     public final void scheduleStopService(IBinder token)
    640             throws RemoteException {
    641         Parcel data = Parcel.obtain();
    642         data.writeInterfaceToken(IApplicationThread.descriptor);
    643         data.writeStrongBinder(token);
    644         mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
    645                 IBinder.FLAG_ONEWAY);
    646         data.recycle();
    647     }
    648 
    649     public final void bindApplication(String packageName, ApplicationInfo info,
    650             List<ProviderInfo> providers, ComponentName testName,
    651             String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode,
    652             boolean restrictedBackupMode, Configuration config,
    653             Map<String, IBinder> services) throws RemoteException {
    654         Parcel data = Parcel.obtain();
    655         data.writeInterfaceToken(IApplicationThread.descriptor);
    656         data.writeString(packageName);
    657         info.writeToParcel(data, 0);
    658         data.writeTypedList(providers);
    659         if (testName == null) {
    660             data.writeInt(0);
    661         } else {
    662             data.writeInt(1);
    663             testName.writeToParcel(data, 0);
    664         }
    665         data.writeString(profileName);
    666         data.writeBundle(testArgs);
    667         data.writeStrongInterface(testWatcher);
    668         data.writeInt(debugMode);
    669         data.writeInt(restrictedBackupMode ? 1 : 0);
    670         config.writeToParcel(data, 0);
    671         data.writeMap(services);
    672         mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
    673                 IBinder.FLAG_ONEWAY);
    674         data.recycle();
    675     }
    676 
    677     public final void scheduleExit() throws RemoteException {
    678         Parcel data = Parcel.obtain();
    679         data.writeInterfaceToken(IApplicationThread.descriptor);
    680         mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
    681                 IBinder.FLAG_ONEWAY);
    682         data.recycle();
    683     }
    684 
    685     public final void scheduleSuicide() throws RemoteException {
    686         Parcel data = Parcel.obtain();
    687         data.writeInterfaceToken(IApplicationThread.descriptor);
    688         mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
    689                 IBinder.FLAG_ONEWAY);
    690         data.recycle();
    691     }
    692 
    693     public final void requestThumbnail(IBinder token)
    694             throws RemoteException {
    695         Parcel data = Parcel.obtain();
    696         data.writeInterfaceToken(IApplicationThread.descriptor);
    697         data.writeStrongBinder(token);
    698         mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
    699                 IBinder.FLAG_ONEWAY);
    700         data.recycle();
    701     }
    702 
    703     public final void scheduleConfigurationChanged(Configuration config)
    704             throws RemoteException {
    705         Parcel data = Parcel.obtain();
    706         data.writeInterfaceToken(IApplicationThread.descriptor);
    707         config.writeToParcel(data, 0);
    708         mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
    709                 IBinder.FLAG_ONEWAY);
    710         data.recycle();
    711     }
    712 
    713     public void updateTimeZone() throws RemoteException {
    714         Parcel data = Parcel.obtain();
    715         data.writeInterfaceToken(IApplicationThread.descriptor);
    716         mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
    717                 IBinder.FLAG_ONEWAY);
    718         data.recycle();
    719     }
    720 
    721     public void processInBackground() throws RemoteException {
    722         Parcel data = Parcel.obtain();
    723         data.writeInterfaceToken(IApplicationThread.descriptor);
    724         mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
    725                 IBinder.FLAG_ONEWAY);
    726         data.recycle();
    727     }
    728 
    729     public void dumpService(FileDescriptor fd, IBinder token, String[] args)
    730             throws RemoteException {
    731         Parcel data = Parcel.obtain();
    732         data.writeInterfaceToken(IApplicationThread.descriptor);
    733         data.writeFileDescriptor(fd);
    734         data.writeStrongBinder(token);
    735         data.writeStringArray(args);
    736         mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0);
    737         data.recycle();
    738     }
    739 
    740     public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
    741             int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
    742             throws RemoteException {
    743         Parcel data = Parcel.obtain();
    744         data.writeInterfaceToken(IApplicationThread.descriptor);
    745         data.writeStrongBinder(receiver.asBinder());
    746         intent.writeToParcel(data, 0);
    747         data.writeInt(resultCode);
    748         data.writeString(dataStr);
    749         data.writeBundle(extras);
    750         data.writeInt(ordered ? 1 : 0);
    751         data.writeInt(sticky ? 1 : 0);
    752         mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
    753                 IBinder.FLAG_ONEWAY);
    754         data.recycle();
    755     }
    756 
    757     public final void scheduleLowMemory() throws RemoteException {
    758         Parcel data = Parcel.obtain();
    759         data.writeInterfaceToken(IApplicationThread.descriptor);
    760         mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
    761                 IBinder.FLAG_ONEWAY);
    762         data.recycle();
    763     }
    764 
    765     public final void scheduleActivityConfigurationChanged(
    766             IBinder token) throws RemoteException {
    767         Parcel data = Parcel.obtain();
    768         data.writeInterfaceToken(IApplicationThread.descriptor);
    769         data.writeStrongBinder(token);
    770         mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
    771                 IBinder.FLAG_ONEWAY);
    772         data.recycle();
    773     }
    774 
    775     public void profilerControl(boolean start, String path,
    776             ParcelFileDescriptor fd) throws RemoteException {
    777         Parcel data = Parcel.obtain();
    778         data.writeInterfaceToken(IApplicationThread.descriptor);
    779         data.writeInt(start ? 1 : 0);
    780         data.writeString(path);
    781         if (fd != null) {
    782             data.writeInt(1);
    783             fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    784         } else {
    785             data.writeInt(0);
    786         }
    787         mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
    788                 IBinder.FLAG_ONEWAY);
    789         data.recycle();
    790     }
    791 
    792     public void setSchedulingGroup(int group) throws RemoteException {
    793         Parcel data = Parcel.obtain();
    794         data.writeInterfaceToken(IApplicationThread.descriptor);
    795         data.writeInt(group);
    796         mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
    797                 IBinder.FLAG_ONEWAY);
    798         data.recycle();
    799     }
    800 
    801     public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
    802         Parcel data = Parcel.obtain();
    803         Parcel reply = Parcel.obtain();
    804         data.writeInterfaceToken(IApplicationThread.descriptor);
    805         mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
    806         reply.readException();
    807         outInfo.readFromParcel(reply);
    808         data.recycle();
    809         reply.recycle();
    810     }
    811 
    812     public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
    813         Parcel data = Parcel.obtain();
    814         data.writeInterfaceToken(IApplicationThread.descriptor);
    815         data.writeInt(cmd);
    816         data.writeStringArray(packages);
    817         mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
    818                 IBinder.FLAG_ONEWAY);
    819         data.recycle();
    820 
    821     }
    822 
    823     public void scheduleCrash(String msg) throws RemoteException {
    824         Parcel data = Parcel.obtain();
    825         data.writeInterfaceToken(IApplicationThread.descriptor);
    826         data.writeString(msg);
    827         mRemote.transact(SCHEDULE_CRASH_TRANSACTION, data, null,
    828                 IBinder.FLAG_ONEWAY);
    829         data.recycle();
    830 
    831     }
    832 }
    833 
    834