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