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