ApplicationThreadNative.java revision 9266c558bf1d21ff647525ff99f7dadbca417309
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.pm.ActivityInfo;
22import android.content.pm.ApplicationInfo;
23import android.content.pm.ProviderInfo;
24import android.content.pm.ServiceInfo;
25import android.content.res.Configuration;
26import android.os.Binder;
27import android.os.Bundle;
28import android.os.RemoteException;
29import android.os.IBinder;
30import android.os.Parcel;
31import android.os.ParcelFileDescriptor;
32
33import java.io.FileDescriptor;
34import java.io.IOException;
35import java.util.HashMap;
36import java.util.List;
37import java.util.Map;
38
39/** {@hide} */
40public abstract class ApplicationThreadNative extends Binder
41        implements IApplicationThread {
42    /**
43     * Cast a Binder object into an application thread interface, generating
44     * a proxy if needed.
45     */
46    static public IApplicationThread asInterface(IBinder obj) {
47        if (obj == null) {
48            return null;
49        }
50        IApplicationThread in =
51            (IApplicationThread)obj.queryLocalInterface(descriptor);
52        if (in != null) {
53            return in;
54        }
55
56        return new ApplicationThreadProxy(obj);
57    }
58
59    public ApplicationThreadNative() {
60        attachInterface(this, descriptor);
61    }
62
63    @Override
64    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
65            throws RemoteException {
66        switch (code) {
67        case SCHEDULE_PAUSE_ACTIVITY_TRANSACTION:
68        {
69            data.enforceInterface(IApplicationThread.descriptor);
70            IBinder b = data.readStrongBinder();
71            boolean finished = data.readInt() != 0;
72            int configChanges = data.readInt();
73            schedulePauseActivity(b, finished, configChanges);
74            return true;
75        }
76
77        case SCHEDULE_STOP_ACTIVITY_TRANSACTION:
78        {
79            data.enforceInterface(IApplicationThread.descriptor);
80            IBinder b = data.readStrongBinder();
81            boolean show = data.readInt() != 0;
82            int configChanges = data.readInt();
83            scheduleStopActivity(b, show, configChanges);
84            return true;
85        }
86
87        case SCHEDULE_WINDOW_VISIBILITY_TRANSACTION:
88        {
89            data.enforceInterface(IApplicationThread.descriptor);
90            IBinder b = data.readStrongBinder();
91            boolean show = data.readInt() != 0;
92            scheduleWindowVisibility(b, show);
93            return true;
94        }
95
96        case SCHEDULE_RESUME_ACTIVITY_TRANSACTION:
97        {
98            data.enforceInterface(IApplicationThread.descriptor);
99            IBinder b = data.readStrongBinder();
100            boolean isForward = data.readInt() != 0;
101            scheduleResumeActivity(b, isForward);
102            return true;
103        }
104
105        case SCHEDULE_SEND_RESULT_TRANSACTION:
106        {
107            data.enforceInterface(IApplicationThread.descriptor);
108            IBinder b = data.readStrongBinder();
109            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
110            scheduleSendResult(b, ri);
111            return true;
112        }
113
114        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
115        {
116            data.enforceInterface(IApplicationThread.descriptor);
117            Intent intent = Intent.CREATOR.createFromParcel(data);
118            IBinder b = data.readStrongBinder();
119            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
120            Bundle state = data.readBundle();
121            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
122            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
123            boolean notResumed = data.readInt() != 0;
124            boolean isForward = data.readInt() != 0;
125            scheduleLaunchActivity(intent, b, info, state, ri, pi, notResumed, isForward);
126            return true;
127        }
128
129        case SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION:
130        {
131            data.enforceInterface(IApplicationThread.descriptor);
132            IBinder b = data.readStrongBinder();
133            List<ResultInfo> ri = data.createTypedArrayList(ResultInfo.CREATOR);
134            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
135            int configChanges = data.readInt();
136            boolean notResumed = data.readInt() != 0;
137            scheduleRelaunchActivity(b, ri, pi, configChanges, notResumed);
138            return true;
139        }
140
141        case SCHEDULE_NEW_INTENT_TRANSACTION:
142        {
143            data.enforceInterface(IApplicationThread.descriptor);
144            List<Intent> pi = data.createTypedArrayList(Intent.CREATOR);
145            IBinder b = data.readStrongBinder();
146            scheduleNewIntent(pi, b);
147            return true;
148        }
149
150        case SCHEDULE_FINISH_ACTIVITY_TRANSACTION:
151        {
152            data.enforceInterface(IApplicationThread.descriptor);
153            IBinder b = data.readStrongBinder();
154            boolean finishing = data.readInt() != 0;
155            int configChanges = data.readInt();
156            scheduleDestroyActivity(b, finishing, configChanges);
157            return true;
158        }
159
160        case SCHEDULE_RECEIVER_TRANSACTION:
161        {
162            data.enforceInterface(IApplicationThread.descriptor);
163            Intent intent = Intent.CREATOR.createFromParcel(data);
164            ActivityInfo info = ActivityInfo.CREATOR.createFromParcel(data);
165            int resultCode = data.readInt();
166            String resultData = data.readString();
167            Bundle resultExtras = data.readBundle();
168            boolean sync = data.readInt() != 0;
169            scheduleReceiver(intent, info, resultCode, resultData,
170                    resultExtras, sync);
171            return true;
172        }
173
174        case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
175            data.enforceInterface(IApplicationThread.descriptor);
176            IBinder token = data.readStrongBinder();
177            ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
178            scheduleCreateService(token, info);
179            return true;
180        }
181
182        case SCHEDULE_BIND_SERVICE_TRANSACTION: {
183            data.enforceInterface(IApplicationThread.descriptor);
184            IBinder token = data.readStrongBinder();
185            Intent intent = Intent.CREATOR.createFromParcel(data);
186            boolean rebind = data.readInt() != 0;
187            scheduleBindService(token, intent, rebind);
188            return true;
189        }
190
191        case SCHEDULE_UNBIND_SERVICE_TRANSACTION: {
192            data.enforceInterface(IApplicationThread.descriptor);
193            IBinder token = data.readStrongBinder();
194            Intent intent = Intent.CREATOR.createFromParcel(data);
195            scheduleUnbindService(token, intent);
196            return true;
197        }
198
199        case SCHEDULE_SERVICE_ARGS_TRANSACTION:
200        {
201            data.enforceInterface(IApplicationThread.descriptor);
202            IBinder token = data.readStrongBinder();
203            int startId = data.readInt();
204            Intent args = Intent.CREATOR.createFromParcel(data);
205            scheduleServiceArgs(token, startId, args);
206            return true;
207        }
208
209        case SCHEDULE_STOP_SERVICE_TRANSACTION:
210        {
211            data.enforceInterface(IApplicationThread.descriptor);
212            IBinder token = data.readStrongBinder();
213            scheduleStopService(token);
214            return true;
215        }
216
217        case BIND_APPLICATION_TRANSACTION:
218        {
219            data.enforceInterface(IApplicationThread.descriptor);
220            String packageName = data.readString();
221            ApplicationInfo info =
222                ApplicationInfo.CREATOR.createFromParcel(data);
223            List<ProviderInfo> providers =
224                data.createTypedArrayList(ProviderInfo.CREATOR);
225            ComponentName testName = (data.readInt() != 0)
226                ? new ComponentName(data) : null;
227            String profileName = data.readString();
228            Bundle testArgs = data.readBundle();
229            IBinder binder = data.readStrongBinder();
230            IInstrumentationWatcher testWatcher = IInstrumentationWatcher.Stub.asInterface(binder);
231            int testMode = data.readInt();
232            Configuration config = Configuration.CREATOR.createFromParcel(data);
233            HashMap<String, IBinder> services = data.readHashMap(null);
234            bindApplication(packageName, info,
235                            providers, testName, profileName,
236                            testArgs, testWatcher, testMode, config, services);
237            return true;
238        }
239
240        case SCHEDULE_EXIT_TRANSACTION:
241        {
242            data.enforceInterface(IApplicationThread.descriptor);
243            scheduleExit();
244            return true;
245        }
246
247        case REQUEST_THUMBNAIL_TRANSACTION:
248        {
249            data.enforceInterface(IApplicationThread.descriptor);
250            IBinder b = data.readStrongBinder();
251            requestThumbnail(b);
252            return true;
253        }
254
255        case SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION:
256        {
257            data.enforceInterface(IApplicationThread.descriptor);
258            Configuration config = Configuration.CREATOR.createFromParcel(data);
259            scheduleConfigurationChanged(config);
260            return true;
261        }
262
263        case UPDATE_TIME_ZONE_TRANSACTION: {
264            data.enforceInterface(IApplicationThread.descriptor);
265            updateTimeZone();
266            return true;
267        }
268
269        case PROCESS_IN_BACKGROUND_TRANSACTION: {
270            data.enforceInterface(IApplicationThread.descriptor);
271            processInBackground();
272            return true;
273        }
274
275        case DUMP_SERVICE_TRANSACTION: {
276            data.enforceInterface(IApplicationThread.descriptor);
277            ParcelFileDescriptor fd = data.readFileDescriptor();
278            final IBinder service = data.readStrongBinder();
279            final String[] args = data.readStringArray();
280            if (fd != null) {
281                dumpService(fd.getFileDescriptor(), service, args);
282                try {
283                    fd.close();
284                } catch (IOException e) {
285                }
286            }
287            return true;
288        }
289
290        case SCHEDULE_REGISTERED_RECEIVER_TRANSACTION: {
291            data.enforceInterface(IApplicationThread.descriptor);
292            IIntentReceiver receiver = IIntentReceiver.Stub.asInterface(
293                    data.readStrongBinder());
294            Intent intent = Intent.CREATOR.createFromParcel(data);
295            int resultCode = data.readInt();
296            String dataStr = data.readString();
297            Bundle extras = data.readBundle();
298            boolean ordered = data.readInt() != 0;
299            scheduleRegisteredReceiver(receiver, intent,
300                    resultCode, dataStr, extras, ordered);
301            return true;
302        }
303
304        case SCHEDULE_LOW_MEMORY_TRANSACTION:
305        {
306            scheduleLowMemory();
307            return true;
308        }
309
310        case SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION:
311        {
312            data.enforceInterface(IApplicationThread.descriptor);
313            IBinder b = data.readStrongBinder();
314            scheduleActivityConfigurationChanged(b);
315            return true;
316        }
317
318        case REQUEST_PSS_TRANSACTION:
319        {
320            data.enforceInterface(IApplicationThread.descriptor);
321            requestPss();
322            return true;
323        }
324        }
325
326        return super.onTransact(code, data, reply, flags);
327    }
328
329    public IBinder asBinder()
330    {
331        return this;
332    }
333}
334
335class ApplicationThreadProxy implements IApplicationThread {
336    private final IBinder mRemote;
337
338    public ApplicationThreadProxy(IBinder remote) {
339        mRemote = remote;
340    }
341
342    public final IBinder asBinder() {
343        return mRemote;
344    }
345
346    public final void schedulePauseActivity(IBinder token, boolean finished,
347            int configChanges) throws RemoteException {
348        Parcel data = Parcel.obtain();
349        data.writeInterfaceToken(IApplicationThread.descriptor);
350        data.writeStrongBinder(token);
351        data.writeInt(finished ? 1 : 0);
352        data.writeInt(configChanges);
353        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
354                IBinder.FLAG_ONEWAY);
355        data.recycle();
356    }
357
358    public final void scheduleStopActivity(IBinder token, boolean showWindow,
359            int configChanges) throws RemoteException {
360        Parcel data = Parcel.obtain();
361        data.writeInterfaceToken(IApplicationThread.descriptor);
362        data.writeStrongBinder(token);
363        data.writeInt(showWindow ? 1 : 0);
364        data.writeInt(configChanges);
365        mRemote.transact(SCHEDULE_STOP_ACTIVITY_TRANSACTION, data, null,
366                IBinder.FLAG_ONEWAY);
367        data.recycle();
368    }
369
370    public final void scheduleWindowVisibility(IBinder token,
371            boolean showWindow) throws RemoteException {
372        Parcel data = Parcel.obtain();
373        data.writeInterfaceToken(IApplicationThread.descriptor);
374        data.writeStrongBinder(token);
375        data.writeInt(showWindow ? 1 : 0);
376        mRemote.transact(SCHEDULE_WINDOW_VISIBILITY_TRANSACTION, data, null,
377                IBinder.FLAG_ONEWAY);
378        data.recycle();
379    }
380
381    public final void scheduleResumeActivity(IBinder token, boolean isForward)
382            throws RemoteException {
383        Parcel data = Parcel.obtain();
384        data.writeInterfaceToken(IApplicationThread.descriptor);
385        data.writeStrongBinder(token);
386        data.writeInt(isForward ? 1 : 0);
387        mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
388                IBinder.FLAG_ONEWAY);
389        data.recycle();
390    }
391
392    public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
393    		throws RemoteException {
394        Parcel data = Parcel.obtain();
395        data.writeInterfaceToken(IApplicationThread.descriptor);
396        data.writeStrongBinder(token);
397        data.writeTypedList(results);
398        mRemote.transact(SCHEDULE_SEND_RESULT_TRANSACTION, data, null,
399                IBinder.FLAG_ONEWAY);
400        data.recycle();
401    }
402
403    public final void scheduleLaunchActivity(Intent intent, IBinder token,
404            ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
405    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward)
406    		throws RemoteException {
407        Parcel data = Parcel.obtain();
408        data.writeInterfaceToken(IApplicationThread.descriptor);
409        intent.writeToParcel(data, 0);
410        data.writeStrongBinder(token);
411        info.writeToParcel(data, 0);
412        data.writeBundle(state);
413        data.writeTypedList(pendingResults);
414        data.writeTypedList(pendingNewIntents);
415        data.writeInt(notResumed ? 1 : 0);
416        data.writeInt(isForward ? 1 : 0);
417        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
418                IBinder.FLAG_ONEWAY);
419        data.recycle();
420    }
421
422    public final void scheduleRelaunchActivity(IBinder token,
423            List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
424            int configChanges, boolean notResumed) throws RemoteException {
425        Parcel data = Parcel.obtain();
426        data.writeInterfaceToken(IApplicationThread.descriptor);
427        data.writeStrongBinder(token);
428        data.writeTypedList(pendingResults);
429        data.writeTypedList(pendingNewIntents);
430        data.writeInt(configChanges);
431        data.writeInt(notResumed ? 1 : 0);
432        mRemote.transact(SCHEDULE_RELAUNCH_ACTIVITY_TRANSACTION, data, null,
433                IBinder.FLAG_ONEWAY);
434        data.recycle();
435    }
436
437    public void scheduleNewIntent(List<Intent> intents, IBinder token)
438            throws RemoteException {
439        Parcel data = Parcel.obtain();
440        data.writeInterfaceToken(IApplicationThread.descriptor);
441        data.writeTypedList(intents);
442        data.writeStrongBinder(token);
443        mRemote.transact(SCHEDULE_NEW_INTENT_TRANSACTION, data, null,
444                IBinder.FLAG_ONEWAY);
445        data.recycle();
446    }
447
448    public final void scheduleDestroyActivity(IBinder token, boolean finishing,
449            int configChanges) throws RemoteException {
450        Parcel data = Parcel.obtain();
451        data.writeInterfaceToken(IApplicationThread.descriptor);
452        data.writeStrongBinder(token);
453        data.writeInt(finishing ? 1 : 0);
454        data.writeInt(configChanges);
455        mRemote.transact(SCHEDULE_FINISH_ACTIVITY_TRANSACTION, data, null,
456                IBinder.FLAG_ONEWAY);
457        data.recycle();
458    }
459
460    public final void scheduleReceiver(Intent intent, ActivityInfo info,
461            int resultCode, String resultData,
462            Bundle map, boolean sync) throws RemoteException {
463        Parcel data = Parcel.obtain();
464        data.writeInterfaceToken(IApplicationThread.descriptor);
465        intent.writeToParcel(data, 0);
466        info.writeToParcel(data, 0);
467        data.writeInt(resultCode);
468        data.writeString(resultData);
469        data.writeBundle(map);
470        data.writeInt(sync ? 1 : 0);
471        mRemote.transact(SCHEDULE_RECEIVER_TRANSACTION, data, null,
472                IBinder.FLAG_ONEWAY);
473        data.recycle();
474    }
475
476    public final void scheduleCreateService(IBinder token, ServiceInfo info)
477            throws RemoteException {
478        Parcel data = Parcel.obtain();
479        data.writeInterfaceToken(IApplicationThread.descriptor);
480        data.writeStrongBinder(token);
481        info.writeToParcel(data, 0);
482        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
483                IBinder.FLAG_ONEWAY);
484        data.recycle();
485    }
486
487    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)
488            throws RemoteException {
489        Parcel data = Parcel.obtain();
490        data.writeInterfaceToken(IApplicationThread.descriptor);
491        data.writeStrongBinder(token);
492        intent.writeToParcel(data, 0);
493        data.writeInt(rebind ? 1 : 0);
494        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,
495                IBinder.FLAG_ONEWAY);
496        data.recycle();
497    }
498
499    public final void scheduleUnbindService(IBinder token, Intent intent)
500            throws RemoteException {
501        Parcel data = Parcel.obtain();
502        data.writeInterfaceToken(IApplicationThread.descriptor);
503        data.writeStrongBinder(token);
504        intent.writeToParcel(data, 0);
505        mRemote.transact(SCHEDULE_UNBIND_SERVICE_TRANSACTION, data, null,
506                IBinder.FLAG_ONEWAY);
507        data.recycle();
508    }
509
510    public final void scheduleServiceArgs(IBinder token, int startId,
511	    Intent args) throws RemoteException {
512        Parcel data = Parcel.obtain();
513        data.writeInterfaceToken(IApplicationThread.descriptor);
514        data.writeStrongBinder(token);
515        data.writeInt(startId);
516        args.writeToParcel(data, 0);
517        mRemote.transact(SCHEDULE_SERVICE_ARGS_TRANSACTION, data, null,
518                IBinder.FLAG_ONEWAY);
519        data.recycle();
520    }
521
522    public final void scheduleStopService(IBinder token)
523            throws RemoteException {
524        Parcel data = Parcel.obtain();
525        data.writeInterfaceToken(IApplicationThread.descriptor);
526        data.writeStrongBinder(token);
527        mRemote.transact(SCHEDULE_STOP_SERVICE_TRANSACTION, data, null,
528                IBinder.FLAG_ONEWAY);
529        data.recycle();
530    }
531
532    public final void bindApplication(String packageName, ApplicationInfo info,
533            List<ProviderInfo> providers, ComponentName testName,
534            String profileName, Bundle testArgs, IInstrumentationWatcher testWatcher, int debugMode,
535            Configuration config, Map<String, IBinder> services) throws RemoteException {
536        Parcel data = Parcel.obtain();
537        data.writeInterfaceToken(IApplicationThread.descriptor);
538        data.writeString(packageName);
539        info.writeToParcel(data, 0);
540        data.writeTypedList(providers);
541        if (testName == null) {
542            data.writeInt(0);
543        } else {
544            data.writeInt(1);
545            testName.writeToParcel(data, 0);
546        }
547        data.writeString(profileName);
548        data.writeBundle(testArgs);
549        data.writeStrongInterface(testWatcher);
550        data.writeInt(debugMode);
551        config.writeToParcel(data, 0);
552        data.writeMap(services);
553        mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,
554                IBinder.FLAG_ONEWAY);
555        data.recycle();
556    }
557
558    public final void scheduleExit() throws RemoteException {
559        Parcel data = Parcel.obtain();
560        data.writeInterfaceToken(IApplicationThread.descriptor);
561        mRemote.transact(SCHEDULE_EXIT_TRANSACTION, data, null,
562                IBinder.FLAG_ONEWAY);
563        data.recycle();
564    }
565
566    public final void requestThumbnail(IBinder token)
567            throws RemoteException {
568        Parcel data = Parcel.obtain();
569        data.writeInterfaceToken(IApplicationThread.descriptor);
570        data.writeStrongBinder(token);
571        mRemote.transact(REQUEST_THUMBNAIL_TRANSACTION, data, null,
572                IBinder.FLAG_ONEWAY);
573        data.recycle();
574    }
575
576    public final void scheduleConfigurationChanged(Configuration config)
577            throws RemoteException {
578        Parcel data = Parcel.obtain();
579        data.writeInterfaceToken(IApplicationThread.descriptor);
580        config.writeToParcel(data, 0);
581        mRemote.transact(SCHEDULE_CONFIGURATION_CHANGED_TRANSACTION, data, null,
582                IBinder.FLAG_ONEWAY);
583        data.recycle();
584    }
585
586    public void updateTimeZone() throws RemoteException {
587        Parcel data = Parcel.obtain();
588        data.writeInterfaceToken(IApplicationThread.descriptor);
589        mRemote.transact(UPDATE_TIME_ZONE_TRANSACTION, data, null,
590                IBinder.FLAG_ONEWAY);
591        data.recycle();
592    }
593
594    public void processInBackground() throws RemoteException {
595        Parcel data = Parcel.obtain();
596        data.writeInterfaceToken(IApplicationThread.descriptor);
597        mRemote.transact(PROCESS_IN_BACKGROUND_TRANSACTION, data, null,
598                IBinder.FLAG_ONEWAY);
599        data.recycle();
600    }
601
602    public void dumpService(FileDescriptor fd, IBinder token, String[] args)
603            throws RemoteException {
604        Parcel data = Parcel.obtain();
605        data.writeInterfaceToken(IApplicationThread.descriptor);
606        data.writeFileDescriptor(fd);
607        data.writeStrongBinder(token);
608        data.writeStringArray(args);
609        mRemote.transact(DUMP_SERVICE_TRANSACTION, data, null, 0);
610        data.recycle();
611    }
612
613    public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
614            int resultCode, String dataStr, Bundle extras, boolean ordered)
615            throws RemoteException {
616        Parcel data = Parcel.obtain();
617        data.writeInterfaceToken(IApplicationThread.descriptor);
618        data.writeStrongBinder(receiver.asBinder());
619        intent.writeToParcel(data, 0);
620        data.writeInt(resultCode);
621        data.writeString(dataStr);
622        data.writeBundle(extras);
623        data.writeInt(ordered ? 1 : 0);
624        mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,
625                IBinder.FLAG_ONEWAY);
626        data.recycle();
627    }
628
629    public final void scheduleLowMemory() throws RemoteException {
630        Parcel data = Parcel.obtain();
631        data.writeInterfaceToken(IApplicationThread.descriptor);
632        mRemote.transact(SCHEDULE_LOW_MEMORY_TRANSACTION, data, null,
633                IBinder.FLAG_ONEWAY);
634        data.recycle();
635    }
636
637    public final void scheduleActivityConfigurationChanged(
638            IBinder token) throws RemoteException {
639        Parcel data = Parcel.obtain();
640        data.writeInterfaceToken(IApplicationThread.descriptor);
641        data.writeStrongBinder(token);
642        mRemote.transact(SCHEDULE_ACTIVITY_CONFIGURATION_CHANGED_TRANSACTION, data, null,
643                IBinder.FLAG_ONEWAY);
644        data.recycle();
645    }
646
647    public final void requestPss() throws RemoteException {
648        Parcel data = Parcel.obtain();
649        data.writeInterfaceToken(IApplicationThread.descriptor);
650        mRemote.transact(REQUEST_PSS_TRANSACTION, data, null,
651                IBinder.FLAG_ONEWAY);
652        data.recycle();
653    }
654
655}
656
657