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