1/*
2 * Copyright (C) 2010 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
17package android.os;
18
19/**
20 * TODO: Make this a public API?  Let's see how it goes with a few use
21 * cases first.
22 * @hide
23 */
24public abstract class RemoteCallback implements Parcelable {
25    final Handler mHandler;
26    final IRemoteCallback mTarget;
27
28    class DeliverResult implements Runnable {
29        final Bundle mResult;
30
31        DeliverResult(Bundle result) {
32            mResult = result;
33        }
34
35        public void run() {
36            onResult(mResult);
37        }
38    }
39
40    class LocalCallback extends IRemoteCallback.Stub {
41        public void sendResult(Bundle bundle) {
42            mHandler.post(new DeliverResult(bundle));
43        }
44    }
45
46    static class RemoteCallbackProxy extends RemoteCallback {
47        RemoteCallbackProxy(IRemoteCallback target) {
48            super(target);
49        }
50
51        protected void onResult(Bundle bundle) {
52        }
53    }
54
55    public RemoteCallback(Handler handler) {
56        mHandler = handler;
57        mTarget = new LocalCallback();
58    }
59
60     RemoteCallback(IRemoteCallback target) {
61        mHandler = null;
62        mTarget = target;
63    }
64
65    public void sendResult(Bundle bundle) throws RemoteException {
66        mTarget.sendResult(bundle);
67    }
68
69    protected abstract void onResult(Bundle bundle);
70
71    public boolean equals(Object otherObj) {
72        if (otherObj == null) {
73            return false;
74        }
75        try {
76            return mTarget.asBinder().equals(((RemoteCallback)otherObj)
77                    .mTarget.asBinder());
78        } catch (ClassCastException e) {
79        }
80        return false;
81    }
82
83    public int hashCode() {
84        return mTarget.asBinder().hashCode();
85    }
86
87    public int describeContents() {
88        return 0;
89    }
90
91    public void writeToParcel(Parcel out, int flags) {
92        out.writeStrongBinder(mTarget.asBinder());
93    }
94
95    public static final Parcelable.Creator<RemoteCallback> CREATOR
96            = new Parcelable.Creator<RemoteCallback>() {
97        public RemoteCallback createFromParcel(Parcel in) {
98            IBinder target = in.readStrongBinder();
99            return target != null ? new RemoteCallbackProxy(
100                    IRemoteCallback.Stub.asInterface(target)) : null;
101        }
102
103        public RemoteCallback[] newArray(int size) {
104            return new RemoteCallback[size];
105        }
106    };
107}
108