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.CompatibilityInfo;
27import android.content.res.Configuration;
28import android.os.Binder;
29import android.os.Bundle;
30import android.os.Debug;
31import android.os.Parcelable;
32import android.os.RemoteException;
33import android.os.IBinder;
34import android.os.Parcel;
35import android.os.ParcelFileDescriptor;
36
37import java.io.FileDescriptor;
38import java.io.IOException;
39import java.util.HashMap;
40import java.util.List;
41import java.util.Map;
42
43/** {@hide} */
44public abstract class ApplicationThreadNative extends Binder
45        implements IApplicationThread {
46    /**
47     * Cast a Binder object into an application thread interface, generating
48     * a proxy if needed.
49     */
50    static public IApplicationThread asInterface(IBinder obj) {
51        if (obj == null) {
52            return null;
53        }
54        IApplicationThread in =
55            (IApplicationThread)obj.queryLocalInterface(descriptor);
56        if (in != null) {
57            return in;
58        }
59
60        return new ApplicationThreadProxy(obj);
61    }
62
63    public ApplicationThreadNative() {
64        attachInterface(this, descriptor);
65    }
66
67    @Override
68    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
69            throws RemoteException {
70        switch (code) {
71        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
72        {
73            data.enforceInterface(IApplicationThread.descriptor);
74            IBinder b = data.readStrongBinder();
75            boolean finished = data.readInt() != 0;
76            boolean userLeaving = data.readInt() != 0;
77            int configChanges = data.readInt();
78            schedulePauseActivity(b, finished, userLeaving, configChanges);
79            return true;
80        }
81
82        case SCHEDULE_STOP_ACTIVITY_TRANSACTION:
83        {
84            data.enforceInterface(IApplicationThread.descriptor);
85            IBinder b = data.readStrongBinder();
86            boolean show = data.readInt() != 0;
87            int configChanges = data.readInt();
88            scheduleStopActivity(b, show, configChanges);
89            return true;
90        }
91
92        case SCHEDULE_WINDOW_VISIBILITY_TRANSACTION:
93        {
94            data.enforceInterface(IApplicationThread.descriptor);
95            IBinder b = data.readStrongBinder();
96            boolean show = data.readInt() != 0;
97            scheduleWindowVisibility(b, show);
98            return true;
99        }
100
101        case SCHEDULE_SLEEPING_TRANSACTION:
102        {
103            data.enforceInterface(IApplicationThread.descriptor);
104            IBinder b = data.readStrongBinder();
105            boolean sleeping = data.readInt() != 0;
106            scheduleSleeping(b, sleeping);
107            return true;
108        }
109
110        case SCHEDULE_RESUME_ACTIVITY_TRANSACTION:
111        {
112            data.enforceInterface(IApplicationThread.descriptor);
113            IBinder b = data.readStrongBinder();
114            boolean isForward = data.readInt() != 0;
115            scheduleResumeActivity(b, isForward);
116            return true;
117        }
118
119        case SCHEDULE_SEND_RESULT_TRANSACTION:
120        {
121            data.enforceInterface(IApplicationThread.descriptor);
122            IBinder b = data.readStrongBinder();
123            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
124            scheduleSendResult(b, ri);
125            return true;
126        }
127
128        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
129        {
130            data.enforceInterface(IApplicationThread.descriptor);
131            Intent intent = Intent.CREATOR.createFromParcel(data);
132            IBinder b = data.readStrongBinder();
133            int ident = data.readInt();
134            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
135            Configuration curConfig = Configuration.CREATOR.createFromParcel(data);
136            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
137            Bundle state = data.readBundle();
138            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
139            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
140            boolean notResumed = data.readInt() != 0;
141            boolean isForward = data.readInt() != 0;
142            String profileName = data.readString();
143            ParcelFileDescriptor profileFd = data.readInt() != 0
144                    ? data.readFileDescriptor() : null;
145            boolean autoStopProfiler = data.readInt() != 0;
146            scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, state, ri, pi,
147                    notResumed, isForward, profileName, profileFd, autoStopProfiler);
148            return true;
149        }
150
151        case SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION:
152        {
153            data.enforceInterface(IApplicationThread.descriptor);
154            IBinder b = data.readStrongBinder();
155            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
156            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
157            int configChanges = data.readInt();
158            boolean notResumed = data.readInt() != 0;
159            Configuration config = null;
160            if (data.readInt() != 0) {
161                config = Configuration.CREATOR.createFromParcel(data);
162            }
163            scheduleRelaunchActivity(b, ri, pi, configChanges, notResumed, config);
164            return true;
165        }
166
167        case SCHEDULE_NEW_INTENT_TRANSACTION:
168        {
169            data.enforceInterface(IApplicationThread.descriptor);
170            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
171            IBinder b = data.readStrongBinder();
172            scheduleNewIntent(pi, b);
173            return true;
174        }
175
176        case SCHEDULE_FINISH_ACTIVITY_TRANSACTION:
177        {
178            data.enforceInterface(IApplicationThread.descriptor);
179            IBinder b = data.readStrongBinder();
180            boolean finishing = data.readInt() != 0;
181            int configChanges = data.readInt();
182            scheduleDestroyActivity(b, finishing, configChanges);
183            return true;
184        }
185
186        case SCHEDULE_RECEIVER_TRANSACTION:
187        {
188            data.enforceInterface(IApplicationThread.descriptor);
189            Intent intent = Intent.CREATOR.createFromParcel(data);
190            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
191            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
192            int resultCode = data.readInt();
193            String resultData = data.readString();
194            Bundle resultExtras = data.readBundle();
195            boolean sync = data.readInt() != 0;
196            scheduleReceiver(intent, info, compatInfo, resultCode, resultData,
197                    resultExtras, sync);
198            return true;
199        }
200
201        case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
202            data.enforceInterface(IApplicationThread.descriptor);
203            IBinder token = data.readStrongBinder();
204            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
205            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
206            scheduleCreateService(token, info, compatInfo);
207            return true;
208        }
209
210        case SCHEDULE_BIND_SERVICE_TRANSACTION: {
211            data.enforceInterface(IApplicationThread.descriptor);
212            IBinder token = data.readStrongBinder();
213            Intent intent = Intent.CREATOR.createFromParcel(data);
214            boolean rebind = data.readInt() != 0;
215            scheduleBindService(token, intent, rebind);
216            return true;
217        }
218
219        case SCHEDULE_UNBIND_SERVICE_TRANSACTION: {
220            data.enforceInterface(IApplicationThread.descriptor);
221            IBinder token = data.readStrongBinder();
222            Intent intent = Intent.CREATOR.createFromParcel(data);
223            scheduleUnbindService(token, intent);
224            return true;
225        }
226
227        case SCHEDULE_SERVICE_ARGS_TRANSACTION:
228        {
229            data.enforceInterface(IApplicationThread.descriptor);
230            IBinder token = data.readStrongBinder();
231            boolean taskRemoved = data.readInt() != 0;
232            int startId = data.readInt();
233            int fl = data.readInt();
234            Intent args;
235            if (data.readInt() != 0) {
236                args = Intent.CREATOR.createFromParcel(data);
237            } else {
238                args = null;
239            }
240            scheduleServiceArgs(token, taskRemoved, startId, fl, args);
241            return true;
242        }
243
244        case SCHEDULE_STOP_SERVICE_TRANSACTION:
245        {
246            data.enforceInterface(IApplicationThread.descriptor);
247            IBinder token = data.readStrongBinder();
248            scheduleStopService(token);
249            return true;
250        }
251
252        case BIND_APPLICATION_TRANSACTION:
253        {
254            data.enforceInterface(IApplicationThread.descriptor);
255            String packageName = data.readString();
256            ApplicationInfo info =
257                ApplicationInfo.CREATOR.createFromParcel(data);
258            List<ProviderInfo> providers =
259                data.createTypedArrayList(ProviderInfo.CREATOR);
260            ComponentName testName = (data.readInt() != 0)
261                ? new ComponentName(data) : null;
262            String profileName = data.readString();
263            ParcelFileDescriptor profileFd = data.readInt() != 0
264                    ? data.readFileDescriptor() : null;
265            boolean autoStopProfiler = data.readInt() != 0;
266            Bundle testArgs = data.readBundle();
267            IBinder binder = data.readStrongBinder();
268            IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
269            int testMode = data.readInt();
270            boolean restrictedBackupMode = (data.readInt() != 0);
271            boolean persistent = (data.readInt() != 0);
272            Configuration config = Configuration.CREATOR.createFromParcel(data);
273            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
274            HashMap<String, IBinder> services = data.readHashMap(null);
275            Bundle coreSettings = data.readBundle();
276            bindApplication(packageName, info,
277                            providers, testName, profileName, profileFd, autoStopProfiler,
278                            testArgs, testWatcher, testMode, restrictedBackupMode, persistent,
279                            config, compatInfo, services, coreSettings);
280            return true;
281        }
282
283        case SCHEDULE_EXIT_TRANSACTION:
284        {
285            data.enforceInterface(IApplicationThread.descriptor);
286            scheduleExit();
287            return true;
288        }
289
290        case SCHEDULE_SUICIDE_TRANSACTION:
291        {
292            data.enforceInterface(IApplicationThread.descriptor);
293            scheduleSuicide();
294            return true;
295        }
296
297        case REQUEST_THUMBNAIL_TRANSACTION:
298        {
299            data.enforceInterface(IApplicationThread.descriptor);
300            IBinder b = data.readStrongBinder();
301            requestThumbnail(b);
302            return true;
303        }
304
305        case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
306        {
307            data.enforceInterface(IApplicationThread.descriptor);
308            Configuration config = Configuration.CREATOR.createFromParcel(data);
309            scheduleConfigurationChanged(config);
310            return true;
311        }
312
313        case UPDATE_TIME_ZONE_TRANSACTION: {
314            data.enforceInterface(IApplicationThread.descriptor);
315            updateTimeZone();
316            return true;
317        }
318
319        case CLEAR_DNS_CACHE_TRANSACTION: {
320            data.enforceInterface(IApplicationThread.descriptor);
321            clearDnsCache();
322            return true;
323        }
324
325        case SET_HTTP_PROXY_TRANSACTION: {
326            data.enforceInterface(IApplicationThread.descriptor);
327            final String proxy = data.readString();
328            final String port = data.readString();
329            final String exclList = data.readString();
330            setHttpProxy(proxy, port, exclList);
331            return true;
332        }
333
334        case PROCESS_IN_BACKGROUND_TRANSACTION: {
335            data.enforceInterface(IApplicationThread.descriptor);
336            processInBackground();
337            return true;
338        }
339
340        case DUMP_SERVICE_TRANSACTION: {
341            data.enforceInterface(IApplicationThread.descriptor);
342            ParcelFileDescriptor fd = data.readFileDescriptor();
343            final IBinder service = data.readStrongBinder();
344            final String[] args = data.readStringArray();
345            if (fd != null) {
346                dumpService(fd.getFileDescriptor(), service, args);
347                try {
348                    fd.close();
349                } catch (IOException e) {
350                }
351            }
352            return true;
353        }
354
355        case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
356            data.enforceInterface(IApplicationThread.descriptor);
357            IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
358                    data.readStrongBinder());
359            Intent intent = Intent.CREATOR.createFromParcel(data);
360            int resultCode = data.readInt();
361            String dataStr = data.readString();
362            Bundle extras = data.readBundle();
363            boolean ordered = data.readInt() != 0;
364            boolean sticky = data.readInt() != 0;
365            scheduleRegisteredReceiver(receiver, intent,
366                    resultCode, dataStr, extras, ordered, sticky);
367            return true;
368        }
369
370        case SCHEDULE_LOW_MEMORY_TRANSACTION:
371        {
372            scheduleLowMemory();
373            return true;
374        }
375
376        case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
377        {
378            data.enforceInterface(IApplicationThread.descriptor);
379            IBinder b = data.readStrongBinder();
380            scheduleActivityConfigurationChanged(b);
381            return true;
382        }
383
384        case PROFILER_CONTROL_TRANSACTION:
385        {
386            data.enforceInterface(IApplicationThread.descriptor);
387            boolean start = data.readInt() != 0;
388            int profileType = data.readInt();
389            String path = data.readString();
390            ParcelFileDescriptor fd = data.readInt() != 0
391                    ? data.readFileDescriptor() : null;
392            profilerControl(start, path, fd, profileType);
393            return true;
394        }
395
396        case SET_SCHEDULING_GROUP_TRANSACTION:
397        {
398            data.enforceInterface(IApplicationThread.descriptor);
399            int group = data.readInt();
400            setSchedulingGroup(group);
401            return true;
402        }
403
404        case SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION:
405        {
406            data.enforceInterface(IApplicationThread.descriptor);
407            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
408            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
409            int backupMode = data.readInt();
410            scheduleCreateBackupAgent(appInfo, compatInfo, backupMode);
411            return true;
412        }
413
414        case SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION:
415        {
416            data.enforceInterface(IApplicationThread.descriptor);
417            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(data);
418            CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
419            scheduleDestroyBackupAgent(appInfo, compatInfo);
420            return true;
421        }
422
423        case GET_MEMORY_INFO_TRANSACTION:
424        {
425            data.enforceInterface(IApplicationThread.descriptor);
426            Debug.MemoryInfo mi = new Debug.MemoryInfo();
427            getMemoryInfo(mi);
428            reply.writeNoException();
429            mi.writeToParcel(reply, 0);
430            return true;
431        }
432
433        case DISPATCH_PACKAGE_BROADCAST_TRANSACTION:
434        {
435            data.enforceInterface(IApplicationThread.descriptor);
436            int cmd = data.readInt();
437            String[] packages = data.readStringArray();
438            dispatchPackageBroadcast(cmd, packages);
439            return true;
440        }
441
442        case SCHEDULE_CRASH_TRANSACTION:
443        {
444            data.enforceInterface(IApplicationThread.descriptor);
445            String msg = data.readString();
446            scheduleCrash(msg);
447            return true;
448        }
449
450        case DUMP_HEAP_TRANSACTION:
451        {
452            data.enforceInterface(IApplicationThread.descriptor);
453            boolean managed = data.readInt() != 0;
454            String path = data.readString();
455            ParcelFileDescriptor fd = data.readInt() != 0
456                    ? data.readFileDescriptor() : null;
457            dumpHeap(managed, path, fd);
458            return true;
459        }
460
461        case DUMP_ACTIVITY_TRANSACTION: {
462            data.enforceInterface(IApplicationThread.descriptor);
463            ParcelFileDescriptor fd = data.readFileDescriptor();
464            final IBinder activity = data.readStrongBinder();
465            final String prefix = data.readString();
466            final String[] args = data.readStringArray();
467            if (fd != null) {
468                dumpActivity(fd.getFileDescriptor(), activity, prefix, args);
469                try {
470                    fd.close();
471                } catch (IOException e) {
472                }
473            }
474            return true;
475        }
476
477        case SET_CORE_SETTINGS_TRANSACTION: {
478            data.enforceInterface(IApplicationThread.descriptor);
479            Bundle settings = data.readBundle();
480            setCoreSettings(settings);
481            return true;
482        }
483
484        case UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION: {
485            data.enforceInterface(IApplicationThread.descriptor);
486            String pkg = data.readString();
487            CompatibilityInfo compat = CompatibilityInfo.CREATOR.createFromParcel(data);
488            updatePackageCompatibilityInfo(pkg, compat);
489            return true;
490        }
491
492        case SCHEDULE_TRIM_MEMORY_TRANSACTION: {
493            data.enforceInterface(IApplicationThread.descriptor);
494            int level = data.readInt();
495            scheduleTrimMemory(level);
496            return true;
497        }
498
499        case DUMP_MEM_INFO_TRANSACTION:
500        {
501            data.enforceInterface(IApplicationThread.descriptor);
502            ParcelFileDescriptor fd = data.readFileDescriptor();
503            boolean checkin = data.readInt() != 0;
504            boolean all = data.readInt() != 0;
505            String[] args = data.readStringArray();
506            Debug.MemoryInfo mi = null;
507            if (fd != null) {
508                try {
509                    mi = dumpMemInfo(fd.getFileDescriptor(), checkin, all, args);
510                } finally {
511                    try {
512                        fd.close();
513                    } catch (IOException e) {
514                        // swallowed, not propagated back to the caller
515                    }
516                }
517            }
518            reply.writeNoException();
519            mi.writeToParcel(reply, 0);
520            return true;
521        }
522
523        case DUMP_GFX_INFO_TRANSACTION:
524        {
525            data.enforceInterface(IApplicationThread.descriptor);
526            ParcelFileDescriptor fd = data.readFileDescriptor();
527            String[] args = data.readStringArray();
528            if (fd != null) {
529                try {
530                    dumpGfxInfo(fd.getFileDescriptor(), args);
531                } finally {
532                    try {
533                        fd.close();
534                    } catch (IOException e) {
535                        // swallowed, not propagated back to the caller
536                    }
537                }
538            }
539            reply.writeNoException();
540            return true;
541        }
542        }
543
544        return super.onTransact(code, data, reply, flags);
545    }
546
547    public IBinder asBinder()
548    {
549        return this;
550    }
551}
552
553class ApplicationThreadProxy implements IApplicationThread {
554    private final IBinder mRemote;
555
556    public ApplicationThreadProxy(IBinder remote) {
557        mRemote = remote;
558    }
559
560    public final IBinder asBinder() {
561        return mRemote;
562    }
563
564    public final void schedulePauseActivity(IBinder token, boolean finished,
565            boolean userLeaving, int configChanges) throws RemoteException {
566        Parcel data = Parcel.obtain();
567        data.writeInterfaceToken(IApplicationThread.descriptor);
568        data.writeStrongBinder(token);
569        data.writeInt(finished ? 1 : 0);
570        data.writeInt(userLeaving ? 1 :0);
571        data.writeInt(configChanges);
572        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
573                IBinder.FLAG_ONEWAY);
574        data.recycle();
575    }
576
577    public final void scheduleStopActivity(IBinder token, boolean showWindow,
578            int configChanges) throws RemoteException {
579        Parcel data = Parcel.obtain();
580        data.writeInterfaceToken(IApplicationThread.descriptor);
581        data.writeStrongBinder(token);
582        data.writeInt(showWindow ? 1 : 0);
583        data.writeInt(configChanges);
584        mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
585                IBinder.FLAG_ONEWAY);
586        data.recycle();
587    }
588
589    public final void scheduleWindowVisibility(IBinder token,
590            boolean showWindow) throws RemoteException {
591        Parcel data = Parcel.obtain();
592        data.writeInterfaceToken(IApplicationThread.descriptor);
593        data.writeStrongBinder(token);
594        data.writeInt(showWindow ? 1 : 0);
595        mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
596                IBinder.FLAG_ONEWAY);
597        data.recycle();
598    }
599
600    public final void scheduleSleeping(IBinder token,
601            boolean sleeping) throws RemoteException {
602        Parcel data = Parcel.obtain();
603        data.writeInterfaceToken(IApplicationThread.descriptor);
604        data.writeStrongBinder(token);
605        data.writeInt(sleeping ? 1 : 0);
606        mRemote.transact(SCHEDULE_SLEEPING_TRANSACTION, data, null,
607                IBinder.FLAG_ONEWAY);
608        data.recycle();
609    }
610
611    public final void scheduleResumeActivity(IBinder token, boolean isForward)
612            throws RemoteException {
613        Parcel data = Parcel.obtain();
614        data.writeInterfaceToken(IApplicationThread.descriptor);
615        data.writeStrongBinder(token);
616        data.writeInt(isForward ? 1 : 0);
617        mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
618                IBinder.FLAG_ONEWAY);
619        data.recycle();
620    }
621
622    public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
623    		throws RemoteException {
624        Parcel data = Parcel.obtain();
625        data.writeInterfaceToken(IApplicationThread.descriptor);
626        data.writeStrongBinder(token);
627        data.writeTypedList(results);
628        mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
629                IBinder.FLAG_ONEWAY);
630        data.recycle();
631    }
632
633    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
634            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
635            Bundle state, List<ResultInfo> pendingResults,
636    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
637    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
638    		throws RemoteException {
639        Parcel data = Parcel.obtain();
640        data.writeInterfaceToken(IApplicationThread.descriptor);
641        intent.writeToParcel(data, 0);
642        data.writeStrongBinder(token);
643        data.writeInt(ident);
644        info.writeToParcel(data, 0);
645        curConfig.writeToParcel(data, 0);
646        compatInfo.writeToParcel(data, 0);
647        data.writeBundle(state);
648        data.writeTypedList(pendingResults);
649        data.writeTypedList(pendingNewIntents);
650        data.writeInt(notResumed ? 1 : 0);
651        data.writeInt(isForward ? 1 : 0);
652        data.writeString(profileName);
653        if (profileFd != null) {
654            data.writeInt(1);
655            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
656        } else {
657            data.writeInt(0);
658        }
659        data.writeInt(autoStopProfiler ? 1 : 0);
660        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
661                IBinder.FLAG_ONEWAY);
662        data.recycle();
663    }
664
665    public final void scheduleRelaunchActivity(IBinder token,
666            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
667            int configChanges, boolean notResumed, Configuration config)
668            throws RemoteException {
669        Parcel data = Parcel.obtain();
670        data.writeInterfaceToken(IApplicationThread.descriptor);
671        data.writeStrongBinder(token);
672        data.writeTypedList(pendingResults);
673        data.writeTypedList(pendingNewIntents);
674        data.writeInt(configChanges);
675        data.writeInt(notResumed ? 1 : 0);
676        if (config != null) {
677            data.writeInt(1);
678            config.writeToParcel(data, 0);
679        } else {
680            data.writeInt(0);
681        }
682        mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
683                IBinder.FLAG_ONEWAY);
684        data.recycle();
685    }
686
687    public void scheduleNewIntent(List<Intent> intents, IBinder token)
688            throws RemoteException {
689        Parcel data = Parcel.obtain();
690        data.writeInterfaceToken(IApplicationThread.descriptor);
691        data.writeTypedList(intents);
692        data.writeStrongBinder(token);
693        mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
694                IBinder.FLAG_ONEWAY);
695        data.recycle();
696    }
697
698    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
699            int configChanges) throws RemoteException {
700        Parcel data = Parcel.obtain();
701        data.writeInterfaceToken(IApplicationThread.descriptor);
702        data.writeStrongBinder(token);
703        data.writeInt(finishing ? 1 : 0);
704        data.writeInt(configChanges);
705        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
706                IBinder.FLAG_ONEWAY);
707        data.recycle();
708    }
709
710    public final void scheduleReceiver(Intent intent, ActivityInfo info,
711            CompatibilityInfo compatInfo, int resultCode, String resultData,
712            Bundle map, boolean sync) throws RemoteException {
713        Parcel data = Parcel.obtain();
714        data.writeInterfaceToken(IApplicationThread.descriptor);
715        intent.writeToParcel(data, 0);
716        info.writeToParcel(data, 0);
717        compatInfo.writeToParcel(data, 0);
718        data.writeInt(resultCode);
719        data.writeString(resultData);
720        data.writeBundle(map);
721        data.writeInt(sync ? 1 : 0);
722        mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
723                IBinder.FLAG_ONEWAY);
724        data.recycle();
725    }
726
727    public final void scheduleCreateBackupAgent(ApplicationInfo app,
728            CompatibilityInfo compatInfo, int backupMode) throws RemoteException {
729        Parcel data = Parcel.obtain();
730        data.writeInterfaceToken(IApplicationThread.descriptor);
731        app.writeToParcel(data, 0);
732        compatInfo.writeToParcel(data, 0);
733        data.writeInt(backupMode);
734        mRemote.transact(SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION, data, null,
735                IBinder.FLAG_ONEWAY);
736        data.recycle();
737    }
738
739    public final void scheduleDestroyBackupAgent(ApplicationInfo app,
740            CompatibilityInfo compatInfo) throws RemoteException {
741        Parcel data = Parcel.obtain();
742        data.writeInterfaceToken(IApplicationThread.descriptor);
743        app.writeToParcel(data, 0);
744        compatInfo.writeToParcel(data, 0);
745        mRemote.transact(SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION, data, null,
746                IBinder.FLAG_ONEWAY);
747        data.recycle();
748    }
749
750    public final void scheduleCreateService(IBinder token, ServiceInfo info,
751            CompatibilityInfo compatInfo) throws RemoteException {
752        Parcel data = Parcel.obtain();
753        data.writeInterfaceToken(IApplicationThread.descriptor);
754        data.writeStrongBinder(token);
755        info.writeToParcel(data, 0);
756        compatInfo.writeToParcel(data, 0);
757        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
758                IBinder.FLAG_ONEWAY);
759        data.recycle();
760    }
761
762    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
763            throws RemoteException {
764        Parcel data = Parcel.obtain();
765        data.writeInterfaceToken(IApplicationThread.descriptor);
766        data.writeStrongBinder(token);
767        intent.writeToParcel(data, 0);
768        data.writeInt(rebind ? 1 : 0);
769        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
770                IBinder.FLAG_ONEWAY);
771        data.recycle();
772    }
773
774    public final void scheduleUnbindService(IBinder token, Intent intent)
775            throws RemoteException {
776        Parcel data = Parcel.obtain();
777        data.writeInterfaceToken(IApplicationThread.descriptor);
778        data.writeStrongBinder(token);
779        intent.writeToParcel(data, 0);
780        mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
781                IBinder.FLAG_ONEWAY);
782        data.recycle();
783    }
784
785    public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
786	    int flags, Intent args) throws RemoteException {
787        Parcel data = Parcel.obtain();
788        data.writeInterfaceToken(IApplicationThread.descriptor);
789        data.writeStrongBinder(token);
790        data.writeInt(taskRemoved ? 1 : 0);
791        data.writeInt(startId);
792        data.writeInt(flags);
793        if (args != null) {
794            data.writeInt(1);
795            args.writeToParcel(data, 0);
796        } else {
797            data.writeInt(0);
798        }
799        mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
800                IBinder.FLAG_ONEWAY);
801        data.recycle();
802    }
803
804    public final void scheduleStopService(IBinder token)
805            throws RemoteException {
806        Parcel data = Parcel.obtain();
807        data.writeInterfaceToken(IApplicationThread.descriptor);
808        data.writeStrongBinder(token);
809        mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
810                IBinder.FLAG_ONEWAY);
811        data.recycle();
812    }
813
814    public final void bindApplication(String packageName, ApplicationInfo info,
815            List<ProviderInfo> providers, ComponentName testName, String profileName,
816            ParcelFileDescriptor profileFd, boolean autoStopProfiler, Bundle testArgs,
817            IInstrumentationWatcher testWatcher, int debugMode, boolean restrictedBackupMode,
818            boolean persistent, Configuration config, CompatibilityInfo compatInfo,
819            Map<String, IBinder> services, Bundle coreSettings) throws RemoteException {
820        Parcel data = Parcel.obtain();
821        data.writeInterfaceToken(IApplicationThread.descriptor);
822        data.writeString(packageName);
823        info.writeToParcel(data, 0);
824        data.writeTypedList(providers);
825        if (testName == null) {
826            data.writeInt(0);
827        } else {
828            data.writeInt(1);
829            testName.writeToParcel(data, 0);
830        }
831        data.writeString(profileName);
832        if (profileFd != null) {
833            data.writeInt(1);
834            profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
835        } else {
836            data.writeInt(0);
837        }
838        data.writeInt(autoStopProfiler ? 1 : 0);
839        data.writeBundle(testArgs);
840        data.writeStrongInterface(testWatcher);
841        data.writeInt(debugMode);
842        data.writeInt(restrictedBackupMode ? 1 : 0);
843        data.writeInt(persistent ? 1 : 0);
844        config.writeToParcel(data, 0);
845        compatInfo.writeToParcel(data, 0);
846        data.writeMap(services);
847        data.writeBundle(coreSettings);
848        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
849                IBinder.FLAG_ONEWAY);
850        data.recycle();
851    }
852
853    public final void scheduleExit() throws RemoteException {
854        Parcel data = Parcel.obtain();
855        data.writeInterfaceToken(IApplicationThread.descriptor);
856        mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
857                IBinder.FLAG_ONEWAY);
858        data.recycle();
859    }
860
861    public final void scheduleSuicide() throws RemoteException {
862        Parcel data = Parcel.obtain();
863        data.writeInterfaceToken(IApplicationThread.descriptor);
864        mRemote.transact(SCHEDULE_SUICIDE_TRANSACTION, data, null,
865                IBinder.FLAG_ONEWAY);
866        data.recycle();
867    }
868
869    public final void requestThumbnail(IBinder token)
870            throws RemoteException {
871        Parcel data = Parcel.obtain();
872        data.writeInterfaceToken(IApplicationThread.descriptor);
873        data.writeStrongBinder(token);
874        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
875                IBinder.FLAG_ONEWAY);
876        data.recycle();
877    }
878
879    public final void scheduleConfigurationChanged(Configuration config)
880            throws RemoteException {
881        Parcel data = Parcel.obtain();
882        data.writeInterfaceToken(IApplicationThread.descriptor);
883        config.writeToParcel(data, 0);
884        mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
885                IBinder.FLAG_ONEWAY);
886        data.recycle();
887    }
888
889    public void updateTimeZone() throws RemoteException {
890        Parcel data = Parcel.obtain();
891        data.writeInterfaceToken(IApplicationThread.descriptor);
892        mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
893                IBinder.FLAG_ONEWAY);
894        data.recycle();
895    }
896
897    public void clearDnsCache() throws RemoteException {
898        Parcel data = Parcel.obtain();
899        data.writeInterfaceToken(IApplicationThread.descriptor);
900        mRemote.transact(CLEAR_DNS_CACHE_TRANSACTION, data, null,
901                IBinder.FLAG_ONEWAY);
902        data.recycle();
903    }
904
905    public void setHttpProxy(String proxy, String port, String exclList) throws RemoteException {
906        Parcel data = Parcel.obtain();
907        data.writeInterfaceToken(IApplicationThread.descriptor);
908        data.writeString(proxy);
909        data.writeString(port);
910        data.writeString(exclList);
911        mRemote.transact(SET_HTTP_PROXY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
912        data.recycle();
913    }
914
915    public void processInBackground() throws RemoteException {
916        Parcel data = Parcel.obtain();
917        data.writeInterfaceToken(IApplicationThread.descriptor);
918        mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
919                IBinder.FLAG_ONEWAY);
920        data.recycle();
921    }
922
923    public void dumpService(FileDescriptor fd, IBinder token, String[] args)
924            throws RemoteException {
925        Parcel data = Parcel.obtain();
926        data.writeInterfaceToken(IApplicationThread.descriptor);
927        data.writeFileDescriptor(fd);
928        data.writeStrongBinder(token);
929        data.writeStringArray(args);
930        mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
931        data.recycle();
932    }
933
934    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
935            int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky)
936            throws RemoteException {
937        Parcel data = Parcel.obtain();
938        data.writeInterfaceToken(IApplicationThread.descriptor);
939        data.writeStrongBinder(receiver.asBinder());
940        intent.writeToParcel(data, 0);
941        data.writeInt(resultCode);
942        data.writeString(dataStr);
943        data.writeBundle(extras);
944        data.writeInt(ordered ? 1 : 0);
945        data.writeInt(sticky ? 1 : 0);
946        mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
947                IBinder.FLAG_ONEWAY);
948        data.recycle();
949    }
950
951    public final void scheduleLowMemory() throws RemoteException {
952        Parcel data = Parcel.obtain();
953        data.writeInterfaceToken(IApplicationThread.descriptor);
954        mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
955                IBinder.FLAG_ONEWAY);
956        data.recycle();
957    }
958
959    public final void scheduleActivityConfigurationChanged(
960            IBinder token) throws RemoteException {
961        Parcel data = Parcel.obtain();
962        data.writeInterfaceToken(IApplicationThread.descriptor);
963        data.writeStrongBinder(token);
964        mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
965                IBinder.FLAG_ONEWAY);
966        data.recycle();
967    }
968
969    public void profilerControl(boolean start, String path,
970            ParcelFileDescriptor fd, int profileType) throws RemoteException {
971        Parcel data = Parcel.obtain();
972        data.writeInterfaceToken(IApplicationThread.descriptor);
973        data.writeInt(start ? 1 : 0);
974        data.writeInt(profileType);
975        data.writeString(path);
976        if (fd != null) {
977            data.writeInt(1);
978            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
979        } else {
980            data.writeInt(0);
981        }
982        mRemote.transact(PROFILER_CONTROL_TRANSACTION, data, null,
983                IBinder.FLAG_ONEWAY);
984        data.recycle();
985    }
986
987    public void setSchedulingGroup(int group) throws RemoteException {
988        Parcel data = Parcel.obtain();
989        data.writeInterfaceToken(IApplicationThread.descriptor);
990        data.writeInt(group);
991        mRemote.transact(SET_SCHEDULING_GROUP_TRANSACTION, data, null,
992                IBinder.FLAG_ONEWAY);
993        data.recycle();
994    }
995
996    public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException {
997        Parcel data = Parcel.obtain();
998        Parcel reply = Parcel.obtain();
999        data.writeInterfaceToken(IApplicationThread.descriptor);
1000        mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0);
1001        reply.readException();
1002        outInfo.readFromParcel(reply);
1003        data.recycle();
1004        reply.recycle();
1005    }
1006
1007    public void dispatchPackageBroadcast(int cmd, String[] packages) throws RemoteException {
1008        Parcel data = Parcel.obtain();
1009        data.writeInterfaceToken(IApplicationThread.descriptor);
1010        data.writeInt(cmd);
1011        data.writeStringArray(packages);
1012        mRemote.transact(DISPATCH_PACKAGE_BROADCAST_TRANSACTION, data, null,
1013                IBinder.FLAG_ONEWAY);
1014        data.recycle();
1015
1016    }
1017
1018    public void scheduleCrash(String msg) throws RemoteException {
1019        Parcel data = Parcel.obtain();
1020        data.writeInterfaceToken(IApplicationThread.descriptor);
1021        data.writeString(msg);
1022        mRemote.transact(SCHEDULE_CRASH_TRANSACTION, data, null,
1023                IBinder.FLAG_ONEWAY);
1024        data.recycle();
1025
1026    }
1027
1028    public void dumpHeap(boolean managed, String path,
1029            ParcelFileDescriptor fd) throws RemoteException {
1030        Parcel data = Parcel.obtain();
1031        data.writeInterfaceToken(IApplicationThread.descriptor);
1032        data.writeInt(managed ? 1 : 0);
1033        data.writeString(path);
1034        if (fd != null) {
1035            data.writeInt(1);
1036            fd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
1037        } else {
1038            data.writeInt(0);
1039        }
1040        mRemote.transact(DUMP_HEAP_TRANSACTION, data, null,
1041                IBinder.FLAG_ONEWAY);
1042        data.recycle();
1043    }
1044
1045    public void dumpActivity(FileDescriptor fd, IBinder token, String prefix, String[] args)
1046            throws RemoteException {
1047        Parcel data = Parcel.obtain();
1048        data.writeInterfaceToken(IApplicationThread.descriptor);
1049        data.writeFileDescriptor(fd);
1050        data.writeStrongBinder(token);
1051        data.writeString(prefix);
1052        data.writeStringArray(args);
1053        mRemote.transact(DUMP_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
1054        data.recycle();
1055    }
1056
1057    public void setCoreSettings(Bundle coreSettings) throws RemoteException {
1058        Parcel data = Parcel.obtain();
1059        data.writeInterfaceToken(IApplicationThread.descriptor);
1060        data.writeBundle(coreSettings);
1061        mRemote.transact(SET_CORE_SETTINGS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
1062    }
1063
1064    public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info)
1065            throws RemoteException {
1066        Parcel data = Parcel.obtain();
1067        data.writeInterfaceToken(IApplicationThread.descriptor);
1068        data.writeString(pkg);
1069        info.writeToParcel(data, 0);
1070        mRemote.transact(UPDATE_PACKAGE_COMPATIBILITY_INFO_TRANSACTION, data, null,
1071                IBinder.FLAG_ONEWAY);
1072    }
1073
1074    public void scheduleTrimMemory(int level) throws RemoteException {
1075        Parcel data = Parcel.obtain();
1076        data.writeInterfaceToken(IApplicationThread.descriptor);
1077        data.writeInt(level);
1078        mRemote.transact(SCHEDULE_TRIM_MEMORY_TRANSACTION, data, null,
1079                IBinder.FLAG_ONEWAY);
1080    }
1081
1082    public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, boolean all,
1083            String[] args) throws RemoteException {
1084        Parcel data = Parcel.obtain();
1085        Parcel reply = Parcel.obtain();
1086        data.writeInterfaceToken(IApplicationThread.descriptor);
1087        data.writeFileDescriptor(fd);
1088        data.writeInt(checkin ? 1 : 0);
1089        data.writeInt(all ? 1 : 0);
1090        data.writeStringArray(args);
1091        mRemote.transact(DUMP_MEM_INFO_TRANSACTION, data, reply, 0);
1092        reply.readException();
1093        Debug.MemoryInfo info = new Debug.MemoryInfo();
1094        info.readFromParcel(reply);
1095        data.recycle();
1096        reply.recycle();
1097        return info;
1098    }
1099
1100    public void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException {
1101        Parcel data = Parcel.obtain();
1102        data.writeInterfaceToken(IApplicationThread.descriptor);
1103        data.writeFileDescriptor(fd);
1104        data.writeStringArray(args);
1105        mRemote.transact(DUMP_GFX_INFO_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
1106        data.recycle();
1107    }
1108}
1109