ApplicationThreadNative.java revision 03595d01188d88c169e8c9dd51b357fd545e69cc
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 CLEAR_DNS_CACHE_TRANSACTION: {
295            data.enforceInterface(IApplicationThread.descriptor);
296            clearDnsCache();
297            return true;
298        }
299
300        case PROCESS_IN_BACKGROUND_TRANSACTION: {
301            data.enforceInterface(IApplicationThread.descriptor);
302            processInBackground();
303            return true;
304        }
305
306        case DUMP_SERVICE_TRANSACTION: {
307            data.enforceInterface(IApplicationThread.descriptor);
308            ParcelFileDescriptor fd = data.readFileDescriptor();
309            final IBinder service = data.readStrongBinder();
310            final String[] args = data.readStringArray();
311            if (fd != null) {
312                dumpService(fd.getFileDescriptor(), service, args);
313                try {
314                    fd.close();
315                } catch (IOException e) {
316                }
317            }
318            return true;
319        }
320
321        case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
322            data.enforceInterface(IApplicationThread.descriptor);
323            IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
324                    data.readStrongBinder());
325            Intent intent = Intent.CREATOR.createFromParcel(data);
326            int resultCode = data.readInt();
327            String dataStr = data.readString();
328            Bundle extras = data.readBundle();
329            boolean ordered = data.readInt() != 0;
330            boolean sticky = data.readInt() != 0;
331            scheduleRegisteredReceiver(receiver, intent,
332                    resultCode, dataStr, extras, ordered, sticky);
333            return true;
334        }
335
336        case SCHEDULE_LOW_MEMORY_TRANSACTION:
337        {
338            scheduleLowMemory();
339            return true;
340        }
341
342        case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
343        {
344            data.enforceInterface(IApplicationThread.descriptor);
345            IBinder b = data.readStrongBinder();
346            scheduleActivityConfigurationChanged(b);
347            return true;
348        }
349
350        case PROFILER_CONTROL_TRANSACTION:
351        {
352            data.enforceInterface(IApplicationThread.descriptor);
353            boolean start = data.readInt() != 0;
354            String path = data.readString();
355            ParcelFileDescriptor fd = data.readInt() != 0
356                    ? data.readFileDescriptor() : null;
357            profilerControl(start, path, fd);
358            return true;
359        }
360
361        case SET_SCHEDULING_GROUP_TRANSACTION:
362        {
363            data.enforceInterface(IApplicationThread.descriptor);
364            int group = data.readInt();
365            setSchedulingGroup(group);
366            return true;
367        }
368
369        case SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION:
370        {
371            data.enforceInterface(IApplicationThread.descriptor);
372            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
373            int backupMode = data.readInt();
374            scheduleCreateBackupAgent(appInfo, backupMode);
375            return true;
376        }
377
378        case SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION:
379        {
380            data.enforceInterface(IApplicationThread.descriptor);
381            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
382            scheduleDestroyBackupAgent(appInfo);
383            return true;
384        }
385
386        case GET_MEMORY_INFO_TRANSACTION:
387        {
388            data.enforceInterface(IApplicationThread.descriptor);
389            Debug.MemoryInfo mi = new Debug.MemoryInfo();
390            getMemoryInfo(mi);
391            reply.writeNoException();
392            mi.writeToParcel(reply, 0);
393            return true;
394        }
395
396        case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
397        {
398            data.enforceInterface(IApplicationThread.descriptor);
399            int cmd = data.readInt();
400            String[] packages = data.readStringArray();
401            dispatchPackageBroadcast(cmd, packages);
402            return true;
403        }
404
405        case SCHEDULE_CRASH_TRANSACTION:
406        {
407            data.enforceInterface(IApplicationThread.descriptor);
408            String msg = data.readString();
409            scheduleCrash(msg);
410            return true;
411        }
412
413        case DUMP_HEAP_TRANSACTION:
414        {
415            data.enforceInterface(IApplicationThread.descriptor);
416            boolean managed = data.readInt() != 0;
417            String path = data.readString();
418            ParcelFileDescriptor fd = data.readInt() != 0
419                    ? data.readFileDescriptor() : null;
420            dumpHeap(managed, path, fd);
421            return true;
422        }
423
424        case DUMP_ACTIVITY_TRANSACTION: {
425            data.enforceInterface(IApplicationThread.descriptor);
426            ParcelFileDescriptor fd = data.readFileDescriptor();
427            final IBinder activity = data.readStrongBinder();
428            final String[] args = data.readStringArray();
429            if (fd != null) {
430                dumpActivity(fd.getFileDescriptor(), activity, args);
431                try {
432                    fd.close();
433                } catch (IOException e) {
434                }
435            }
436            return true;
437        }
438        }
439
440        return super.onTransact(code, data, reply, flags);
441    }
442
443    public IBinder asBinder()
444    {
445        return this;
446    }
447}
448
449class ApplicationThreadProxy implements IApplicationThread {
450    private final IBinder mRemote;
451
452    public ApplicationThreadProxy(IBinder remote) {
453        mRemote = remote;
454    }
455
456    public final IBinder asBinder() {
457        return mRemote;
458    }
459
460    public final void schedulePauseActivity(IBinder token, boolean finished,
461            boolean userLeaving, int configChanges) throws RemoteException {
462        Parcel data = Parcel.obtain();
463        data.writeInterfaceToken(IApplicationThread.descriptor);
464        data.writeStrongBinder(token);
465        data.writeInt(finished ? 1 : 0);
466        data.writeInt(userLeaving ? 1 :0);
467        data.writeInt(configChanges);
468        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
469                IBinder.FLAG_ONEWAY);
470        data.recycle();
471    }
472
473    public final void scheduleStopActivity(IBinder token, boolean showWindow,
474            int configChanges) throws RemoteException {
475        Parcel data = Parcel.obtain();
476        data.writeInterfaceToken(IApplicationThread.descriptor);
477        data.writeStrongBinder(token);
478        data.writeInt(showWindow ? 1 : 0);
479        data.writeInt(configChanges);
480        mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
481                IBinder.FLAG_ONEWAY);
482        data.recycle();
483    }
484
485    public final void scheduleWindowVisibility(IBinder token,
486            boolean showWindow) throws RemoteException {
487        Parcel data = Parcel.obtain();
488        data.writeInterfaceToken(IApplicationThread.descriptor);
489        data.writeStrongBinder(token);
490        data.writeInt(showWindow ? 1 : 0);
491        mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
492                IBinder.FLAG_ONEWAY);
493        data.recycle();
494    }
495
496    public final void scheduleResumeActivity(IBinder token, boolean isForward)
497            throws RemoteException {
498        Parcel data = Parcel.obtain();
499        data.writeInterfaceToken(IApplicationThread.descriptor);
500        data.writeStrongBinder(token);
501        data.writeInt(isForward ? 1 : 0);
502        mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
503                IBinder.FLAG_ONEWAY);
504        data.recycle();
505    }
506
507    public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
508    		throws RemoteException {
509        Parcel data = Parcel.obtain();
510        data.writeInterfaceToken(IApplicationThread.descriptor);
511        data.writeStrongBinder(token);
512        data.writeTypedList(results);
513        mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
514                IBinder.FLAG_ONEWAY);
515        data.recycle();
516    }
517
518    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
519            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
520    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
521    		throws RemoteException {
522        Parcel data = Parcel.obtain();
523        data.writeInterfaceToken(IApplicationThread.descriptor);
524        intent.writeToParcel(data, 0);
525        data.writeStrongBinder(token);
526        data.writeInt(ident);
527        info.writeToParcel(data, 0);
528        data.writeBundle(state);
529        data.writeTypedList(pendingResults);
530        data.writeTypedList(pendingNewIntents);
531        data.writeInt(notResumed ? 1 : 0);
532        data.writeInt(isForward ? 1 : 0);
533        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
534                IBinder.FLAG_ONEWAY);
535        data.recycle();
536    }
537
538    public final void scheduleRelaunchActivity(IBinder token,
539            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
540            int configChanges, boolean notResumed, Configuration config)
541            throws RemoteException {
542        Parcel data = Parcel.obtain();
543        data.writeInterfaceToken(IApplicationThread.descriptor);
544        data.writeStrongBinder(token);
545        data.writeTypedList(pendingResults);
546        data.writeTypedList(pendingNewIntents);
547        data.writeInt(configChanges);
548        data.writeInt(notResumed ? 1 : 0);
549        if (config != null) {
550            data.writeInt(1);
551            config.writeToParcel(data, 0);
552        } else {
553            data.writeInt(0);
554        }
555        mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
556                IBinder.FLAG_ONEWAY);
557        data.recycle();
558    }
559
560    public void scheduleNewIntent(List<Intent> intents, IBinder token)
561            throws RemoteException {
562        Parcel data = Parcel.obtain();
563        data.writeInterfaceToken(IApplicationThread.descriptor);
564        data.writeTypedList(intents);
565        data.writeStrongBinder(token);
566        mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
567                IBinder.FLAG_ONEWAY);
568        data.recycle();
569    }
570
571    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
572            int configChanges) throws RemoteException {
573        Parcel data = Parcel.obtain();
574        data.writeInterfaceToken(IApplicationThread.descriptor);
575        data.writeStrongBinder(token);
576        data.writeInt(finishing ? 1 : 0);
577        data.writeInt(configChanges);
578        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
579                IBinder.FLAG_ONEWAY);
580        data.recycle();
581    }
582
583    public final void scheduleReceiver(Intent intent, ActivityInfo info,
584            int resultCode, String resultData,
585            Bundle map, boolean sync) throws RemoteException {
586        Parcel data = Parcel.obtain();
587        data.writeInterfaceToken(IApplicationThread.descriptor);
588        intent.writeToParcel(data, 0);
589        info.writeToParcel(data, 0);
590        data.writeInt(resultCode);
591        data.writeString(resultData);
592        data.writeBundle(map);
593        data.writeInt(sync ? 1 : 0);
594        mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
595                IBinder.FLAG_ONEWAY);
596        data.recycle();
597    }
598
599    public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode)
600            throws RemoteException {
601        Parcel data = Parcel.obtain();
602        data.writeInterfaceToken(IApplicationThread.descriptor);
603        app.writeToParcel(data, 0);
604        data.writeInt(backupMode);
605        mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null,
606                IBinder.FLAG_ONEWAY);
607        data.recycle();
608    }
609
610    public final void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException {
611        Parcel data = Parcel.obtain();
612        data.writeInterfaceToken(IApplicationThread.descriptor);
613        app.writeToParcel(data, 0);
614        mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null,
615                IBinder.FLAG_ONEWAY);
616        data.recycle();
617    }
618
619    public final void scheduleCreateService(IBinder token, ServiceInfo info)
620            throws RemoteException {
621        Parcel data = Parcel.obtain();
622        data.writeInterfaceToken(IApplicationThread.descriptor);
623        data.writeStrongBinder(token);
624        info.writeToParcel(data, 0);
625        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
626                IBinder.FLAG_ONEWAY);
627        data.recycle();
628    }
629
630    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
631            throws RemoteException {
632        Parcel data = Parcel.obtain();
633        data.writeInterfaceToken(IApplicationThread.descriptor);
634        data.writeStrongBinder(token);
635        intent.writeToParcel(data, 0);
636        data.writeInt(rebind ? 1 : 0);
637        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
638                IBinder.FLAG_ONEWAY);
639        data.recycle();
640    }
641
642    public final void scheduleUnbindService(IBinder token, Intent intent)
643            throws RemoteException {
644        Parcel data = Parcel.obtain();
645        data.writeInterfaceToken(IApplicationThread.descriptor);
646        data.writeStrongBinder(token);
647        intent.writeToParcel(data, 0);
648        mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
649                IBinder.FLAG_ONEWAY);
650        data.recycle();
651    }
652
653    public final void scheduleServiceArgs(IBinder token, int startId,
654	    int flags, Intent args) throws RemoteException {
655        Parcel data = Parcel.obtain();
656        data.writeInterfaceToken(IApplicationThread.descriptor);
657        data.writeStrongBinder(token);
658        data.writeInt(startId);
659        data.writeInt(flags);
660        if (args != null) {
661            data.writeInt(1);
662            args.writeToParcel(data, 0);
663        } else {
664            data.writeInt(0);
665        }
666        mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
667                IBinder.FLAG_ONEWAY);
668        data.recycle();
669    }
670
671    public final void scheduleStopService(IBinder token)
672            throws RemoteException {
673        Parcel data = Parcel.obtain();
674        data.writeInterfaceToken(IApplicationThread.descriptor);
675        data.writeStrongBinder(token);
676        mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
677                IBinder.FLAG_ONEWAY);
678        data.recycle();
679    }
680
681    public final void bindApplication(String packageName, ApplicationInfo info,
682            List<ProviderInfo> providers, ComponentName testName,
683            String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode,
684            boolean restrictedBackupMode, Configuration config,
685            Map<String, IBinder> services) throws RemoteException {
686        Parcel data = Parcel.obtain();
687        data.writeInterfaceToken(IApplicationThread.descriptor);
688        data.writeString(packageName);
689        info.writeToParcel(data, 0);
690        data.writeTypedList(providers);
691        if (testName == null) {
692            data.writeInt(0);
693        } else {
694            data.writeInt(1);
695            testName.writeToParcel(data, 0);
696        }
697        data.writeString(profileName);
698        data.writeBundle(testArgs);
699        data.writeStrongInterface(testWatcher);
700        data.writeInt(debugMode);
701        data.writeInt(restrictedBackupMode ? 1 : 0);
702        config.writeToParcel(data, 0);
703        data.writeMap(services);
704        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
705                IBinder.FLAG_ONEWAY);
706        data.recycle();
707    }
708
709    public final void scheduleExit() throws RemoteException {
710        Parcel data = Parcel.obtain();
711        data.writeInterfaceToken(IApplicationThread.descriptor);
712        mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
713                IBinder.FLAG_ONEWAY);
714        data.recycle();
715    }
716
717    public final void scheduleSuicide() throws RemoteException {
718        Parcel data = Parcel.obtain();
719        data.writeInterfaceToken(IApplicationThread.descriptor);
720        mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
721                IBinder.FLAG_ONEWAY);
722        data.recycle();
723    }
724
725    public final void requestThumbnail(IBinder token)
726            throws RemoteException {
727        Parcel data = Parcel.obtain();
728        data.writeInterfaceToken(IApplicationThread.descriptor);
729        data.writeStrongBinder(token);
730        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
731                IBinder.FLAG_ONEWAY);
732        data.recycle();
733    }
734
735    public final void scheduleConfigurationChanged(Configuration config)
736            throws RemoteException {
737        Parcel data = Parcel.obtain();
738        data.writeInterfaceToken(IApplicationThread.descriptor);
739        config.writeToParcel(data, 0);
740        mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
741                IBinder.FLAG_ONEWAY);
742        data.recycle();
743    }
744
745    public void updateTimeZone() throws RemoteException {
746        Parcel data = Parcel.obtain();
747        data.writeInterfaceToken(IApplicationThread.descriptor);
748        mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
749                IBinder.FLAG_ONEWAY);
750        data.recycle();
751    }
752
753    public void clearDnsCache() throws RemoteException {
754        Parcel data = Parcel.obtain();
755        data.writeInterfaceToken(IApplicationThread.descriptor);
756        mRemote.transact(CLEAR_DNS_CACHE_TRANSACTION, data, null,
757                IBinder.FLAG_ONEWAY);
758        data.recycle();
759    }
760
761    public void processInBackground() throws RemoteException {
762        Parcel data = Parcel.obtain();
763        data.writeInterfaceToken(IApplicationThread.descriptor);
764        mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
765                IBinder.FLAG_ONEWAY);
766        data.recycle();
767    }
768
769    public void dumpService(FileDescriptor fd, IBinder token, String[] args)
770            throws RemoteException {
771        Parcel data = Parcel.obtain();
772        data.writeInterfaceToken(IApplicationThread.descriptor);
773        data.writeFileDescriptor(fd);
774        data.writeStrongBinder(token);
775        data.writeStringArray(args);
776        mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0);
777        data.recycle();
778    }
779
780    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
781            int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
782            throws RemoteException {
783        Parcel data = Parcel.obtain();
784        data.writeInterfaceToken(IApplicationThread.descriptor);
785        data.writeStrongBinder(receiver.asBinder());
786        intent.writeToParcel(data, 0);
787        data.writeInt(resultCode);
788        data.writeString(dataStr);
789        data.writeBundle(extras);
790        data.writeInt(ordered ? 1 : 0);
791        data.writeInt(sticky ? 1 : 0);
792        mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
793                IBinder.FLAG_ONEWAY);
794        data.recycle();
795    }
796
797    public final void scheduleLowMemory() throws RemoteException {
798        Parcel data = Parcel.obtain();
799        data.writeInterfaceToken(IApplicationThread.descriptor);
800        mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
801                IBinder.FLAG_ONEWAY);
802        data.recycle();
803    }
804
805    public final void scheduleActivityConfigurationChanged(
806            IBinder token) throws RemoteException {
807        Parcel data = Parcel.obtain();
808        data.writeInterfaceToken(IApplicationThread.descriptor);
809        data.writeStrongBinder(token);
810        mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
811                IBinder.FLAG_ONEWAY);
812        data.recycle();
813    }
814
815    public void profilerControl(boolean start, String path,
816            ParcelFileDescriptor fd) throws RemoteException {
817        Parcel data = Parcel.obtain();
818        data.writeInterfaceToken(IApplicationThread.descriptor);
819        data.writeInt(start ? 1 : 0);
820        data.writeString(path);
821        if (fd != null) {
822            data.writeInt(1);
823            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
824        } else {
825            data.writeInt(0);
826        }
827        mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
828                IBinder.FLAG_ONEWAY);
829        data.recycle();
830    }
831
832    public void setSchedulingGroup(int group) throws RemoteException {
833        Parcel data = Parcel.obtain();
834        data.writeInterfaceToken(IApplicationThread.descriptor);
835        data.writeInt(group);
836        mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
837                IBinder.FLAG_ONEWAY);
838        data.recycle();
839    }
840
841    public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
842        Parcel data = Parcel.obtain();
843        Parcel reply = Parcel.obtain();
844        data.writeInterfaceToken(IApplicationThread.descriptor);
845        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
846        reply.readException();
847        outInfo.readFromParcel(reply);
848        data.recycle();
849        reply.recycle();
850    }
851
852    public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
853        Parcel data = Parcel.obtain();
854        data.writeInterfaceToken(IApplicationThread.descriptor);
855        data.writeInt(cmd);
856        data.writeStringArray(packages);
857        mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
858                IBinder.FLAG_ONEWAY);
859        data.recycle();
860
861    }
862
863    public void scheduleCrash(String msg) throws RemoteException {
864        Parcel data = Parcel.obtain();
865        data.writeInterfaceToken(IApplicationThread.descriptor);
866        data.writeString(msg);
867        mRemote.transact(SCHEDULE_CRASH_TRANSACTION, data, null,
868                IBinder.FLAG_ONEWAY);
869        data.recycle();
870
871    }
872
873    public void dumpHeap(boolean managed, String path,
874            ParcelFileDescriptor fd) throws RemoteException {
875        Parcel data = Parcel.obtain();
876        data.writeInterfaceToken(IApplicationThread.descriptor);
877        data.writeInt(managed ? 1 : 0);
878        data.writeString(path);
879        if (fd != null) {
880            data.writeInt(1);
881            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
882        } else {
883            data.writeInt(0);
884        }
885        mRemote.transact(DUMP_HEAP_TRANSACTION, data, null,
886                IBinder.FLAG_ONEWAY);
887        data.recycle();
888    }
889
890    public void dumpActivity(FileDescriptor fd, IBinder token, String[] args)
891            throws RemoteException {
892        Parcel data = Parcel.obtain();
893        data.writeInterfaceToken(IApplicationThread.descriptor);
894        data.writeFileDescriptor(fd);
895        data.writeStrongBinder(token);
896        data.writeStringArray(args);
897        mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, 0);
898        data.recycle();
899    }
900}
901