Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(823)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/PostMessageSender.java

Issue 2422793002: HTML MessagePort as mojo::MessagePipeHandle (Closed)
Patch Set: Add missing ScopedAsyncTaskScheduler instance for the new unit tests; required by a recent change t… Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser;
6
7 import java.util.ArrayDeque;
8
9 /**
10 * Sanity checks and sends post messages to web. Queues messages if necessary.
11 */
12 public class PostMessageSender implements AppWebMessagePortService.MessageChanne lObserver {
13 /**
14 * The interface for message handler.
15 */
16 public static interface PostMessageSenderDelegate {
17 /*
18 * Posts a message to the destination frame for real. The unique message port
19 * id of any transferred port should be known at this time.
20 */
21 void postMessageToWeb(
22 String frameName, String message, String targetOrigin, int[] sen tPortIds);
23
24 /*
25 * Whether the post message sender is ready to post messages.
26 */
27 boolean isPostMessageSenderReady();
28
29 /*
30 * Informs that all messages are posted and message queue is empty.
31 */
32 void onPostMessageQueueEmpty();
33 }
34 ;
35
36 // A struct to store Message parameters that are sent from App to Web.
37 private static class PostMessageParams {
38 public String frameName;
39 public String message;
40 public String targetOrigin;
41 public AppWebMessagePort[] sentPorts;
42
43 public PostMessageParams(String frameName, String message, String target Origin,
44 AppWebMessagePort[] sentPorts) {
45 this.frameName = frameName;
46 this.message = message;
47 this.targetOrigin = targetOrigin;
48 this.sentPorts = sentPorts;
49 }
50 }
51
52 private PostMessageSenderDelegate mDelegate;
53 private AppWebMessagePortService mService;
54
55 // If a message that is sent from android webview to web has a pending port (a port that
56 // is not internally created yet), this message, and any following messages will be
57 // queued until the transferred port becomes ready. This is necessary to pre vent any
58 // reordering.
59 private ArrayDeque<PostMessageParams> mMessageQueue = new ArrayDeque<PostMes sageParams>();
60
61 public PostMessageSender(PostMessageSenderDelegate delegate, AppWebMessagePo rtService service) {
62 mDelegate = delegate;
63 mService = service;
64 }
65
66 // TODO(sgurun) in code review it was found this was implemented wrongly
67 // as mMessageQueue.size() > 0. write a test to catch this.
68 public boolean isMessageQueueEmpty() {
69 return mMessageQueue.size() == 0;
70 }
71
72 // Return true if any sent port is pending.
73 private boolean anySentPortIsPending(AppWebMessagePort[] sentPorts) {
74 if (sentPorts != null) {
75 for (AppWebMessagePort port : sentPorts) {
76 if (!port.isReady()) {
77 return true;
78 }
79 }
80 }
81 return false;
82 }
83
84 // A message to a frame is queued if:
85 // 1. Sender is not ready to post. When posting messages to frames, sender i s always
86 // ready. However, when posting messages using message channels, sender may be in
87 // a pending state.
88 // 2. There are already queued messages
89 // 3. The message includes a port that is not ready yet.
90 private boolean shouldQueueMessage(AppWebMessagePort[] sentPorts) {
91 // if messages to frames are already in queue mode, simply queue it, no need to
92 // check ports.
93 if (mMessageQueue.size() > 0 || !mDelegate.isPostMessageSenderReady()) {
94 return true;
95 }
96 if (anySentPortIsPending(sentPorts)) {
97 return true;
98 }
99 return false;
100 }
101
102 private void postMessageToWeb(
103 String frameName, String message, String targetOrigin, AppWebMessage Port[] sentPorts) {
104 int[] portIds = null;
105 if (sentPorts != null) {
106 portIds = new int[sentPorts.length];
107 for (int i = 0; i < sentPorts.length; i++) {
108 portIds[i] = sentPorts[i].portId();
109 }
110 mService.removeSentPorts(portIds);
111 }
112 mDelegate.postMessageToWeb(frameName, message, targetOrigin, portIds);
113 }
114
115 /*
116 * Sanity checks the message and queues it if necessary. Posts the message t o delegate
117 * when message can be sent.
118 */
119 public void postMessage(String frameName, String message, String targetOrigi n,
120 AppWebMessagePort[] sentPorts) throws IllegalStateException {
121 // Sanity check all the ports that are being transferred.
122 if (sentPorts != null) {
123 for (AppWebMessagePort p : sentPorts) {
124 if (p.isClosed()) {
125 throw new IllegalStateException("Closed port cannot be trans fered");
126 }
127 if (p.isTransferred()) {
128 throw new IllegalStateException("Port cannot be re-transferr ed");
129 }
130 if (p.isStarted()) {
131 throw new IllegalStateException("Started port cannot be tran sferred");
132 }
133 p.setTransferred();
134 }
135 }
136 if (shouldQueueMessage(sentPorts)) {
137 mMessageQueue.add(new PostMessageParams(frameName, message, targetOr igin, sentPorts));
138 } else {
139 postMessageToWeb(frameName, message, targetOrigin, sentPorts);
140 }
141 }
142
143 /*
144 * Starts posting any messages that are queued.
145 */
146 public void onMessageChannelCreated() {
147 PostMessageParams msg;
148
149 if (!mDelegate.isPostMessageSenderReady()) {
150 return;
151 }
152
153 while ((msg = mMessageQueue.peek()) != null) {
154 // If there are still pending ports, message cannot be posted.
155 if (anySentPortIsPending(msg.sentPorts)) {
156 return;
157 }
158 mMessageQueue.remove();
159 postMessageToWeb(msg.frameName, msg.message, msg.targetOrigin, msg.s entPorts);
160 }
161 mDelegate.onPostMessageQueueEmpty();
162 }
163 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698