1 /* 2 * Copyright (C) 2009 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 17 package android.os; 18 19 import com.android.internal.os.IResultReceiver; 20 21 /** 22 * Generic interface for receiving a callback result from someone. Use this 23 * by creating a subclass and implement {@link #onReceiveResult}, which you can 24 * then pass to others and send through IPC, and receive results they 25 * supply with {@link #send}. 26 * 27 * <p>Note: the implementation underneath is just a simple wrapper around 28 * a {@link Binder} that is used to perform the communication. This means 29 * semantically you should treat it as such: this class does not impact process 30 * lifecycle management (you must be using some higher-level component to tell 31 * the system that your process needs to continue running), the connection will 32 * break if your process goes away for any reason, etc.</p> 33 */ 34 public class ResultReceiver implements Parcelable { 35 final boolean mLocal; 36 final Handler mHandler; 37 38 IResultReceiver mReceiver; 39 40 class MyRunnable implements Runnable { 41 final int mResultCode; 42 final Bundle mResultData; 43 MyRunnable(int resultCode, Bundle resultData)44 MyRunnable(int resultCode, Bundle resultData) { 45 mResultCode = resultCode; 46 mResultData = resultData; 47 } 48 run()49 public void run() { 50 onReceiveResult(mResultCode, mResultData); 51 } 52 } 53 54 class MyResultReceiver extends IResultReceiver.Stub { send(int resultCode, Bundle resultData)55 public void send(int resultCode, Bundle resultData) { 56 if (mHandler != null) { 57 mHandler.post(new MyRunnable(resultCode, resultData)); 58 } else { 59 onReceiveResult(resultCode, resultData); 60 } 61 } 62 } 63 64 /** 65 * Create a new ResultReceive to receive results. Your 66 * {@link #onReceiveResult} method will be called from the thread running 67 * <var>handler</var> if given, or from an arbitrary thread if null. 68 */ ResultReceiver(Handler handler)69 public ResultReceiver(Handler handler) { 70 mLocal = true; 71 mHandler = handler; 72 } 73 74 /** 75 * Deliver a result to this receiver. Will call {@link #onReceiveResult}, 76 * always asynchronously if the receiver has supplied a Handler in which 77 * to dispatch the result. 78 * @param resultCode Arbitrary result code to deliver, as defined by you. 79 * @param resultData Any additional data provided by you. 80 */ send(int resultCode, Bundle resultData)81 public void send(int resultCode, Bundle resultData) { 82 if (mLocal) { 83 if (mHandler != null) { 84 mHandler.post(new MyRunnable(resultCode, resultData)); 85 } else { 86 onReceiveResult(resultCode, resultData); 87 } 88 return; 89 } 90 91 if (mReceiver != null) { 92 try { 93 mReceiver.send(resultCode, resultData); 94 } catch (RemoteException e) { 95 } 96 } 97 } 98 99 /** 100 * Override to receive results delivered to this object. 101 * 102 * @param resultCode Arbitrary result code delivered by the sender, as 103 * defined by the sender. 104 * @param resultData Any additional data provided by the sender. 105 */ onReceiveResult(int resultCode, Bundle resultData)106 protected void onReceiveResult(int resultCode, Bundle resultData) { 107 } 108 describeContents()109 public int describeContents() { 110 return 0; 111 } 112 writeToParcel(Parcel out, int flags)113 public void writeToParcel(Parcel out, int flags) { 114 synchronized (this) { 115 if (mReceiver == null) { 116 mReceiver = new MyResultReceiver(); 117 } 118 out.writeStrongBinder(mReceiver.asBinder()); 119 } 120 } 121 ResultReceiver(Parcel in)122 ResultReceiver(Parcel in) { 123 mLocal = false; 124 mHandler = null; 125 mReceiver = IResultReceiver.Stub.asInterface(in.readStrongBinder()); 126 } 127 128 public static final Parcelable.Creator<ResultReceiver> CREATOR 129 = new Parcelable.Creator<ResultReceiver>() { 130 public ResultReceiver createFromParcel(Parcel in) { 131 return new ResultReceiver(in); 132 } 133 public ResultReceiver[] newArray(int size) { 134 return new ResultReceiver[size]; 135 } 136 }; 137 } 138