ResultReceiver.java revision e2dc54fb995a75eab424aafe4960799ed5512f4d
1e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo/*
2e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * Copyright (C) 2015 The Android Open Source Project
3e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *
4e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * Licensed under the Apache License, Version 2.0 (the "License");
5e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * you may not use this file except in compliance with the License.
6e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * You may obtain a copy of the License at
7e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *
8e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *      http://www.apache.org/licenses/LICENSE-2.0
9e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *
10e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * Unless required by applicable law or agreed to in writing, software
11e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * distributed under the License is distributed on an "AS IS" BASIS,
12e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * See the License for the specific language governing permissions and
14e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * limitations under the License.
15e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo */
16e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
17e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seopackage android.support.v4.os;
18e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
19e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Bundle;
20e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Handler;
21e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Parcel;
22e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Parcelable;
23e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.RemoteException;
24e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.support.v4.os.IResultReceiver;
25e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
26e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo/**
27e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * Generic interface for receiving a callback result from someone.  Use this
28e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * by creating a subclass and implement {@link #onReceiveResult}, which you can
29e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * then pass to others and send through IPC, and receive results they
30e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * supply with {@link #send}.
31e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *
32e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * <p>Note: the implementation underneath is just a simple wrapper around
33e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * a {@link Binder} that is used to perform the communication.  This means
34e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * semantically you should treat it as such: this class does not impact process
35e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * lifecycle management (you must be using some higher-level component to tell
36e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * the system that your process needs to continue running), the connection will
37e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * break if your process goes away for any reason, etc.</p>
38e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * @hide
39e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo */
40e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seopublic class ResultReceiver implements Parcelable {
41e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    final boolean mLocal;
42e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    final Handler mHandler;
43e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
44e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    IResultReceiver mReceiver;
45e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
46e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    class MyRunnable implements Runnable {
47e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        final int mResultCode;
48e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        final Bundle mResultData;
49e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
50e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        MyRunnable(int resultCode, Bundle resultData) {
51e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            mResultCode = resultCode;
52e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            mResultData = resultData;
53e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
54e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
55e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public void run() {
56e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            onReceiveResult(mResultCode, mResultData);
57e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
58e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
59e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
60e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    class MyResultReceiver extends IResultReceiver.Stub {
61e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public void send(int resultCode, Bundle resultData) {
62e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mHandler != null) {
63e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mHandler.post(new MyRunnable(resultCode, resultData));
64e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } else {
65e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                onReceiveResult(resultCode, resultData);
66e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
67e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
68e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
69e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
70e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
71e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Create a new ResultReceive to receive results.  Your
72e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * {@link #onReceiveResult} method will be called from the thread running
73e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * <var>handler</var> if given, or from an arbitrary thread if null.
74e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
75e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public ResultReceiver(Handler handler) {
76e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mLocal = true;
77e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mHandler = handler;
78e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
79e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
80e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
81e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Deliver a result to this receiver.  Will call {@link #onReceiveResult},
82e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * always asynchronously if the receiver has supplied a Handler in which
83e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * to dispatch the result.
84e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultCode Arbitrary result code to deliver, as defined by you.
85e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultData Any additional data provided by you.
86e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
87e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public void send(int resultCode, Bundle resultData) {
88e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        if (mLocal) {
89e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mHandler != null) {
90e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mHandler.post(new MyRunnable(resultCode, resultData));
91e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } else {
92e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                onReceiveResult(resultCode, resultData);
93e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
94e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return;
95e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
96e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
97e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        if (mReceiver != null) {
98e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            try {
99e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mReceiver.send(resultCode, resultData);
100e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } catch (RemoteException e) {
101e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
102e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
103e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
104e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
105e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
106e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Override to receive results delivered to this object.
107e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     *
108e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultCode Arbitrary result code delivered by the sender, as
109e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * defined by the sender.
110e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultData Any additional data provided by the sender.
111e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
112e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    protected void onReceiveResult(int resultCode, Bundle resultData) {
113e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
114e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
115e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public int describeContents() {
116e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        return 0;
117e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
118e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
119e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public void writeToParcel(Parcel out, int flags) {
120e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        synchronized (this) {
121e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mReceiver == null) {
122e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mReceiver = new MyResultReceiver();
123e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
124e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            out.writeStrongBinder(mReceiver.asBinder());
125e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
126e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
127e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
128e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    ResultReceiver(Parcel in) {
129e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mLocal = false;
130e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mHandler = null;
131e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
132e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
133e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
134e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public static final Parcelable.Creator<ResultReceiver> CREATOR
135e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            = new Parcelable.Creator<ResultReceiver>() {
136e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public ResultReceiver createFromParcel(Parcel in) {
137e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return new ResultReceiver(in);
138e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
139e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public ResultReceiver[] newArray(int size) {
140e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return new ResultReceiver[size];
141e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
142e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    };
143e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo}
144