ApplicationThreadNative.java revision 3025ef332c29e255388f74b2afefe05f64bce07c
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            scheduleRelaunchActivity(b, ri, pi, configChanges, notResumed);
144            return true;
145        }
146
147        case SCHEDULE_NEW_INTENT_TRANSACTION:
148        {
149            data.enforceInterface(IApplicationThread.descriptor);
150            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
151            IBinder b = data.readStrongBinder();
152            scheduleNewIntent(pi, b);
153            return true;
154        }
155
156        case SCHEDULE_FINISH_ACTIVITY_TRANSACTION:
157        {
158            data.enforceInterface(IApplicationThread.descriptor);
159            IBinder b = data.readStrongBinder();
160            boolean finishing = data.readInt() != 0;
161            int configChanges = data.readInt();
162            scheduleDestroyActivity(b, finishing, configChanges);
163            return true;
164        }
165
166        case SCHEDULE_RECEIVER_TRANSACTION:
167        {
168            data.enforceInterface(IApplicationThread.descriptor);
169            Intent intent = Intent.CREATOR.createFromParcel(data);
170            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
171            int resultCode = data.readInt();
172            String resultData = data.readString();
173            Bundle resultExtras = data.readBundle();
174            boolean sync = data.readInt() != 0;
175            scheduleReceiver(intent, info, resultCode, resultData,
176                    resultExtras, sync);
177            return true;
178        }
179
180        case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
181            data.enforceInterface(IApplicationThread.descriptor);
182            IBinder token = data.readStrongBinder();
183            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
184            scheduleCreateService(token, info);
185            return true;
186        }
187
188        case SCHEDULE_BIND_SERVICE_TRANSACTION: {
189            data.enforceInterface(IApplicationThread.descriptor);
190            IBinder token = data.readStrongBinder();
191            Intent intent = Intent.CREATOR.createFromParcel(data);
192            boolean rebind = data.readInt() != 0;
193            scheduleBindService(token, intent, rebind);
194            return true;
195        }
196
197        case SCHEDULE_UNBIND_SERVICE_TRANSACTION: {
198            data.enforceInterface(IApplicationThread.descriptor);
199            IBinder token = data.readStrongBinder();
200            Intent intent = Intent.CREATOR.createFromParcel(data);
201            scheduleUnbindService(token, intent);
202            return true;
203        }
204
205        case SCHEDULE_SERVICE_ARGS_TRANSACTION:
206        {
207            data.enforceInterface(IApplicationThread.descriptor);
208            IBinder token = data.readStrongBinder();
209            int startId = data.readInt();
210            int fl = data.readInt();
211            Intent args;
212            if (data.readInt() != 0) {
213                args = Intent.CREATOR.createFromParcel(data);
214            } else {
215                args = null;
216            }
217            scheduleServiceArgs(token, startId, fl, args);
218            return true;
219        }
220
221        case SCHEDULE_STOP_SERVICE_TRANSACTION:
222        {
223            data.enforceInterface(IApplicationThread.descriptor);
224            IBinder token = data.readStrongBinder();
225            scheduleStopService(token);
226            return true;
227        }
228
229        case BIND_APPLICATION_TRANSACTION:
230        {
231            data.enforceInterface(IApplicationThread.descriptor);
232            String packageName = data.readString();
233            ApplicationInfo info =
234                ApplicationInfo.CREATOR.createFromParcel(data);
235            List<ProviderInfo> providers =
236                data.createTypedArrayList(ProviderInfo.CREATOR);
237            ComponentName testName = (data.readInt() != 0)
238                ? new ComponentName(data) : null;
239            String profileName = data.readString();
240            Bundle testArgs = data.readBundle();
241            IBinder binder = data.readStrongBinder();
242            IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
243            int testMode = data.readInt();
244            boolean restrictedBackupMode = (data.readInt() != 0);
245            Configuration config = Configuration.CREATOR.createFromParcel(data);
246            HashMap<String, IBinder> services = data.readHashMap(null);
247            bindApplication(packageName, info,
248                            providers, testName, profileName,
249                            testArgs, testWatcher, testMode, restrictedBackupMode,
250                            config, services);
251            return true;
252        }
253
254        case SCHEDULE_EXIT_TRANSACTION:
255        {
256            data.enforceInterface(IApplicationThread.descriptor);
257            scheduleExit();
258            return true;
259        }
260
261        case REQUEST_THUMBNAIL_TRANSACTION:
262        {
263            data.enforceInterface(IApplicationThread.descriptor);
264            IBinder b = data.readStrongBinder();
265            requestThumbnail(b);
266            return true;
267        }
268
269        case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
270        {
271            data.enforceInterface(IApplicationThread.descriptor);
272            Configuration config = Configuration.CREATOR.createFromParcel(data);
273            scheduleConfigurationChanged(config);
274            return true;
275        }
276
277        case UPDATE_TIME_ZONE_TRANSACTION: {
278            data.enforceInterface(IApplicationThread.descriptor);
279            updateTimeZone();
280            return true;
281        }
282
283        case PROCESS_IN_BACKGROUND_TRANSACTION: {
284            data.enforceInterface(IApplicationThread.descriptor);
285            processInBackground();
286            return true;
287        }
288
289        case DUMP_SERVICE_TRANSACTION: {
290            data.enforceInterface(IApplicationThread.descriptor);
291            ParcelFileDescriptor fd = data.readFileDescriptor();
292            final IBinder service = data.readStrongBinder();
293            final String[] args = data.readStringArray();
294            if (fd != null) {
295                dumpService(fd.getFileDescriptor(), service, args);
296                try {
297                    fd.close();
298                } catch (IOException e) {
299                }
300            }
301            return true;
302        }
303
304        case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
305            data.enforceInterface(IApplicationThread.descriptor);
306            IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
307                    data.readStrongBinder());
308            Intent intent = Intent.CREATOR.createFromParcel(data);
309            int resultCode = data.readInt();
310            String dataStr = data.readString();
311            Bundle extras = data.readBundle();
312            boolean ordered = data.readInt() != 0;
313            scheduleRegisteredReceiver(receiver, intent,
314                    resultCode, dataStr, extras, ordered);
315            return true;
316        }
317
318        case SCHEDULE_LOW_MEMORY_TRANSACTION:
319        {
320            scheduleLowMemory();
321            return true;
322        }
323
324        case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
325        {
326            data.enforceInterface(IApplicationThread.descriptor);
327            IBinder b = data.readStrongBinder();
328            scheduleActivityConfigurationChanged(b);
329            return true;
330        }
331
332        case REQUEST_PSS_TRANSACTION:
333        {
334            data.enforceInterface(IApplicationThread.descriptor);
335            requestPss();
336            return true;
337        }
338
339        case PROFILER_CONTROL_TRANSACTION:
340        {
341            data.enforceInterface(IApplicationThread.descriptor);
342            boolean start = data.readInt() != 0;
343            String path = data.readString();
344            ParcelFileDescriptor fd = data.readInt() != 0
345                    ? data.readFileDescriptor() : null;
346            profilerControl(start, path, fd);
347            return true;
348        }
349
350        case SET_SCHEDULING_GROUP_TRANSACTION:
351        {
352            data.enforceInterface(IApplicationThread.descriptor);
353            int group = data.readInt();
354            setSchedulingGroup(group);
355            return true;
356        }
357
358        case SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION:
359        {
360            data.enforceInterface(IApplicationThread.descriptor);
361            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
362            int backupMode = data.readInt();
363            scheduleCreateBackupAgent(appInfo, backupMode);
364            return true;
365        }
366
367        case SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION:
368        {
369            data.enforceInterface(IApplicationThread.descriptor);
370            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
371            scheduleDestroyBackupAgent(appInfo);
372            return true;
373        }
374
375        case GET_MEMORY_INFO_TRANSACTION:
376        {
377            data.enforceInterface(IApplicationThread.descriptor);
378            Debug.MemoryInfo mi = new Debug.MemoryInfo();
379            getMemoryInfo(mi);
380            reply.writeNoException();
381            mi.writeToParcel(reply, 0);
382            return true;
383        }
384        }
385
386        return super.onTransact(code, data, reply, flags);
387    }
388
389    public IBinder asBinder()
390    {
391        return this;
392    }
393}
394
395class ApplicationThreadProxy implements IApplicationThread {
396    private final IBinder mRemote;
397
398    public ApplicationThreadProxy(IBinder remote) {
399        mRemote = remote;
400    }
401
402    public final IBinder asBinder() {
403        return mRemote;
404    }
405
406    public final void schedulePauseActivity(IBinder token, boolean finished,
407            boolean userLeaving, int configChanges) throws RemoteException {
408        Parcel data = Parcel.obtain();
409        data.writeInterfaceToken(IApplicationThread.descriptor);
410        data.writeStrongBinder(token);
411        data.writeInt(finished ? 1 : 0);
412        data.writeInt(userLeaving ? 1 :0);
413        data.writeInt(configChanges);
414        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
415                IBinder.FLAG_ONEWAY);
416        data.recycle();
417    }
418
419    public final void scheduleStopActivity(IBinder token, boolean showWindow,
420            int configChanges) throws RemoteException {
421        Parcel data = Parcel.obtain();
422        data.writeInterfaceToken(IApplicationThread.descriptor);
423        data.writeStrongBinder(token);
424        data.writeInt(showWindow ? 1 : 0);
425        data.writeInt(configChanges);
426        mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
427                IBinder.FLAG_ONEWAY);
428        data.recycle();
429    }
430
431    public final void scheduleWindowVisibility(IBinder token,
432            boolean showWindow) throws RemoteException {
433        Parcel data = Parcel.obtain();
434        data.writeInterfaceToken(IApplicationThread.descriptor);
435        data.writeStrongBinder(token);
436        data.writeInt(showWindow ? 1 : 0);
437        mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
438                IBinder.FLAG_ONEWAY);
439        data.recycle();
440    }
441
442    public final void scheduleResumeActivity(IBinder token, boolean isForward)
443            throws RemoteException {
444        Parcel data = Parcel.obtain();
445        data.writeInterfaceToken(IApplicationThread.descriptor);
446        data.writeStrongBinder(token);
447        data.writeInt(isForward ? 1 : 0);
448        mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
449                IBinder.FLAG_ONEWAY);
450        data.recycle();
451    }
452
453    public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
454    		throws RemoteException {
455        Parcel data = Parcel.obtain();
456        data.writeInterfaceToken(IApplicationThread.descriptor);
457        data.writeStrongBinder(token);
458        data.writeTypedList(results);
459        mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
460                IBinder.FLAG_ONEWAY);
461        data.recycle();
462    }
463
464    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
465            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
466    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
467    		throws RemoteException {
468        Parcel data = Parcel.obtain();
469        data.writeInterfaceToken(IApplicationThread.descriptor);
470        intent.writeToParcel(data, 0);
471        data.writeStrongBinder(token);
472        data.writeInt(ident);
473        info.writeToParcel(data, 0);
474        data.writeBundle(state);
475        data.writeTypedList(pendingResults);
476        data.writeTypedList(pendingNewIntents);
477        data.writeInt(notResumed ? 1 : 0);
478        data.writeInt(isForward ? 1 : 0);
479        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
480                IBinder.FLAG_ONEWAY);
481        data.recycle();
482    }
483
484    public final void scheduleRelaunchActivity(IBinder token,
485            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
486            int configChanges, boolean notResumed) throws RemoteException {
487        Parcel data = Parcel.obtain();
488        data.writeInterfaceToken(IApplicationThread.descriptor);
489        data.writeStrongBinder(token);
490        data.writeTypedList(pendingResults);
491        data.writeTypedList(pendingNewIntents);
492        data.writeInt(configChanges);
493        data.writeInt(notResumed ? 1 : 0);
494        mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
495                IBinder.FLAG_ONEWAY);
496        data.recycle();
497    }
498
499    public void scheduleNewIntent(List<Intent> intents, IBinder token)
500            throws RemoteException {
501        Parcel data = Parcel.obtain();
502        data.writeInterfaceToken(IApplicationThread.descriptor);
503        data.writeTypedList(intents);
504        data.writeStrongBinder(token);
505        mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
506                IBinder.FLAG_ONEWAY);
507        data.recycle();
508    }
509
510    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
511            int configChanges) throws RemoteException {
512        Parcel data = Parcel.obtain();
513        data.writeInterfaceToken(IApplicationThread.descriptor);
514        data.writeStrongBinder(token);
515        data.writeInt(finishing ? 1 : 0);
516        data.writeInt(configChanges);
517        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
518                IBinder.FLAG_ONEWAY);
519        data.recycle();
520    }
521
522    public final void scheduleReceiver(Intent intent, ActivityInfo info,
523            int resultCode, String resultData,
524            Bundle map, boolean sync) throws RemoteException {
525        Parcel data = Parcel.obtain();
526        data.writeInterfaceToken(IApplicationThread.descriptor);
527        intent.writeToParcel(data, 0);
528        info.writeToParcel(data, 0);
529        data.writeInt(resultCode);
530        data.writeString(resultData);
531        data.writeBundle(map);
532        data.writeInt(sync ? 1 : 0);
533        mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
534                IBinder.FLAG_ONEWAY);
535        data.recycle();
536    }
537
538    public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode)
539            throws RemoteException {
540        Parcel data = Parcel.obtain();
541        data.writeInterfaceToken(IApplicationThread.descriptor);
542        app.writeToParcel(data, 0);
543        data.writeInt(backupMode);
544        mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null,
545                IBinder.FLAG_ONEWAY);
546        data.recycle();
547    }
548
549    public final void scheduleDestroyBackupAgent(ApplicationInfo app) throws RemoteException {
550        Parcel data = Parcel.obtain();
551        data.writeInterfaceToken(IApplicationThread.descriptor);
552        app.writeToParcel(data, 0);
553        mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null,
554                IBinder.FLAG_ONEWAY);
555        data.recycle();
556    }
557
558    public final void scheduleCreateService(IBinder token, ServiceInfo info)
559            throws RemoteException {
560        Parcel data = Parcel.obtain();
561        data.writeInterfaceToken(IApplicationThread.descriptor);
562        data.writeStrongBinder(token);
563        info.writeToParcel(data, 0);
564        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
565                IBinder.FLAG_ONEWAY);
566        data.recycle();
567    }
568
569    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
570            throws RemoteException {
571        Parcel data = Parcel.obtain();
572        data.writeInterfaceToken(IApplicationThread.descriptor);
573        data.writeStrongBinder(token);
574        intent.writeToParcel(data, 0);
575        data.writeInt(rebind ? 1 : 0);
576        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
577                IBinder.FLAG_ONEWAY);
578        data.recycle();
579    }
580
581    public final void scheduleUnbindService(IBinder token, Intent intent)
582            throws RemoteException {
583        Parcel data = Parcel.obtain();
584        data.writeInterfaceToken(IApplicationThread.descriptor);
585        data.writeStrongBinder(token);
586        intent.writeToParcel(data, 0);
587        mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
588                IBinder.FLAG_ONEWAY);
589        data.recycle();
590    }
591
592    public final void scheduleServiceArgs(IBinder token, int startId,
593	    int flags, Intent args) throws RemoteException {
594        Parcel data = Parcel.obtain();
595        data.writeInterfaceToken(IApplicationThread.descriptor);
596        data.writeStrongBinder(token);
597        data.writeInt(startId);
598        data.writeInt(flags);
599        if (args != null) {
600            data.writeInt(1);
601            args.writeToParcel(data, 0);
602        } else {
603            data.writeInt(0);
604        }
605        mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
606                IBinder.FLAG_ONEWAY);
607        data.recycle();
608    }
609
610    public final void scheduleStopService(IBinder token)
611            throws RemoteException {
612        Parcel data = Parcel.obtain();
613        data.writeInterfaceToken(IApplicationThread.descriptor);
614        data.writeStrongBinder(token);
615        mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
616                IBinder.FLAG_ONEWAY);
617        data.recycle();
618    }
619
620    public final void bindApplication(String packageName, ApplicationInfo info,
621            List<ProviderInfo> providers, ComponentName testName,
622            String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode,
623            boolean restrictedBackupMode, Configuration config,
624            Map<String, IBinder> services) throws RemoteException {
625        Parcel data = Parcel.obtain();
626        data.writeInterfaceToken(IApplicationThread.descriptor);
627        data.writeString(packageName);
628        info.writeToParcel(data, 0);
629        data.writeTypedList(providers);
630        if (testName == null) {
631            data.writeInt(0);
632        } else {
633            data.writeInt(1);
634            testName.writeToParcel(data, 0);
635        }
636        data.writeString(profileName);
637        data.writeBundle(testArgs);
638        data.writeStrongInterface(testWatcher);
639        data.writeInt(debugMode);
640        data.writeInt(restrictedBackupMode ? 1 : 0);
641        config.writeToParcel(data, 0);
642        data.writeMap(services);
643        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
644                IBinder.FLAG_ONEWAY);
645        data.recycle();
646    }
647
648    public final void scheduleExit() throws RemoteException {
649        Parcel data = Parcel.obtain();
650        data.writeInterfaceToken(IApplicationThread.descriptor);
651        mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
652                IBinder.FLAG_ONEWAY);
653        data.recycle();
654    }
655
656    public final void requestThumbnail(IBinder token)
657            throws RemoteException {
658        Parcel data = Parcel.obtain();
659        data.writeInterfaceToken(IApplicationThread.descriptor);
660        data.writeStrongBinder(token);
661        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
662                IBinder.FLAG_ONEWAY);
663        data.recycle();
664    }
665
666    public final void scheduleConfigurationChanged(Configuration config)
667            throws RemoteException {
668        Parcel data = Parcel.obtain();
669        data.writeInterfaceToken(IApplicationThread.descriptor);
670        config.writeToParcel(data, 0);
671        mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
672                IBinder.FLAG_ONEWAY);
673        data.recycle();
674    }
675
676    public void updateTimeZone() throws RemoteException {
677        Parcel data = Parcel.obtain();
678        data.writeInterfaceToken(IApplicationThread.descriptor);
679        mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
680                IBinder.FLAG_ONEWAY);
681        data.recycle();
682    }
683
684    public void processInBackground() throws RemoteException {
685        Parcel data = Parcel.obtain();
686        data.writeInterfaceToken(IApplicationThread.descriptor);
687        mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
688                IBinder.FLAG_ONEWAY);
689        data.recycle();
690    }
691
692    public void dumpService(FileDescriptor fd, IBinder token, String[] args)
693            throws RemoteException {
694        Parcel data = Parcel.obtain();
695        data.writeInterfaceToken(IApplicationThread.descriptor);
696        data.writeFileDescriptor(fd);
697        data.writeStrongBinder(token);
698        data.writeStringArray(args);
699        mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0);
700        data.recycle();
701    }
702
703    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
704            int resultCode, String dataStr, Bundle extras, boolean ordered)
705            throws RemoteException {
706        Parcel data = Parcel.obtain();
707        data.writeInterfaceToken(IApplicationThread.descriptor);
708        data.writeStrongBinder(receiver.asBinder());
709        intent.writeToParcel(data, 0);
710        data.writeInt(resultCode);
711        data.writeString(dataStr);
712        data.writeBundle(extras);
713        data.writeInt(ordered ? 1 : 0);
714        mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
715                IBinder.FLAG_ONEWAY);
716        data.recycle();
717    }
718
719    public final void scheduleLowMemory() throws RemoteException {
720        Parcel data = Parcel.obtain();
721        data.writeInterfaceToken(IApplicationThread.descriptor);
722        mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
723                IBinder.FLAG_ONEWAY);
724        data.recycle();
725    }
726
727    public final void scheduleActivityConfigurationChanged(
728            IBinder token) throws RemoteException {
729        Parcel data = Parcel.obtain();
730        data.writeInterfaceToken(IApplicationThread.descriptor);
731        data.writeStrongBinder(token);
732        mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
733                IBinder.FLAG_ONEWAY);
734        data.recycle();
735    }
736
737    public final void requestPss() throws RemoteException {
738        Parcel data = Parcel.obtain();
739        data.writeInterfaceToken(IApplicationThread.descriptor);
740        mRemote.transact(REQUEST_PSS_TRANSACTION, data, null,
741                IBinder.FLAG_ONEWAY);
742        data.recycle();
743    }
744
745    public void profilerControl(boolean start, String path,
746            ParcelFileDescriptor fd) throws RemoteException {
747        Parcel data = Parcel.obtain();
748        data.writeInterfaceToken(IApplicationThread.descriptor);
749        data.writeInt(start ? 1 : 0);
750        data.writeString(path);
751        if (fd != null) {
752            data.writeInt(1);
753            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
754        } else {
755            data.writeInt(0);
756        }
757        mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
758                IBinder.FLAG_ONEWAY);
759        data.recycle();
760    }
761
762    public void setSchedulingGroup(int group) throws RemoteException {
763        Parcel data = Parcel.obtain();
764        data.writeInterfaceToken(IApplicationThread.descriptor);
765        data.writeInt(group);
766        mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
767                IBinder.FLAG_ONEWAY);
768        data.recycle();
769    }
770
771    public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
772        Parcel data = Parcel.obtain();
773        Parcel reply = Parcel.obtain();
774        data.writeInterfaceToken(IApplicationThread.descriptor);
775        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
776        reply.readException();
777        outInfo.readFromParcel(reply);
778        data.recycle();
779        reply.recycle();
780    }
781}
782
783