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
19import android.util.TimeUtils;
20
21/**
22 *
23 * Defines a message containing a description and arbitrary data object that can be
24 * sent to a {@link Handler}.  This object contains two extra int fields and an
25 * extra object field that allow you to not do allocations in many cases.
26 *
27 * <p class="note">While the constructor of Message is public, the best way to get
28 * one of these is to call {@link #obtain Message.obtain()} or one of the
29 * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
30 * them from a pool of recycled objects.</p>
31 */
32public final class Message implements Parcelable {
33    /**
34     * User-defined message code so that the recipient can identify
35     * what this message is about. Each {@link Handler} has its own name-space
36     * for message codes, so you do not need to worry about yours conflicting
37     * with other handlers.
38     */
39    public int what;
40
41    /**
42     * arg1 and arg2 are lower-cost alternatives to using
43     * {@link #setData(Bundle) setData()} if you only need to store a
44     * few integer values.
45     */
46    public int arg1;
47
48    /**
49     * arg1 and arg2 are lower-cost alternatives to using
50     * {@link #setData(Bundle) setData()} if you only need to store a
51     * few integer values.
52     */
53    public int arg2;
54
55    /**
56     * An arbitrary object to send to the recipient.  When using
57     * {@link Messenger} to send the message across processes this can only
58     * be non-null if it contains a Parcelable of a framework class (not one
59     * implemented by the application).   For other data transfer use
60     * {@link #setData}.
61     *
62     * <p>Note that Parcelable objects here are not supported prior to
63     * the {@link android.os.Build.VERSION_CODES#FROYO} release.
64     */
65    public Object obj;
66
67    /**
68     * Optional Messenger where replies to this message can be sent.  The
69     * semantics of exactly how this is used are up to the sender and
70     * receiver.
71     */
72    public Messenger replyTo;
73
74    /**
75     * Optional field indicating the uid that sent the message.  This is
76     * only valid for messages posted by a {@link Messenger}; otherwise,
77     * it will be -1.
78     */
79    public int sendingUid = -1;
80
81    /** If set message is in use.
82     * This flag is set when the message is enqueued and remains set while it
83     * is delivered and afterwards when it is recycled.  The flag is only cleared
84     * when a new message is created or obtained since that is the only time that
85     * applications are allowed to modify the contents of the message.
86     *
87     * It is an error to attempt to enqueue or recycle a message that is already in use.
88     */
89    /*package*/ static final int FLAG_IN_USE = 1 << 0;
90
91    /** If set message is asynchronous */
92    /*package*/ static final int FLAG_ASYNCHRONOUS = 1 << 1;
93
94    /** Flags to clear in the copyFrom method */
95    /*package*/ static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE;
96
97    /*package*/ int flags;
98
99    /*package*/ long when;
100
101    /*package*/ Bundle data;
102
103    /*package*/ Handler target;
104
105    /*package*/ Runnable callback;
106
107    // sometimes we store linked lists of these things
108    /*package*/ Message next;
109
110    private static final Object sPoolSync = new Object();
111    private static Message sPool;
112    private static int sPoolSize = 0;
113
114    private static final int MAX_POOL_SIZE = 50;
115
116    private static boolean gCheckRecycle = true;
117
118    /**
119     * Return a new Message instance from the global pool. Allows us to
120     * avoid allocating new objects in many cases.
121     */
122    public static Message obtain() {
123        synchronized (sPoolSync) {
124            if (sPool != null) {
125                Message m = sPool;
126                sPool = m.next;
127                m.next = null;
128                m.flags = 0; // clear in-use flag
129                sPoolSize--;
130                return m;
131            }
132        }
133        return new Message();
134    }
135
136    /**
137     * Same as {@link #obtain()}, but copies the values of an existing
138     * message (including its target) into the new one.
139     * @param orig Original message to copy.
140     * @return A Message object from the global pool.
141     */
142    public static Message obtain(Message orig) {
143        Message m = obtain();
144        m.what = orig.what;
145        m.arg1 = orig.arg1;
146        m.arg2 = orig.arg2;
147        m.obj = orig.obj;
148        m.replyTo = orig.replyTo;
149        m.sendingUid = orig.sendingUid;
150        if (orig.data != null) {
151            m.data = new Bundle(orig.data);
152        }
153        m.target = orig.target;
154        m.callback = orig.callback;
155
156        return m;
157    }
158
159    /**
160     * Same as {@link #obtain()}, but sets the value for the <em>target</em> member on the Message returned.
161     * @param h  Handler to assign to the returned Message object's <em>target</em> member.
162     * @return A Message object from the global pool.
163     */
164    public static Message obtain(Handler h) {
165        Message m = obtain();
166        m.target = h;
167
168        return m;
169    }
170
171    /**
172     * Same as {@link #obtain(Handler)}, but assigns a callback Runnable on
173     * the Message that is returned.
174     * @param h  Handler to assign to the returned Message object's <em>target</em> member.
175     * @param callback Runnable that will execute when the message is handled.
176     * @return A Message object from the global pool.
177     */
178    public static Message obtain(Handler h, Runnable callback) {
179        Message m = obtain();
180        m.target = h;
181        m.callback = callback;
182
183        return m;
184    }
185
186    /**
187     * Same as {@link #obtain()}, but sets the values for both <em>target</em> and
188     * <em>what</em> members on the Message.
189     * @param h  Value to assign to the <em>target</em> member.
190     * @param what  Value to assign to the <em>what</em> member.
191     * @return A Message object from the global pool.
192     */
193    public static Message obtain(Handler h, int what) {
194        Message m = obtain();
195        m.target = h;
196        m.what = what;
197
198        return m;
199    }
200
201    /**
202     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
203     * members.
204     * @param h  The <em>target</em> value to set.
205     * @param what  The <em>what</em> value to set.
206     * @param obj  The <em>object</em> method to set.
207     * @return  A Message object from the global pool.
208     */
209    public static Message obtain(Handler h, int what, Object obj) {
210        Message m = obtain();
211        m.target = h;
212        m.what = what;
213        m.obj = obj;
214
215        return m;
216    }
217
218    /**
219     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
220     * <em>arg1</em>, and <em>arg2</em> members.
221     *
222     * @param h  The <em>target</em> value to set.
223     * @param what  The <em>what</em> value to set.
224     * @param arg1  The <em>arg1</em> value to set.
225     * @param arg2  The <em>arg2</em> value to set.
226     * @return  A Message object from the global pool.
227     */
228    public static Message obtain(Handler h, int what, int arg1, int arg2) {
229        Message m = obtain();
230        m.target = h;
231        m.what = what;
232        m.arg1 = arg1;
233        m.arg2 = arg2;
234
235        return m;
236    }
237
238    /**
239     * Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
240     * <em>arg1</em>, <em>arg2</em>, and <em>obj</em> members.
241     *
242     * @param h  The <em>target</em> value to set.
243     * @param what  The <em>what</em> value to set.
244     * @param arg1  The <em>arg1</em> value to set.
245     * @param arg2  The <em>arg2</em> value to set.
246     * @param obj  The <em>obj</em> value to set.
247     * @return  A Message object from the global pool.
248     */
249    public static Message obtain(Handler h, int what,
250            int arg1, int arg2, Object obj) {
251        Message m = obtain();
252        m.target = h;
253        m.what = what;
254        m.arg1 = arg1;
255        m.arg2 = arg2;
256        m.obj = obj;
257
258        return m;
259    }
260
261    /** @hide */
262    public static void updateCheckRecycle(int targetSdkVersion) {
263        if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) {
264            gCheckRecycle = false;
265        }
266    }
267
268    /**
269     * Return a Message instance to the global pool.
270     * <p>
271     * You MUST NOT touch the Message after calling this function because it has
272     * effectively been freed.  It is an error to recycle a message that is currently
273     * enqueued or that is in the process of being delivered to a Handler.
274     * </p>
275     */
276    public void recycle() {
277        if (isInUse()) {
278            if (gCheckRecycle) {
279                throw new IllegalStateException("This message cannot be recycled because it "
280                        + "is still in use.");
281            }
282            return;
283        }
284        recycleUnchecked();
285    }
286
287    /**
288     * Recycles a Message that may be in-use.
289     * Used internally by the MessageQueue and Looper when disposing of queued Messages.
290     */
291    void recycleUnchecked() {
292        // Mark the message as in use while it remains in the recycled object pool.
293        // Clear out all other details.
294        flags = FLAG_IN_USE;
295        what = 0;
296        arg1 = 0;
297        arg2 = 0;
298        obj = null;
299        replyTo = null;
300        sendingUid = -1;
301        when = 0;
302        target = null;
303        callback = null;
304        data = null;
305
306        synchronized (sPoolSync) {
307            if (sPoolSize < MAX_POOL_SIZE) {
308                next = sPool;
309                sPool = this;
310                sPoolSize++;
311            }
312        }
313    }
314
315    /**
316     * Make this message like o.  Performs a shallow copy of the data field.
317     * Does not copy the linked list fields, nor the timestamp or
318     * target/callback of the original message.
319     */
320    public void copyFrom(Message o) {
321        this.flags = o.flags & ~FLAGS_TO_CLEAR_ON_COPY_FROM;
322        this.what = o.what;
323        this.arg1 = o.arg1;
324        this.arg2 = o.arg2;
325        this.obj = o.obj;
326        this.replyTo = o.replyTo;
327        this.sendingUid = o.sendingUid;
328
329        if (o.data != null) {
330            this.data = (Bundle) o.data.clone();
331        } else {
332            this.data = null;
333        }
334    }
335
336    /**
337     * Return the targeted delivery time of this message, in milliseconds.
338     */
339    public long getWhen() {
340        return when;
341    }
342
343    public void setTarget(Handler target) {
344        this.target = target;
345    }
346
347    /**
348     * Retrieve the a {@link android.os.Handler Handler} implementation that
349     * will receive this message. The object must implement
350     * {@link android.os.Handler#handleMessage(android.os.Message)
351     * Handler.handleMessage()}. Each Handler has its own name-space for
352     * message codes, so you do not need to
353     * worry about yours conflicting with other handlers.
354     */
355    public Handler getTarget() {
356        return target;
357    }
358
359    /**
360     * Retrieve callback object that will execute when this message is handled.
361     * This object must implement Runnable. This is called by
362     * the <em>target</em> {@link Handler} that is receiving this Message to
363     * dispatch it.  If
364     * not set, the message will be dispatched to the receiving Handler's
365     * {@link Handler#handleMessage(Message Handler.handleMessage())}.
366     */
367    public Runnable getCallback() {
368        return callback;
369    }
370
371    /**
372     * Obtains a Bundle of arbitrary data associated with this
373     * event, lazily creating it if necessary. Set this value by calling
374     * {@link #setData(Bundle)}.  Note that when transferring data across
375     * processes via {@link Messenger}, you will need to set your ClassLoader
376     * on the Bundle via {@link Bundle#setClassLoader(ClassLoader)
377     * Bundle.setClassLoader()} so that it can instantiate your objects when
378     * you retrieve them.
379     * @see #peekData()
380     * @see #setData(Bundle)
381     */
382    public Bundle getData() {
383        if (data == null) {
384            data = new Bundle();
385        }
386
387        return data;
388    }
389
390    /**
391     * Like getData(), but does not lazily create the Bundle.  A null
392     * is returned if the Bundle does not already exist.  See
393     * {@link #getData} for further information on this.
394     * @see #getData()
395     * @see #setData(Bundle)
396     */
397    public Bundle peekData() {
398        return data;
399    }
400
401    /**
402     * Sets a Bundle of arbitrary data values. Use arg1 and arg2 members
403     * as a lower cost way to send a few simple integer values, if you can.
404     * @see #getData()
405     * @see #peekData()
406     */
407    public void setData(Bundle data) {
408        this.data = data;
409    }
410
411    /**
412     * Sends this Message to the Handler specified by {@link #getTarget}.
413     * Throws a null pointer exception if this field has not been set.
414     */
415    public void sendToTarget() {
416        target.sendMessage(this);
417    }
418
419    /**
420     * Returns true if the message is asynchronous, meaning that it is not
421     * subject to {@link Looper} synchronization barriers.
422     *
423     * @return True if the message is asynchronous.
424     *
425     * @see #setAsynchronous(boolean)
426     */
427    public boolean isAsynchronous() {
428        return (flags & FLAG_ASYNCHRONOUS) != 0;
429    }
430
431    /**
432     * Sets whether the message is asynchronous, meaning that it is not
433     * subject to {@link Looper} synchronization barriers.
434     * <p>
435     * Certain operations, such as view invalidation, may introduce synchronization
436     * barriers into the {@link Looper}'s message queue to prevent subsequent messages
437     * from being delivered until some condition is met.  In the case of view invalidation,
438     * messages which are posted after a call to {@link android.view.View#invalidate}
439     * are suspended by means of a synchronization barrier until the next frame is
440     * ready to be drawn.  The synchronization barrier ensures that the invalidation
441     * request is completely handled before resuming.
442     * </p><p>
443     * Asynchronous messages are exempt from synchronization barriers.  They typically
444     * represent interrupts, input events, and other signals that must be handled independently
445     * even while other work has been suspended.
446     * </p><p>
447     * Note that asynchronous messages may be delivered out of order with respect to
448     * synchronous messages although they are always delivered in order among themselves.
449     * If the relative order of these messages matters then they probably should not be
450     * asynchronous in the first place.  Use with caution.
451     * </p>
452     *
453     * @param async True if the message is asynchronous.
454     *
455     * @see #isAsynchronous()
456     */
457    public void setAsynchronous(boolean async) {
458        if (async) {
459            flags |= FLAG_ASYNCHRONOUS;
460        } else {
461            flags &= ~FLAG_ASYNCHRONOUS;
462        }
463    }
464
465    /*package*/ boolean isInUse() {
466        return ((flags & FLAG_IN_USE) == FLAG_IN_USE);
467    }
468
469    /*package*/ void markInUse() {
470        flags |= FLAG_IN_USE;
471    }
472
473    /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
474    */
475    public Message() {
476    }
477
478    @Override
479    public String toString() {
480        return toString(SystemClock.uptimeMillis());
481    }
482
483    String toString(long now) {
484        StringBuilder b = new StringBuilder();
485        b.append("{ when=");
486        TimeUtils.formatDuration(when - now, b);
487
488        if (target != null) {
489            if (callback != null) {
490                b.append(" callback=");
491                b.append(callback.getClass().getName());
492            } else {
493                b.append(" what=");
494                b.append(what);
495            }
496
497            if (arg1 != 0) {
498                b.append(" arg1=");
499                b.append(arg1);
500            }
501
502            if (arg2 != 0) {
503                b.append(" arg2=");
504                b.append(arg2);
505            }
506
507            if (obj != null) {
508                b.append(" obj=");
509                b.append(obj);
510            }
511
512            b.append(" target=");
513            b.append(target.getClass().getName());
514        } else {
515            b.append(" barrier=");
516            b.append(arg1);
517        }
518
519        b.append(" }");
520        return b.toString();
521    }
522
523    public static final Parcelable.Creator<Message> CREATOR
524            = new Parcelable.Creator<Message>() {
525        public Message createFromParcel(Parcel source) {
526            Message msg = Message.obtain();
527            msg.readFromParcel(source);
528            return msg;
529        }
530
531        public Message[] newArray(int size) {
532            return new Message[size];
533        }
534    };
535
536    public int describeContents() {
537        return 0;
538    }
539
540    public void writeToParcel(Parcel dest, int flags) {
541        if (callback != null) {
542            throw new RuntimeException(
543                "Can't marshal callbacks across processes.");
544        }
545        dest.writeInt(what);
546        dest.writeInt(arg1);
547        dest.writeInt(arg2);
548        if (obj != null) {
549            try {
550                Parcelable p = (Parcelable)obj;
551                dest.writeInt(1);
552                dest.writeParcelable(p, flags);
553            } catch (ClassCastException e) {
554                throw new RuntimeException(
555                    "Can't marshal non-Parcelable objects across processes.");
556            }
557        } else {
558            dest.writeInt(0);
559        }
560        dest.writeLong(when);
561        dest.writeBundle(data);
562        Messenger.writeMessengerOrNullToParcel(replyTo, dest);
563        dest.writeInt(sendingUid);
564    }
565
566    private void readFromParcel(Parcel source) {
567        what = source.readInt();
568        arg1 = source.readInt();
569        arg2 = source.readInt();
570        if (source.readInt() != 0) {
571            obj = source.readParcelable(getClass().getClassLoader());
572        }
573        when = source.readLong();
574        data = source.readBundle();
575        replyTo = Messenger.readMessengerOrNullFromParcel(source);
576        sendingUid = source.readInt();
577    }
578}
579