ApplicationThreadNative.java revision 824c510752fd6a30cdba5ed7324cb80a5043ce26
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
17package android.app;
18
19import android.content.ComponentName;
20import android.content.Intent;
21import android.content.IIntentReceiver;
22import android.content.pm.ActivityInfo;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.ProviderInfo;
25import android.content.pm.ServiceInfo;
26import android.content.res.Configuration;
27import android.os.Binder;
28import android.os.Bundle;
29import android.os.Debug;
30import android.os.Parcelable;
31import android.os.RemoteException;
32import android.os.IBinder;
33import android.os.Parcel;
34import android.os.ParcelFileDescriptor;
35
36import java.io.FileDescriptor;
37import java.io.IOException;
38import java.util.HashMap;
39import java.util.List;
40import java.util.Map;
41
42/** {@hide} */
43public 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        case DUMP_HEAP_TRANSACTION:
408        {
409            data.enforceInterface(IApplicationThread.descriptor);
410            boolean managed = data.readInt() != 0;
411            String path = data.readString();
412            ParcelFileDescriptor fd = data.readInt() != 0
413                    ? data.readFileDescriptor() : null;
414            dumpHeap(managed, path, fd);
415            return true;
416        }
417        }
418
419        return super.onTransact(code, data, reply, flags);
420    }
421
422    public IBinder asBinder()
423    {
424        return this;
425    }
426}
427
428class ApplicationThreadProxy implements IApplicationThread {
429    private final IBinder mRemote;
430
431    public ApplicationThreadProxy(IBinder remote) {
432        mRemote = remote;
433    }
434
435    public final IBinder asBinder() {
436        return mRemote;
437    }
438
439    public final void schedulePauseActivity(IBinder token, boolean finished,
440            boolean userLeaving, int configChanges) throws RemoteException {
441        Parcel data = Parcel.obtain();
442        data.writeInterfaceToken(IApplicationThread.descriptor);
443        data.writeStrongBinder(token);
444        data.writeInt(finished ? 1 : 0);
445        data.writeInt(userLeaving ? 1 :0);
446        data.writeInt(configChanges);
447        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
448                IBinder.FLAG_ONEWAY);
449        data.recycle();
450    }
451
452    public final void scheduleStopActivity(IBinder token, boolean showWindow,
453            int configChanges) throws RemoteException {
454        Parcel data = Parcel.obtain();
455        data.writeInterfaceToken(IApplicationThread.descriptor);
456        data.writeStrongBinder(token);
457        data.writeInt(showWindow ? 1 : 0);
458        data.writeInt(configChanges);
459        mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
460                IBinder.FLAG_ONEWAY);
461        data.recycle();
462    }
463
464    public final void scheduleWindowVisibility(IBinder token,
465            boolean showWindow) throws RemoteException {
466        Parcel data = Parcel.obtain();
467        data.writeInterfaceToken(IApplicationThread.descriptor);
468        data.writeStrongBinder(token);
469        data.writeInt(showWindow ? 1 : 0);
470        mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
471                IBinder.FLAG_ONEWAY);
472        data.recycle();
473    }
474
475    public final void scheduleResumeActivity(IBinder token, boolean isForward)
476            throws RemoteException {
477        Parcel data = Parcel.obtain();
478        data.writeInterfaceToken(IApplicationThread.descriptor);
479        data.writeStrongBinder(token);
480        data.writeInt(isForward ? 1 : 0);
481        mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
482                IBinder.FLAG_ONEWAY);
483        data.recycle();
484    }
485
486    public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
487    		throws RemoteException {
488        Parcel data = Parcel.obtain();
489        data.writeInterfaceToken(IApplicationThread.descriptor);
490        data.writeStrongBinder(token);
491        data.writeTypedList(results);
492        mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
493                IBinder.FLAG_ONEWAY);
494        data.recycle();
495    }
496
497    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
498            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
499    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
500    		throws RemoteException {
501        Parcel data = Parcel.obtain();
502        data.writeInterfaceToken(IApplicationThread.descriptor);
503        intent.writeToParcel(data, 0);
504        data.writeStrongBinder(token);
505        data.writeInt(ident);
506        info.writeToParcel(data, 0);
507        data.writeBundle(state);
508        data.writeTypedList(pendingResults);
509        data.writeTypedList(pendingNewIntents);
510        data.writeInt(notResumed ? 1 : 0);
511        data.writeInt(isForward ? 1 : 0);
512        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
513                IBinder.FLAG_ONEWAY);
514        data.recycle();
515    }
516
517    public final void scheduleRelaunchActivity(IBinder token,
518            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
519            int configChanges, boolean notResumed, Configuration config)
520            throws RemoteException {
521        Parcel data = Parcel.obtain();
522        data.writeInterfaceToken(IApplicationThread.descriptor);
523        data.writeStrongBinder(token);
524        data.writeTypedList(pendingResults);
525        data.writeTypedList(pendingNewIntents);
526        data.writeInt(configChanges);
527        data.writeInt(notResumed ? 1 : 0);
528        if (config != null) {
529            data.writeInt(1);
530            config.writeToParcel(data, 0);
531        } else {
532            data.writeInt(0);
533        }
534        mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
535                IBinder.FLAG_ONEWAY);
536        data.recycle();
537    }
538
539    public void scheduleNewIntent(List<Intent> intents, IBinder token)
540            throws RemoteException {
541        Parcel data = Parcel.obtain();
542        data.writeInterfaceToken(IApplicationThread.descriptor);
543        data.writeTypedList(intents);
544        data.writeStrongBinder(token);
545        mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
546                IBinder.FLAG_ONEWAY);
547        data.recycle();
548    }
549
550    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
551            int configChanges) throws RemoteException {
552        Parcel data = Parcel.obtain();
553        data.writeInterfaceToken(IApplicationThread.descriptor);
554        data.writeStrongBinder(token);
555        data.writeInt(finishing ? 1 : 0);
556        data.writeInt(configChanges);
557        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
558                IBinder.FLAG_ONEWAY);
559        data.recycle();
560    }
561
562    public final void scheduleReceiver(Intent intent, ActivityInfo info,
563            int resultCode, String resultData,
564            Bundle map, boolean sync) throws RemoteException {
565        Parcel data = Parcel.obtain();
566        data.writeInterfaceToken(IApplicationThread.descriptor);
567        intent.writeToParcel(data, 0);
568        info.writeToParcel(data, 0);
569        data.writeInt(resultCode);
570        data.writeString(resultData);
571        data.writeBundle(map);
572        data.writeInt(sync ? 1 : 0);
573        mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
574                IBinder.FLAG_ONEWAY);
575        data.recycle();
576    }
577
578    public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode)
579            throws RemoteException {
580        Parcel data = Parcel.obtain();
581        data.writeInterfaceToken(IApplicationThread.descriptor);
582        app.writeToParcel(data, 0);
583        data.writeInt(backupMode);
584        mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null,
585                IBinder.FLAG_ONEWAY);
586        data.recycle();
587    }
588
589    public final void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException {
590        Parcel data = Parcel.obtain();
591        data.writeInterfaceToken(IApplicationThread.descriptor);
592        app.writeToParcel(data, 0);
593        mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null,
594                IBinder.FLAG_ONEWAY);
595        data.recycle();
596    }
597
598    public final void scheduleCreateService(IBinder token, ServiceInfo info)
599            throws RemoteException {
600        Parcel data = Parcel.obtain();
601        data.writeInterfaceToken(IApplicationThread.descriptor);
602        data.writeStrongBinder(token);
603        info.writeToParcel(data, 0);
604        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
605                IBinder.FLAG_ONEWAY);
606        data.recycle();
607    }
608
609    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
610            throws RemoteException {
611        Parcel data = Parcel.obtain();
612        data.writeInterfaceToken(IApplicationThread.descriptor);
613        data.writeStrongBinder(token);
614        intent.writeToParcel(data, 0);
615        data.writeInt(rebind ? 1 : 0);
616        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
617                IBinder.FLAG_ONEWAY);
618        data.recycle();
619    }
620
621    public final void scheduleUnbindService(IBinder token, Intent intent)
622            throws RemoteException {
623        Parcel data = Parcel.obtain();
624        data.writeInterfaceToken(IApplicationThread.descriptor);
625        data.writeStrongBinder(token);
626        intent.writeToParcel(data, 0);
627        mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
628                IBinder.FLAG_ONEWAY);
629        data.recycle();
630    }
631
632    public final void scheduleServiceArgs(IBinder token, int startId,
633	    int flags, Intent args) throws RemoteException {
634        Parcel data = Parcel.obtain();
635        data.writeInterfaceToken(IApplicationThread.descriptor);
636        data.writeStrongBinder(token);
637        data.writeInt(startId);
638        data.writeInt(flags);
639        if (args != null) {
640            data.writeInt(1);
641            args.writeToParcel(data, 0);
642        } else {
643            data.writeInt(0);
644        }
645        mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
646                IBinder.FLAG_ONEWAY);
647        data.recycle();
648    }
649
650    public final void scheduleStopService(IBinder token)
651            throws RemoteException {
652        Parcel data = Parcel.obtain();
653        data.writeInterfaceToken(IApplicationThread.descriptor);
654        data.writeStrongBinder(token);
655        mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
656                IBinder.FLAG_ONEWAY);
657        data.recycle();
658    }
659
660    public final void bindApplication(String packageName, ApplicationInfo info,
661            List<ProviderInfo> providers, ComponentName testName,
662            String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode,
663            boolean restrictedBackupMode, Configuration config,
664            Map<String, IBinder> services) throws RemoteException {
665        Parcel data = Parcel.obtain();
666        data.writeInterfaceToken(IApplicationThread.descriptor);
667        data.writeString(packageName);
668        info.writeToParcel(data, 0);
669        data.writeTypedList(providers);
670        if (testName == null) {
671            data.writeInt(0);
672        } else {
673            data.writeInt(1);
674            testName.writeToParcel(data, 0);
675        }
676        data.writeString(profileName);
677        data.writeBundle(testArgs);
678        data.writeStrongInterface(testWatcher);
679        data.writeInt(debugMode);
680        data.writeInt(restrictedBackupMode ? 1 : 0);
681        config.writeToParcel(data, 0);
682        data.writeMap(services);
683        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
684                IBinder.FLAG_ONEWAY);
685        data.recycle();
686    }
687
688    public final void scheduleExit() throws RemoteException {
689        Parcel data = Parcel.obtain();
690        data.writeInterfaceToken(IApplicationThread.descriptor);
691        mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
692                IBinder.FLAG_ONEWAY);
693        data.recycle();
694    }
695
696    public final void scheduleSuicide() throws RemoteException {
697        Parcel data = Parcel.obtain();
698        data.writeInterfaceToken(IApplicationThread.descriptor);
699        mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
700                IBinder.FLAG_ONEWAY);
701        data.recycle();
702    }
703
704    public final void requestThumbnail(IBinder token)
705            throws RemoteException {
706        Parcel data = Parcel.obtain();
707        data.writeInterfaceToken(IApplicationThread.descriptor);
708        data.writeStrongBinder(token);
709        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
710                IBinder.FLAG_ONEWAY);
711        data.recycle();
712    }
713
714    public final void scheduleConfigurationChanged(Configuration config)
715            throws RemoteException {
716        Parcel data = Parcel.obtain();
717        data.writeInterfaceToken(IApplicationThread.descriptor);
718        config.writeToParcel(data, 0);
719        mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
720                IBinder.FLAG_ONEWAY);
721        data.recycle();
722    }
723
724    public void updateTimeZone() throws RemoteException {
725        Parcel data = Parcel.obtain();
726        data.writeInterfaceToken(IApplicationThread.descriptor);
727        mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
728                IBinder.FLAG_ONEWAY);
729        data.recycle();
730    }
731
732    public void processInBackground() throws RemoteException {
733        Parcel data = Parcel.obtain();
734        data.writeInterfaceToken(IApplicationThread.descriptor);
735        mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
736                IBinder.FLAG_ONEWAY);
737        data.recycle();
738    }
739
740    public void dumpService(FileDescriptor fd, IBinder token, String[] args)
741            throws RemoteException {
742        Parcel data = Parcel.obtain();
743        data.writeInterfaceToken(IApplicationThread.descriptor);
744        data.writeFileDescriptor(fd);
745        data.writeStrongBinder(token);
746        data.writeStringArray(args);
747        mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0);
748        data.recycle();
749    }
750
751    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
752            int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
753            throws RemoteException {
754        Parcel data = Parcel.obtain();
755        data.writeInterfaceToken(IApplicationThread.descriptor);
756        data.writeStrongBinder(receiver.asBinder());
757        intent.writeToParcel(data, 0);
758        data.writeInt(resultCode);
759        data.writeString(dataStr);
760        data.writeBundle(extras);
761        data.writeInt(ordered ? 1 : 0);
762        data.writeInt(sticky ? 1 : 0);
763        mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
764                IBinder.FLAG_ONEWAY);
765        data.recycle();
766    }
767
768    public final void scheduleLowMemory() throws RemoteException {
769        Parcel data = Parcel.obtain();
770        data.writeInterfaceToken(IApplicationThread.descriptor);
771        mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
772                IBinder.FLAG_ONEWAY);
773        data.recycle();
774    }
775
776    public final void scheduleActivityConfigurationChanged(
777            IBinder token) throws RemoteException {
778        Parcel data = Parcel.obtain();
779        data.writeInterfaceToken(IApplicationThread.descriptor);
780        data.writeStrongBinder(token);
781        mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
782                IBinder.FLAG_ONEWAY);
783        data.recycle();
784    }
785
786    public void profilerControl(boolean start, String path,
787            ParcelFileDescriptor fd) throws RemoteException {
788        Parcel data = Parcel.obtain();
789        data.writeInterfaceToken(IApplicationThread.descriptor);
790        data.writeInt(start ? 1 : 0);
791        data.writeString(path);
792        if (fd != null) {
793            data.writeInt(1);
794            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
795        } else {
796            data.writeInt(0);
797        }
798        mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
799                IBinder.FLAG_ONEWAY);
800        data.recycle();
801    }
802
803    public void setSchedulingGroup(int group) throws RemoteException {
804        Parcel data = Parcel.obtain();
805        data.writeInterfaceToken(IApplicationThread.descriptor);
806        data.writeInt(group);
807        mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
808                IBinder.FLAG_ONEWAY);
809        data.recycle();
810    }
811
812    public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
813        Parcel data = Parcel.obtain();
814        Parcel reply = Parcel.obtain();
815        data.writeInterfaceToken(IApplicationThread.descriptor);
816        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
817        reply.readException();
818        outInfo.readFromParcel(reply);
819        data.recycle();
820        reply.recycle();
821    }
822
823    public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
824        Parcel data = Parcel.obtain();
825        data.writeInterfaceToken(IApplicationThread.descriptor);
826        data.writeInt(cmd);
827        data.writeStringArray(packages);
828        mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
829                IBinder.FLAG_ONEWAY);
830        data.recycle();
831
832    }
833
834    public void scheduleCrash(String msg) throws RemoteException {
835        Parcel data = Parcel.obtain();
836        data.writeInterfaceToken(IApplicationThread.descriptor);
837        data.writeString(msg);
838        mRemote.transact(SCHEDULE_CRASH_TRANSACTION, data, null,
839                IBinder.FLAG_ONEWAY);
840        data.recycle();
841
842    }
843
844    public void dumpHeap(boolean managed, String path,
845            ParcelFileDescriptor fd) throws RemoteException {
846        Parcel data = Parcel.obtain();
847        data.writeInterfaceToken(IApplicationThread.descriptor);
848        data.writeInt(managed ? 1 : 0);
849        data.writeString(path);
850        if (fd != null) {
851            data.writeInt(1);
852            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
853        } else {
854            data.writeInt(0);
855        }
856        mRemote.transact(DUMP_HEAP_TRANSACTION, data, null,
857                IBinder.FLAG_ONEWAY);
858        data.recycle();
859    }
860}
861
862