1/*
2 * Copyright (C) 2006 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 * Reference to a Handler, which others can use to send messages to it.
21 * This allows for the implementation of message-based communication across
22 * processes, by creating a Messenger pointing to a Handler in one process,
23 * and handing that Messenger to another process.
24 */
25public final class Messenger implements Parcelable {
26    private final IMessenger mTarget;
27
28    /**
29     * Create a new Messenger pointing to the given Handler.  Any Message
30     * objects sent through this Messenger will appear in the Handler as if
31     * {@link Handler#sendMessage(Message) Handler.sendMessage(Message)} had
32     * been called directly.
33     *
34     * @param target The Handler that will receive sent messages.
35     */
36    public Messenger(Handler target) {
37        mTarget = target.getIMessenger();
38    }
39
40    /**
41     * Send a Message to this Messenger's Handler.
42     *
43     * @param message The Message to send.  Usually retrieved through
44     * {@link Message#obtain() Message.obtain()}.
45     *
46     * @throws RemoteException Throws DeadObjectException if the target
47     * Handler no longer exists.
48     */
49    public void send(Message message) throws RemoteException {
50        mTarget.send(message);
51    }
52
53    /**
54     * Retrieve the IBinder that this Messenger is using to communicate with
55     * its associated Handler.
56     *
57     * @return Returns the IBinder backing this Messenger.
58     */
59    public IBinder getBinder() {
60        return mTarget.asBinder();
61    }
62
63    /**
64     * Comparison operator on two Messenger objects, such that true
65     * is returned then they both point to the same Handler.
66     */
67    public boolean equals(Object otherObj) {
68        if (otherObj == null) {
69            return false;
70        }
71        try {
72            return mTarget.asBinder().equals(((Messenger)otherObj)
73                    .mTarget.asBinder());
74        } catch (ClassCastException e) {
75        }
76        return false;
77    }
78
79    public int hashCode() {
80        return mTarget.asBinder().hashCode();
81    }
82
83    public int describeContents() {
84        return 0;
85    }
86
87    public void writeToParcel(Parcel out, int flags) {
88        out.writeStrongBinder(mTarget.asBinder());
89    }
90
91    public static final Parcelable.Creator<Messenger> CREATOR
92            = new Parcelable.Creator<Messenger>() {
93        public Messenger createFromParcel(Parcel in) {
94            IBinder target = in.readStrongBinder();
95            return target != null ? new Messenger(target) : null;
96        }
97
98        public Messenger[] newArray(int size) {
99            return new Messenger[size];
100        }
101    };
102
103    /**
104     * Convenience function for writing either a Messenger or null pointer to
105     * a Parcel.  You must use this with {@link #readMessengerOrNullFromParcel}
106     * for later reading it.
107     *
108     * @param messenger The Messenger to write, or null.
109     * @param out Where to write the Messenger.
110     */
111    public static void writeMessengerOrNullToParcel(Messenger messenger,
112            Parcel out) {
113        out.writeStrongBinder(messenger != null ? messenger.mTarget.asBinder()
114                : null);
115    }
116
117    /**
118     * Convenience function for reading either a Messenger or null pointer from
119     * a Parcel.  You must have previously written the Messenger with
120     * {@link #writeMessengerOrNullToParcel}.
121     *
122     * @param in The Parcel containing the written Messenger.
123     *
124     * @return Returns the Messenger read from the Parcel, or null if null had
125     * been written.
126     */
127    public static Messenger readMessengerOrNullFromParcel(Parcel in) {
128        IBinder b = in.readStrongBinder();
129        return b != null ? new Messenger(b) : null;
130    }
131
132    /**
133     * Create a Messenger from a raw IBinder, which had previously been
134     * retrieved with {@link #getBinder}.
135     *
136     * @param target The IBinder this Messenger should communicate with.
137     */
138    public Messenger(IBinder target) {
139        mTarget = IMessenger.Stub.asInterface(target);
140    }
141}
142