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