1e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo/*
2ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikas * Copyright 2018 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
19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
21e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Bundle;
22e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Handler;
23e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Parcel;
24e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.Parcelable;
25e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seoimport android.os.RemoteException;
269dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikas
27ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo;
28c39d9c75590eca86a5e7e32a8824ba04a0d42e9bAlan Viverette
29e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo/**
30e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * Generic interface for receiving a callback result from someone.  Use this
31e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * by creating a subclass and implement {@link #onReceiveResult}, which you can
32e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * then pass to others and send through IPC, and receive results they
33e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * supply with {@link #send}.
34e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo *
35e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * <p>Note: the implementation underneath is just a simple wrapper around
36e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * a {@link Binder} that is used to perform the communication.  This means
37e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * semantically you should treat it as such: this class does not impact process
38e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * lifecycle management (you must be using some higher-level component to tell
39e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * the system that your process needs to continue running), the connection will
40e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * break if your process goes away for any reason, etc.</p>
41e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo * @hide
42e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo */
438e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas@RestrictTo(LIBRARY_GROUP)
44e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seopublic class ResultReceiver implements Parcelable {
45e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    final boolean mLocal;
46e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    final Handler mHandler;
478e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
48e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    IResultReceiver mReceiver;
498e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
50e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    class MyRunnable implements Runnable {
51e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        final int mResultCode;
52e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        final Bundle mResultData;
538e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
54e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        MyRunnable(int resultCode, Bundle resultData) {
55e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            mResultCode = resultCode;
56e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            mResultData = resultData;
57e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
588e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
5915375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
60e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public void run() {
61e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            onReceiveResult(mResultCode, mResultData);
62e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
63e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
648e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
65e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    class MyResultReceiver extends IResultReceiver.Stub {
6615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
67e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public void send(int resultCode, Bundle resultData) {
68e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mHandler != null) {
69e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mHandler.post(new MyRunnable(resultCode, resultData));
70e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } else {
71e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                onReceiveResult(resultCode, resultData);
72e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
73e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
74e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
758e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
76e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
77e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Create a new ResultReceive to receive results.  Your
78e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * {@link #onReceiveResult} method will be called from the thread running
79e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * <var>handler</var> if given, or from an arbitrary thread if null.
80e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
81e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public ResultReceiver(Handler handler) {
82e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mLocal = true;
83e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mHandler = handler;
84e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
858e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
86e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
87e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Deliver a result to this receiver.  Will call {@link #onReceiveResult},
88e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * always asynchronously if the receiver has supplied a Handler in which
89e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * to dispatch the result.
90e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultCode Arbitrary result code to deliver, as defined by you.
91e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultData Any additional data provided by you.
92e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
93e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public void send(int resultCode, Bundle resultData) {
94e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        if (mLocal) {
95e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mHandler != null) {
96e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mHandler.post(new MyRunnable(resultCode, resultData));
97e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } else {
98e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                onReceiveResult(resultCode, resultData);
99e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
100e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return;
101e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
1028e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
103e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        if (mReceiver != null) {
104e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            try {
105e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mReceiver.send(resultCode, resultData);
106e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            } catch (RemoteException e) {
107e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
108e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
109e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
1108e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
111e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    /**
112e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * Override to receive results delivered to this object.
1138e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas     *
114e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultCode Arbitrary result code delivered by the sender, as
115e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * defined by the sender.
116e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     * @param resultData Any additional data provided by the sender.
117e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo     */
118e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    protected void onReceiveResult(int resultCode, Bundle resultData) {
119e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
1208e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
12115375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas    @Override
122e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public int describeContents() {
123e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        return 0;
124e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
125e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
12615375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas    @Override
127e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    public void writeToParcel(Parcel out, int flags) {
128e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        synchronized (this) {
129e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            if (mReceiver == null) {
130e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo                mReceiver = new MyResultReceiver();
131e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            }
132e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            out.writeStrongBinder(mReceiver.asBinder());
133e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
134e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
135e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo
136e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    ResultReceiver(Parcel in) {
137e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mLocal = false;
138e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mHandler = null;
139e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder());
140e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    }
1418e10080c914d1ad0784394fa3026b85535535847Aurimas Liutikas
142d3c5347b3ec0025ec906e2053eaa9b97287c46a5Kirill Grouchnikov    public static final Creator<ResultReceiver> CREATOR
143d3c5347b3ec0025ec906e2053eaa9b97287c46a5Kirill Grouchnikov            = new Creator<ResultReceiver>() {
14415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
145e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public ResultReceiver createFromParcel(Parcel in) {
146e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return new ResultReceiver(in);
147e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
14815375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas        @Override
149e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        public ResultReceiver[] newArray(int size) {
150e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo            return new ResultReceiver[size];
151e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo        }
152e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo    };
153e2dc54fb995a75eab424aafe4960799ed5512f4dJae Seo}
154