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