AI2 Component  (Version nb184)
RetValManager.java
Go to the documentation of this file.
1 // -*- mode: java; c-basic-offset: 2; -*-
2 // Copyright 2013-2018 MIT, All rights reserved
3 // Released under the Apache License, Version 2.0
4 // http://www.apache.org/licenses/LICENSE-2.0
5 // This work is licensed under a Creative Commons Attribution 3.0 Unported License.
6 
7 package com.google.appinventor.components.runtime.util;
8 
9 import android.util.Log;
10 
13 
14 import java.util.ArrayList;
15 
16 import org.json.JSONArray;
17 import org.json.JSONException;
18 import org.json.JSONObject;
19 
20 
21 /*
22  * A Class for managing return values from evaluating Repl Forms and
23  * stashing them in a JSON Array for return to the Blocks Editor from the
24  * Companion.
25  */
26 
27 public class RetValManager {
28 
29  private static final String LOG_TAG = "RetValManager";
30  private static final Object semaphore = new Object();
31  private static final long TENSECONDS = 10000; // Ten Seconds (in milliseconds)
32 
33  // There can be only one!
34  private static ArrayList<JSONObject> currentArray = new ArrayList<JSONObject>(10);
35 
36  // Need a better place for this version string, but for various reasons, this is how we
37  // are going to do this for now...
38 
39  // Prevent instantiation, we are only called statically
40  private RetValManager() {
41  }
42 
43  /*
44  * appendReturnValue -- Add a result, already encoded as a String to
45  * the array of pending values.
46  *
47  * @param blockid The block id of the block this is for (-1 for no particular block)
48  * @param ok Indication of success or failure
49  * @param item The item to append
50  */
51  public static void appendReturnValue(String blockid, String ok, String item) {
52  synchronized (semaphore) {
53  JSONObject retval = new JSONObject();
54  try {
55  retval.put("status", ok);
56  retval.put("type", "return");
57  retval.put("value", item);
58  retval.put("blockid", blockid);
59  } catch (JSONException e) {
60  Log.e(LOG_TAG, "Error building retval", e);
61  return;
62  }
63  boolean sendNotify = currentArray.isEmpty();
64  currentArray.add(retval);
65  if (PhoneStatus.getUseWebRTC()) {
66  webRTCsendCurrent();
67  } else if (sendNotify) {
68  semaphore.notifyAll();
69  }
70  }
71  }
72 
73  public static void sendError(String error) {
74  synchronized (semaphore) {
75  JSONObject retval = new JSONObject();
76  try {
77  retval.put("status", "OK");
78  retval.put("type", "error");
79  retval.put("value", error);
80  } catch (JSONException e) {
81  Log.e(LOG_TAG, "Error building retval", e);
82  return;
83  }
84  boolean sendNotify = currentArray.isEmpty();
85  currentArray.add(retval);
86  if (PhoneStatus.getUseWebRTC()) {
87  webRTCsendCurrent();
88  } else if (sendNotify) {
89  semaphore.notifyAll();
90  }
91  }
92  }
93 
94  /*
95  * pushScreen -- Push to a new Screen
96  *
97  * @param screenName The screen to go to.
98  * @param value The value to hand it
99  */
100  public static void pushScreen(String screenName, Object value) {
101  synchronized (semaphore) {
102  JSONObject retval = new JSONObject();
103  try {
104  retval.put("status", "OK");
105  retval.put("type", "pushScreen");
106  retval.put("screen", screenName);
107  if (value != null)
108  retval.put("value", value.toString());
109  } catch (JSONException e) {
110  Log.e(LOG_TAG, "Error building retval", e);
111  return;
112  }
113  boolean sendNotify = currentArray.isEmpty();
114  currentArray.add(retval);
115  if (PhoneStatus.getUseWebRTC()) {
116  webRTCsendCurrent();
117  } else if (sendNotify) {
118  semaphore.notifyAll();
119  }
120  }
121  }
122 
123  /*
124  * popScreen -- Pop to a Previous Screen
125  *
126  * @param screenName The screen to go to.
127  * @param value The value to hand it
128  */
129  public static void popScreen(String value) {
130  synchronized (semaphore) {
131  JSONObject retval = new JSONObject();
132  try {
133  retval.put("status", "OK");
134  retval.put("type", "popScreen");
135  if (value != null)
136  retval.put("value", value.toString());
137  } catch (JSONException e) {
138  Log.e(LOG_TAG, "Error building retval", e);
139  return;
140  }
141  boolean sendNotify = currentArray.isEmpty();
142  currentArray.add(retval);
143  if (PhoneStatus.getUseWebRTC()) {
144  webRTCsendCurrent();
145  } else if (sendNotify) {
146  semaphore.notifyAll();
147  }
148  }
149  }
150 
151  /*
152  * assetTransferred
153  *
154  * @param name name of the asset transferred
155  */
156  public static void assetTransferred(String name) {
157  synchronized (semaphore) {
158  JSONObject retval = new JSONObject();
159  try {
160  retval.put("status", "OK");
161  retval.put("type", "assetTransferred");
162  if (name != null)
163  retval.put("value", name.toString());
164  } catch (JSONException e) {
165  Log.e(LOG_TAG, "Error building retval", e);
166  return;
167  }
168  boolean sendNotify = currentArray.isEmpty();
169  currentArray.add(retval);
170  if (PhoneStatus.getUseWebRTC()) {
171  webRTCsendCurrent();
172  } else if (sendNotify) {
173  semaphore.notifyAll();
174  }
175  }
176  }
177 
178  /*
179  * extensionsLoaded
180  *
181  */
182  public static void extensionsLoaded() {
183  synchronized (semaphore) {
184  JSONObject retval = new JSONObject();
185  try {
186  retval.put("status", "OK");
187  retval.put("type", "extensionsLoaded");
188  } catch (JSONException e) {
189  Log.e(LOG_TAG, "Error building retval", e);
190  return;
191  }
192  boolean sendNotify = currentArray.isEmpty();
193  currentArray.add(retval);
194  if (PhoneStatus.getUseWebRTC()) {
195  webRTCsendCurrent();
196  } else if (sendNotify) {
197  semaphore.notifyAll();
198  }
199  }
200  }
201 
202  /*
203  * fetch -- Fetch all pending results as a JSON encoded array.
204  *
205  * NOTE: This code is not used when we are using webrtc
206  *
207  * @param block true if we should block waiting for results
208  * @return String The JSON encoded array.
209  */
210  public static String fetch(boolean block) {
211  long startTime = System.currentTimeMillis();
212  synchronized (semaphore) {
213  while (currentArray.isEmpty() && block) {
214  long time = System.currentTimeMillis();
215  if ((time - startTime) > (TENSECONDS - 100)) // Time to give up...
216  break;
217  try {
218  semaphore.wait(TENSECONDS);
219  } catch (InterruptedException e) {
220  }
221  }
222  JSONArray arrayoutput = new JSONArray(currentArray);
223  JSONObject output = new JSONObject();
224  try {
225  output.put("status", "OK");
226  output.put("values", arrayoutput);
227  } catch (JSONException e) {
228  Log.e(LOG_TAG, "Error fetching retvals", e);
229  return("{\"status\" : \"BAD\", \"message\" : \"Failure in RetValManager\"}");
230  }
231  currentArray.clear(); // empty it out
232  return output.toString();
233  }
234  }
235 
236  // Only used for webrtc. Note: Our caller is holding "semphore" so we don't
237  // need to worry about multi-thread synchonization here
238  private static void webRTCsendCurrent() {
239  try {
240  JSONObject output = new JSONObject();
241  output.put("status", "OK");
242  output.put("values", new JSONArray(currentArray));
243  ReplForm.returnRetvals(output.toString());
244  } catch (JSONException e) {
245  Log.e(LOG_TAG, "Error building retval", e);
246  return;
247  }
248  currentArray.clear();
249  }
250 
251 }
com.google.appinventor.components.runtime.ReplForm
Definition: ReplForm.java:62
com.google.appinventor.components.runtime.util.RetValManager.popScreen
static void popScreen(String value)
Definition: RetValManager.java:129
com.google.appinventor.components.runtime.PhoneStatus.getUseWebRTC
static boolean getUseWebRTC()
Definition: PhoneStatus.java:356
com.google.appinventor.components
com.google.appinventor.components.runtime.util.RetValManager.pushScreen
static void pushScreen(String screenName, Object value)
Definition: RetValManager.java:100
com.google.appinventor.components.runtime.ReplForm.returnRetvals
static void returnRetvals(final String retvals)
Definition: ReplForm.java:449
com.google.appinventor.components.runtime.util.RetValManager.sendError
static void sendError(String error)
Definition: RetValManager.java:73
com.google.appinventor.components.runtime.util.RetValManager.extensionsLoaded
static void extensionsLoaded()
Definition: RetValManager.java:182
com.google.appinventor.components.runtime.util.RetValManager.appendReturnValue
static void appendReturnValue(String blockid, String ok, String item)
Definition: RetValManager.java:51
com.google.appinventor.components.runtime.util.RetValManager.fetch
static String fetch(boolean block)
Definition: RetValManager.java:210
com.google.appinventor.components.runtime
Copyright 2009-2011 Google, All Rights reserved.
Definition: AccelerometerSensor.java:8
com.google
com
com.google.appinventor.components.runtime.util.RetValManager
Definition: RetValManager.java:27
com.google.appinventor.components.runtime.util.RetValManager.assetTransferred
static void assetTransferred(String name)
Definition: RetValManager.java:156
com.google.appinventor
com.google.appinventor.components.runtime.PhoneStatus
Definition: PhoneStatus.java:74