mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1319496 - 3. Convert prompts to BundleEventListener; r=sebastian
Convert prompts to use BundleEventListener and GeckoBundle. DefaultDoorHanger.setOptions accepts a JSONObject argument, but if we converted it to GeckoBundle, it would involve a lot of extra changes in the other doorhanger code. So this patch adds GeckoBundle.fromJSONObject and converts JSONObject to GeckoBundle within DefaultDoorHanger.setOptions. In the future, another patch would convert all doorhanger code to use GeckoBundle instead of JSONObject.
This commit is contained in:
parent
ba7b253f47
commit
edb09e5551
@ -98,9 +98,11 @@ import org.mozilla.gecko.updater.PostUpdateHandler;
|
||||
import org.mozilla.gecko.updater.UpdateServiceHelper;
|
||||
import org.mozilla.gecko.util.ActivityUtils;
|
||||
import org.mozilla.gecko.util.Clipboard;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.FloatUtils;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.IntentUtils;
|
||||
@ -200,7 +202,8 @@ public class BrowserApp extends GeckoApp
|
||||
OnUrlOpenInBackgroundListener,
|
||||
AnchoredPopup.OnVisibilityChangeListener,
|
||||
ActionModeCompat.Presenter,
|
||||
LayoutInflater.Factory {
|
||||
LayoutInflater.Factory,
|
||||
BundleEventListener {
|
||||
private static final String LOGTAG = "GeckoBrowserApp";
|
||||
|
||||
private static final int TABS_ANIMATION_DURATION = 450;
|
||||
@ -729,7 +732,6 @@ public class BrowserApp extends GeckoApp
|
||||
"Menu:Update",
|
||||
"LightweightTheme:Update",
|
||||
"Search:Keyword",
|
||||
"Prompt:ShowTop",
|
||||
"Tab:Added",
|
||||
"Video:Play");
|
||||
|
||||
@ -751,6 +753,8 @@ public class BrowserApp extends GeckoApp
|
||||
"Updater:Launch",
|
||||
"Website:Metadata");
|
||||
|
||||
getAppEventDispatcher().registerUiThreadListener(this, "Prompt:ShowTop");
|
||||
|
||||
final GeckoProfile profile = getProfile();
|
||||
|
||||
// We want to upload the telemetry core ping as soon after startup as possible. It relies on the
|
||||
@ -1060,8 +1064,7 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
if (!mHasResumed) {
|
||||
EventDispatcher.getInstance().unregisterGeckoThreadListener((GeckoEventListener) this,
|
||||
"Prompt:ShowTop");
|
||||
getAppEventDispatcher().unregisterUiThreadListener(this, "Prompt:ShowTop");
|
||||
mHasResumed = true;
|
||||
}
|
||||
|
||||
@ -1081,8 +1084,7 @@ public class BrowserApp extends GeckoApp
|
||||
|
||||
if (mHasResumed) {
|
||||
// Register for Prompt:ShowTop so we can foreground this activity even if it's hidden.
|
||||
EventDispatcher.getInstance().registerGeckoThreadListener((GeckoEventListener) this,
|
||||
"Prompt:ShowTop");
|
||||
getAppEventDispatcher().registerUiThreadListener(this, "Prompt:ShowTop");
|
||||
mHasResumed = false;
|
||||
}
|
||||
|
||||
@ -1434,7 +1436,6 @@ public class BrowserApp extends GeckoApp
|
||||
"Menu:Update",
|
||||
"LightweightTheme:Update",
|
||||
"Search:Keyword",
|
||||
"Prompt:ShowTop",
|
||||
"Tab:Added",
|
||||
"Video:Play");
|
||||
|
||||
@ -1456,6 +1457,8 @@ public class BrowserApp extends GeckoApp
|
||||
"Updater:Launch",
|
||||
"Website:Metadata");
|
||||
|
||||
getAppEventDispatcher().unregisterUiThreadListener(this, "Prompt:ShowTop");
|
||||
|
||||
if (AppConstants.MOZ_ANDROID_BEAM) {
|
||||
NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this);
|
||||
if (nfc != null) {
|
||||
@ -1700,6 +1703,21 @@ public class BrowserApp extends GeckoApp
|
||||
mBrowserToolbar.refresh();
|
||||
}
|
||||
|
||||
@Override // BundleEventListener
|
||||
public void handleMessage(final String event, final GeckoBundle message,
|
||||
final EventCallback callback) {
|
||||
switch (event) {
|
||||
case "Prompt:ShowTop":
|
||||
// Bring this activity to front so the prompt is visible..
|
||||
Intent bringToFrontIntent = new Intent();
|
||||
bringToFrontIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME,
|
||||
AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
|
||||
bringToFrontIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
startActivity(bringToFrontIntent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(final String event, final NativeJSObject message,
|
||||
final EventCallback callback) {
|
||||
@ -2111,14 +2129,6 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
break;
|
||||
|
||||
case "Prompt:ShowTop":
|
||||
// Bring this activity to front so the prompt is visible..
|
||||
Intent bringToFrontIntent = new Intent();
|
||||
bringToFrontIntent.setClassName(AppConstants.ANDROID_PACKAGE_NAME, AppConstants.MOZ_ANDROID_BROWSER_INTENT_CLASS);
|
||||
bringToFrontIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
startActivity(bringToFrontIntent);
|
||||
break;
|
||||
|
||||
case "Tab:Added":
|
||||
if (message.getBoolean("cancelEditMode")) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
package org.mozilla.gecko.prompts;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.widget.BasicColorPicker;
|
||||
|
||||
import android.content.Context;
|
||||
@ -21,9 +21,9 @@ public class ColorPickerInput extends PromptInput {
|
||||
private final boolean mShowAdvancedButton = true;
|
||||
private final int mInitialColor;
|
||||
|
||||
public ColorPickerInput(JSONObject obj) {
|
||||
public ColorPickerInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
String init = obj.optString("value");
|
||||
String init = obj.getString("value");
|
||||
mInitialColor = Color.rgb(Integer.parseInt(init.substring(1, 3), 16),
|
||||
Integer.parseInt(init.substring(3, 5), 16),
|
||||
Integer.parseInt(init.substring(5, 7), 16));
|
||||
|
@ -8,10 +8,9 @@ package org.mozilla.gecko.prompts;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ResourceDrawableUtils;
|
||||
|
||||
import android.content.Context;
|
||||
@ -39,11 +38,12 @@ public class IconGridInput extends PromptInput implements OnItemClickListener {
|
||||
private static int mMaxColumns = -1; // The maximum number of columns to show
|
||||
private static int mIconSize = -1; // Size of icons in the grid
|
||||
private int mSelected; // Current selection
|
||||
private final JSONArray mArray;
|
||||
private final GeckoBundle[] mArray;
|
||||
|
||||
public IconGridInput(JSONObject obj) {
|
||||
public IconGridInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
mArray = obj.optJSONArray("items");
|
||||
final GeckoBundle[] array = obj.getBundleArray("items");
|
||||
mArray = array != null ? array : new GeckoBundle[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,9 +70,9 @@ public class IconGridInput extends PromptInput implements OnItemClickListener {
|
||||
final GridView view = (GridView) LayoutInflater.from(context).inflate(R.layout.icon_grid, null, false);
|
||||
view.setColumnWidth(mColumnWidth);
|
||||
|
||||
final ArrayList<IconGridItem> items = new ArrayList<IconGridItem>(mArray.length());
|
||||
for (int i = 0; i < mArray.length(); i++) {
|
||||
IconGridItem item = new IconGridItem(context, mArray.optJSONObject(i));
|
||||
final ArrayList<IconGridItem> items = new ArrayList<IconGridItem>(mArray.length);
|
||||
for (int i = 0; i < mArray.length; i++) {
|
||||
IconGridItem item = new IconGridItem(context, mArray[i]);
|
||||
items.add(item);
|
||||
if (item.selected) {
|
||||
mSelected = i;
|
||||
@ -151,11 +151,11 @@ public class IconGridInput extends PromptInput implements OnItemClickListener {
|
||||
final boolean selected;
|
||||
Drawable icon;
|
||||
|
||||
public IconGridItem(final Context context, final JSONObject obj) {
|
||||
label = obj.optString("name");
|
||||
final String iconUrl = obj.optString("iconUri");
|
||||
description = obj.optString("description");
|
||||
selected = obj.optBoolean("selected");
|
||||
public IconGridItem(final Context context, final GeckoBundle obj) {
|
||||
label = obj.getString("name");
|
||||
final String iconUrl = obj.getString("iconUri");
|
||||
description = obj.getString("description");
|
||||
selected = obj.getBoolean("selected");
|
||||
|
||||
ResourceDrawableUtils.getDrawable(context, iconUrl, new ResourceDrawableUtils.BitmapLoader() {
|
||||
@Override
|
||||
|
@ -11,6 +11,7 @@ import org.json.JSONObject;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
@ -78,27 +79,25 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
|
||||
return view;
|
||||
}
|
||||
|
||||
public void show(JSONObject message) {
|
||||
String title = message.optString("title");
|
||||
String text = message.optString("text");
|
||||
mGuid = message.optString("guid");
|
||||
public void show(GeckoBundle message) {
|
||||
String title = message.getString("title");
|
||||
String text = message.getString("text");
|
||||
mGuid = message.getString("guid");
|
||||
|
||||
mButtons = getStringArray(message, "buttons");
|
||||
mButtons = message.getStringArray("buttons");
|
||||
final int buttonCount = mButtons == null ? 0 : mButtons.length;
|
||||
mDoubleTapButtonType = convertIndexToButtonType(message.optInt("doubleTapButton", -1), buttonCount);
|
||||
mDoubleTapButtonType = convertIndexToButtonType(message.getInt("doubleTapButton", -1), buttonCount);
|
||||
mPreviousInputValue = null;
|
||||
|
||||
JSONArray inputs = getSafeArray(message, "inputs");
|
||||
mInputs = new PromptInput[inputs.length()];
|
||||
GeckoBundle[] inputs = message.getBundleArray("inputs");
|
||||
mInputs = new PromptInput[inputs != null ? inputs.length : 0];
|
||||
for (int i = 0; i < mInputs.length; i++) {
|
||||
try {
|
||||
mInputs[i] = PromptInput.getInput(inputs.getJSONObject(i));
|
||||
mInputs[i].setListener(this);
|
||||
} catch (Exception ex) { }
|
||||
mInputs[i] = PromptInput.getInput(inputs[i]);
|
||||
mInputs[i].setListener(this);
|
||||
}
|
||||
|
||||
PromptListItem[] menuitems = PromptListItem.getArray(message.optJSONArray("listitems"));
|
||||
String selected = message.optString("choiceMode");
|
||||
PromptListItem[] menuitems = PromptListItem.getArray(message.getBundleArray("listitems"));
|
||||
String selected = message.getString("choiceMode");
|
||||
|
||||
int choiceMode = ListView.CHOICE_MODE_NONE;
|
||||
if ("single".equals(selected)) {
|
||||
@ -107,9 +106,7 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
|
||||
choiceMode = ListView.CHOICE_MODE_MULTIPLE;
|
||||
}
|
||||
|
||||
if (message.has("tabId")) {
|
||||
mTabId = message.optInt("tabId", Tabs.INVALID_TAB_ID);
|
||||
}
|
||||
mTabId = message.getInt("tabId", Tabs.INVALID_TAB_ID);
|
||||
|
||||
show(title, text, menuitems, choiceMode);
|
||||
}
|
||||
@ -540,41 +537,6 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
|
||||
return false;
|
||||
}
|
||||
|
||||
private static JSONArray getSafeArray(JSONObject json, String key) {
|
||||
try {
|
||||
return json.getJSONArray(key);
|
||||
} catch (Exception e) {
|
||||
return new JSONArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getStringArray(JSONObject aObject, String aName) {
|
||||
JSONArray items = getSafeArray(aObject, aName);
|
||||
int length = items.length();
|
||||
String[] list = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
list[i] = items.getString(i);
|
||||
} catch (Exception ex) { }
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static boolean[] getBooleanArray(JSONObject aObject, String aName) {
|
||||
JSONArray items = new JSONArray();
|
||||
try {
|
||||
items = aObject.getJSONArray(aName);
|
||||
} catch (Exception ex) { return null; }
|
||||
int length = items.length();
|
||||
boolean[] list = new boolean[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
list[i] = items.getBoolean(i);
|
||||
} catch (Exception ex) { }
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public interface PromptCallback {
|
||||
|
||||
/**
|
||||
|
@ -9,8 +9,8 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.widget.AllCapsTextView;
|
||||
import org.mozilla.gecko.widget.DateTimePicker;
|
||||
|
||||
@ -59,10 +59,10 @@ public abstract class PromptInput {
|
||||
protected final boolean mAutofocus;
|
||||
public static final String INPUT_TYPE = "textbox";
|
||||
|
||||
public EditInput(JSONObject object) {
|
||||
public EditInput(GeckoBundle object) {
|
||||
super(object);
|
||||
mHint = object.optString("hint");
|
||||
mAutofocus = object.optBoolean("autofocus");
|
||||
mHint = object.getString("hint");
|
||||
mAutofocus = object.getBoolean("autofocus");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -103,7 +103,7 @@ public abstract class PromptInput {
|
||||
|
||||
public static class NumberInput extends EditInput {
|
||||
public static final String INPUT_TYPE = "number";
|
||||
public NumberInput(JSONObject obj) {
|
||||
public NumberInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ public abstract class PromptInput {
|
||||
|
||||
public static class PasswordInput extends EditInput {
|
||||
public static final String INPUT_TYPE = "password";
|
||||
public PasswordInput(JSONObject obj) {
|
||||
public PasswordInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@ -138,9 +138,9 @@ public abstract class PromptInput {
|
||||
public static final String INPUT_TYPE = "checkbox";
|
||||
private final boolean mChecked;
|
||||
|
||||
public CheckboxInput(JSONObject obj) {
|
||||
public CheckboxInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
mChecked = obj.optBoolean("checked");
|
||||
mChecked = obj.getBoolean("checked");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -170,7 +170,7 @@ public abstract class PromptInput {
|
||||
"month"
|
||||
};
|
||||
|
||||
public DateTimeInput(JSONObject obj) {
|
||||
public DateTimeInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@ -265,16 +265,17 @@ public abstract class PromptInput {
|
||||
|
||||
public static class MenulistInput extends PromptInput {
|
||||
public static final String INPUT_TYPE = "menulist";
|
||||
private static String[] mListitems;
|
||||
private static int mSelected;
|
||||
private final String[] mListitems;
|
||||
private final int mSelected;
|
||||
|
||||
public Spinner spinner;
|
||||
public AllCapsTextView textView;
|
||||
|
||||
public MenulistInput(JSONObject obj) {
|
||||
public MenulistInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
mListitems = Prompt.getStringArray(obj, "values");
|
||||
mSelected = obj.optInt("selected");
|
||||
final String[] listitems = obj.getStringArray("values");
|
||||
mListitems = listitems != null ? listitems : new String[0];
|
||||
mSelected = obj.getInt("selected");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -314,7 +315,7 @@ public abstract class PromptInput {
|
||||
|
||||
public static class LabelInput extends PromptInput {
|
||||
public static final String INPUT_TYPE = "label";
|
||||
public LabelInput(JSONObject obj) {
|
||||
public LabelInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
}
|
||||
|
||||
@ -328,18 +329,18 @@ public abstract class PromptInput {
|
||||
}
|
||||
}
|
||||
|
||||
public PromptInput(JSONObject obj) {
|
||||
mLabel = obj.optString("label");
|
||||
mType = obj.optString("type");
|
||||
String id = obj.optString("id");
|
||||
public PromptInput(GeckoBundle obj) {
|
||||
mLabel = obj.getString("label");
|
||||
mType = obj.getString("type");
|
||||
String id = obj.getString("id");
|
||||
mId = TextUtils.isEmpty(id) ? mType : id;
|
||||
mValue = obj.optString("value");
|
||||
mMaxValue = obj.optString("max");
|
||||
mMinValue = obj.optString("min");
|
||||
mValue = obj.getString("value");
|
||||
mMaxValue = obj.getString("max");
|
||||
mMinValue = obj.getString("min");
|
||||
}
|
||||
|
||||
public static PromptInput getInput(JSONObject obj) {
|
||||
String type = obj.optString("type");
|
||||
public static PromptInput getInput(GeckoBundle obj) {
|
||||
String type = obj.getString("type");
|
||||
switch (type) {
|
||||
case EditInput.INPUT_TYPE:
|
||||
return new EditInput(obj);
|
||||
|
@ -1,15 +1,12 @@
|
||||
package org.mozilla.gecko.prompts;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.mozilla.gecko.IntentHelper;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.ThumbnailHelper;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ResourceDrawableUtils;
|
||||
import org.mozilla.gecko.widget.GeckoActionProvider;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@ -32,32 +29,32 @@ public class PromptListItem {
|
||||
public boolean mSelected;
|
||||
public Drawable mIcon;
|
||||
|
||||
PromptListItem(JSONObject aObject) {
|
||||
PromptListItem(GeckoBundle aObject) {
|
||||
Context context = GeckoAppShell.getContext();
|
||||
label = aObject.isNull("label") ? "" : aObject.optString("label");
|
||||
isGroup = aObject.optBoolean("isGroup");
|
||||
inGroup = aObject.optBoolean("inGroup");
|
||||
disabled = aObject.optBoolean("disabled");
|
||||
id = aObject.optInt("id");
|
||||
mSelected = aObject.optBoolean("selected");
|
||||
label = aObject.getString("label", "");
|
||||
isGroup = aObject.getBoolean("isGroup");
|
||||
inGroup = aObject.getBoolean("inGroup");
|
||||
disabled = aObject.getBoolean("disabled");
|
||||
id = aObject.getInt("id");
|
||||
mSelected = aObject.getBoolean("selected");
|
||||
|
||||
JSONObject obj = aObject.optJSONObject("showAsActions");
|
||||
GeckoBundle obj = aObject.getBundle("showAsActions");
|
||||
if (obj != null) {
|
||||
showAsActions = true;
|
||||
String uri = obj.isNull("uri") ? "" : obj.optString("uri");
|
||||
String type = obj.isNull("type") ? GeckoActionProvider.DEFAULT_MIME_TYPE :
|
||||
obj.optString("type", GeckoActionProvider.DEFAULT_MIME_TYPE);
|
||||
String uri = obj.getString("uri", "");
|
||||
String type = obj.getString("type", GeckoActionProvider.DEFAULT_MIME_TYPE);
|
||||
|
||||
mIntent = IntentHelper.getShareIntent(context, uri, type, "");
|
||||
isParent = true;
|
||||
} else {
|
||||
mIntent = null;
|
||||
showAsActions = false;
|
||||
// Support both "isParent" (backwards compat for older consumers), and "menu" for the new Tabbed prompt ui.
|
||||
isParent = aObject.optBoolean("isParent") || aObject.optBoolean("menu");
|
||||
// Support both "isParent" (backwards compat for older consumers), and "menu"
|
||||
// for the new Tabbed prompt ui.
|
||||
isParent = aObject.getBoolean("isParent") || aObject.getBoolean("menu");
|
||||
}
|
||||
|
||||
final String iconStr = aObject.optString("icon");
|
||||
final String iconStr = aObject.getString("icon");
|
||||
if (iconStr != null) {
|
||||
final ResourceDrawableUtils.BitmapLoader loader = new ResourceDrawableUtils.BitmapLoader() {
|
||||
@Override
|
||||
@ -109,18 +106,16 @@ public class PromptListItem {
|
||||
showAsActions = false;
|
||||
}
|
||||
|
||||
static PromptListItem[] getArray(JSONArray items) {
|
||||
static PromptListItem[] getArray(GeckoBundle[] items) {
|
||||
if (items == null) {
|
||||
return new PromptListItem[0];
|
||||
}
|
||||
|
||||
int length = items.length();
|
||||
int length = items.length;
|
||||
List<PromptListItem> list = new ArrayList<>(length);
|
||||
for (int i = 0; i < length; i++) {
|
||||
try {
|
||||
PromptListItem item = new PromptListItem(items.getJSONObject(i));
|
||||
list.add(item);
|
||||
} catch (JSONException ex) { }
|
||||
PromptListItem item = new PromptListItem(items[i]);
|
||||
list.add(item);
|
||||
}
|
||||
|
||||
return list.toArray(new PromptListItem[length]);
|
||||
|
@ -5,68 +5,46 @@
|
||||
|
||||
package org.mozilla.gecko.prompts;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
public class PromptService implements GeckoEventListener {
|
||||
public class PromptService implements BundleEventListener {
|
||||
private static final String LOGTAG = "GeckoPromptService";
|
||||
|
||||
private final Context mContext;
|
||||
|
||||
public PromptService(Context context) {
|
||||
GeckoApp.getEventDispatcher().registerGeckoThreadListener(this,
|
||||
GeckoApp.getEventDispatcher().registerUiThreadListener(this,
|
||||
"Prompt:Show",
|
||||
"Prompt:ShowTop");
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
GeckoApp.getEventDispatcher().unregisterGeckoThreadListener(this,
|
||||
GeckoApp.getEventDispatcher().unregisterUiThreadListener(this,
|
||||
"Prompt:Show",
|
||||
"Prompt:ShowTop");
|
||||
}
|
||||
|
||||
public void show(final String aTitle, final String aText, final PromptListItem[] aMenuList,
|
||||
final int aChoiceMode, final Prompt.PromptCallback callback) {
|
||||
// The dialog must be created on the UI thread.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Prompt p;
|
||||
p = new Prompt(mContext, callback);
|
||||
p.show(aTitle, aText, aMenuList, aChoiceMode);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// GeckoEventListener implementation
|
||||
// BundleEventListener implementation
|
||||
@Override
|
||||
public void handleMessage(String event, final JSONObject message) {
|
||||
// The dialog must be created on the UI thread.
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
public void handleMessage(final String event, final GeckoBundle message,
|
||||
final EventCallback callback) {
|
||||
Prompt p;
|
||||
p = new Prompt(mContext, new Prompt.PromptCallback() {
|
||||
@Override
|
||||
public void run() {
|
||||
Prompt p;
|
||||
p = new Prompt(mContext, new Prompt.PromptCallback() {
|
||||
@Override
|
||||
public void onPromptFinished(String jsonResult) {
|
||||
try {
|
||||
EventDispatcher.sendResponse(message, new JSONObject(jsonResult));
|
||||
} catch (JSONException ex) {
|
||||
Log.i(LOGTAG, "Error building json response", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
p.show(message);
|
||||
public void onPromptFinished(String jsonResult) {
|
||||
callback.sendSuccess(jsonResult);
|
||||
}
|
||||
});
|
||||
p.show(message);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.content.Context;
|
||||
@ -33,19 +34,15 @@ public class TabInput extends PromptInput implements AdapterView.OnItemClickList
|
||||
private TabHost mHost;
|
||||
private int mPosition;
|
||||
|
||||
public TabInput(JSONObject obj) {
|
||||
public TabInput(GeckoBundle obj) {
|
||||
super(obj);
|
||||
mTabs = new LinkedHashMap<String, PromptListItem[]>();
|
||||
try {
|
||||
JSONArray tabs = obj.getJSONArray("items");
|
||||
for (int i = 0; i < tabs.length(); i++) {
|
||||
JSONObject tab = tabs.getJSONObject(i);
|
||||
String title = tab.getString("label");
|
||||
JSONArray items = tab.getJSONArray("items");
|
||||
mTabs.put(title, PromptListItem.getArray(items));
|
||||
}
|
||||
} catch (JSONException ex) {
|
||||
Log.e(LOGTAG, "Exception", ex);
|
||||
GeckoBundle[] tabs = obj.getBundleArray("items");
|
||||
for (int i = 0; i < (tabs != null ? tabs.length : 0); i++) {
|
||||
GeckoBundle tab = tabs[i];
|
||||
String title = tab.getString("label");
|
||||
GeckoBundle[] items = tab.getBundleArray("items");
|
||||
mTabs.put(title, PromptListItem.getArray(items));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Telemetry;
|
||||
import org.mozilla.gecko.TelemetryContract;
|
||||
import org.mozilla.gecko.prompts.PromptInput;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@ -109,7 +110,8 @@ public class DefaultDoorHanger extends DoorHanger {
|
||||
|
||||
for (int i = 0; i < inputs.length(); i++) {
|
||||
try {
|
||||
PromptInput input = PromptInput.getInput(inputs.getJSONObject(i));
|
||||
PromptInput input = PromptInput.getInput(
|
||||
GeckoBundle.fromJSONObject(inputs.getJSONObject(i)));
|
||||
mInputs.add(input);
|
||||
|
||||
final int padding = mResources.getDimensionPixelSize(R.dimen.doorhanger_section_padding_medium);
|
||||
|
@ -8,10 +8,15 @@ package org.mozilla.gecko.util;
|
||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.support.v4.util.SimpleArrayMap;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@ -618,4 +623,68 @@ public final class GeckoBundle {
|
||||
public int size() {
|
||||
return mMap.size();
|
||||
}
|
||||
|
||||
private static Object fromJSONValue(Object value) throws JSONException {
|
||||
if (value instanceof JSONObject || value == JSONObject.NULL) {
|
||||
return fromJSONObject((JSONObject) value);
|
||||
}
|
||||
if (value instanceof JSONArray) {
|
||||
final JSONArray array = (JSONArray) value;
|
||||
final int len = array.length();
|
||||
if (len == 0) {
|
||||
return EMPTY_BOOLEAN_ARRAY;
|
||||
}
|
||||
Object out = null;
|
||||
for (int i = 0; i < len; i++) {
|
||||
final Object element = fromJSONValue(array.opt(0));
|
||||
if (element == null) {
|
||||
continue;
|
||||
}
|
||||
if (out == null) {
|
||||
Class<?> type = element.getClass();
|
||||
if (type == Boolean.class) {
|
||||
type = boolean.class;
|
||||
} else if (type == Integer.class) {
|
||||
type = int.class;
|
||||
} else if (type == Double.class) {
|
||||
type = double.class;
|
||||
}
|
||||
out = Array.newInstance(type, len);
|
||||
}
|
||||
Array.set(out, i, element);
|
||||
}
|
||||
if (out == null) {
|
||||
// Treat all-null arrays as String arrays.
|
||||
return new String[len];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
if (value instanceof Boolean) {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof Byte || value instanceof Short || value instanceof Integer) {
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
if (value instanceof Float || value instanceof Double || value instanceof Long) {
|
||||
return ((Number) value).doubleValue();
|
||||
}
|
||||
return value != null ? value.toString() : null;
|
||||
}
|
||||
|
||||
public static GeckoBundle fromJSONObject(final JSONObject obj) throws JSONException {
|
||||
if (obj == null || obj == JSONObject.NULL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String[] keys = new String[obj.length()];
|
||||
final Object[] values = new String[obj.length()];
|
||||
|
||||
final Iterator<String> iter = obj.keys();
|
||||
for (int i = 0; iter.hasNext(); i++) {
|
||||
final String key = iter.next();
|
||||
keys[i] = key;
|
||||
values[i] = fromJSONValue(obj.opt(key));
|
||||
}
|
||||
return new GeckoBundle(keys, values);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/Messaging.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["Prompt"];
|
||||
|
||||
@ -176,7 +175,8 @@ Prompt.prototype = {
|
||||
},
|
||||
|
||||
_innerShow: function() {
|
||||
Messaging.sendRequestForResult(this.msg).then((data) => {
|
||||
let window = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
window.WindowEventDispatcher.sendRequestForResult(this.msg).then((data) => {
|
||||
if (this.callback)
|
||||
this.callback(data);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user