Bug 1245692 - Pre: sanitise PromptInput setup r?mcomella draft
authorAndrzej Hunt <ahunt@mozilla.com>
Wed, 25 May 2016 11:42:37 -0700
changeset 374119 fb375a625cd6a35ff4060036deba5f1c621af7de
parent 374094 359674b9970a98e42c97184e9d7c59c89bac06d7
child 374120 3c5f360cbd253b9613127a70471943057ead4390
push id19938
push userahunt@mozilla.com
push dateWed, 01 Jun 2016 21:55:05 +0000
reviewersmcomella
bugs1245692
milestone49.0a1
Bug 1245692 - Pre: sanitise PromptInput setup r?mcomella MozReview-Commit-ID: 8qe9JqrACfh
mobile/android/base/java/org/mozilla/gecko/prompts/ColorPickerInput.java
mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java
mobile/android/base/java/org/mozilla/gecko/prompts/Prompt.java
mobile/android/base/java/org/mozilla/gecko/prompts/PromptInput.java
mobile/android/base/java/org/mozilla/gecko/prompts/TabInput.java
mobile/android/base/java/org/mozilla/gecko/widget/DefaultDoorHanger.java
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/ColorPickerInput.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/ColorPickerInput.java
@@ -13,39 +13,39 @@ import android.content.Context;
 import android.graphics.Color;
 import android.view.LayoutInflater;
 import android.view.View;
 
 public class ColorPickerInput extends PromptInput {
     public static final String INPUT_TYPE = "color";
     public static final String LOGTAG = "GeckoColorPickerInput";
 
-    private final boolean mShowAdvancedButton = true;
     private final int mInitialColor;
+    private final View mView;
 
-    public ColorPickerInput(JSONObject obj) {
+    public ColorPickerInput(JSONObject obj, Context context) {
         super(obj);
         String init = obj.optString("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));
-    }
 
-    @Override
-    public View getView(Context context) throws UnsupportedOperationException {
         LayoutInflater inflater = LayoutInflater.from(context);
         mView = inflater.inflate(R.layout.basic_color_picker_dialog, null);
 
         BasicColorPicker cp = (BasicColorPicker) mView.findViewById(R.id.colorpicker);
         cp.setColor(mInitialColor);
+    }
 
+    @Override
+    public View getView() throws UnsupportedOperationException {
         return mView;
     }
 
-    @Override
+@Override
     public Object getValue() {
         BasicColorPicker cp = (BasicColorPicker) mView.findViewById(R.id.colorpicker);
         int color = cp.getColor();
         return "#" + Integer.toHexString(color).substring(2);
     }
 
     @Override
     public boolean getScrollable() {
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java
@@ -37,23 +37,26 @@ public class IconGridInput extends Promp
     private ArrayAdapter<IconGridItem> mAdapter; // An adapter holding a list of items to show in the grid
 
     private static int mColumnWidth = -1;  // The maximum width of columns
     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;
 
-    public IconGridInput(JSONObject obj) {
+    private GridView mGrid;
+
+    public IconGridInput(JSONObject obj, Context context) {
         super(obj);
         mArray = obj.optJSONArray("items");
+
+        initView(context);
     }
 
-    @Override
-    public View getView(Context context) throws UnsupportedOperationException {
+    private void initView(Context context) {
         if (mColumnWidth < 0) {
             // getColumnWidth isn't available on pre-ICS, so we pull it out and assign it here
             mColumnWidth = context.getResources().getDimensionPixelSize(R.dimen.icongrid_columnwidth);
         }
 
         if (mIconSize < 0) {
             mIconSize = GeckoAppShell.getPreferredIconSize();
         }
@@ -63,41 +66,44 @@ public class IconGridInput extends Promp
         }
 
         // TODO: Dynamically handle size changes
         final WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         final Display display = wm.getDefaultDisplay();
         final int screenWidth = display.getWidth();
         int maxColumns = Math.min(mMaxColumns, screenWidth / mColumnWidth);
 
-        final GridView view = (GridView) LayoutInflater.from(context).inflate(R.layout.icon_grid, null, false);
-        view.setColumnWidth(mColumnWidth);
+        mGrid = (GridView) LayoutInflater.from(context).inflate(R.layout.icon_grid, null, false);
+        mGrid.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));
             items.add(item);
             if (item.selected) {
                 mSelected = i;
             }
         }
 
-        view.setNumColumns(Math.min(items.size(), maxColumns));
-        view.setOnItemClickListener(this);
+        mGrid.setNumColumns(Math.min(items.size(), maxColumns));
+        mGrid.setOnItemClickListener(this);
         // Despite what the docs say, setItemChecked was not moved into the AbsListView class until sometime between
         // Android 2.3.7 and Android 4.0.3. For other versions the item won't be visually highlighted, BUT we really only
         // mSelected will still be set so that we default to its behavior.
         if (Versions.feature11Plus && mSelected > -1) {
-            view.setItemChecked(mSelected, true);
+            mGrid.setItemChecked(mSelected, true);
         }
 
         mAdapter = new IconGridAdapter(context, -1, items);
-        view.setAdapter(mAdapter);
-        mView = view;
-        return mView;
+        mGrid.setAdapter(mAdapter);
+    }
+
+    @Override
+    public View getView() throws UnsupportedOperationException {
+        return mGrid;
     }
 
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         mSelected = position;
         notifyListeners(Integer.toString(position));
     }
 
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/Prompt.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/Prompt.java
@@ -88,17 +88,17 @@ public class Prompt implements OnClickLi
         final int buttonCount = mButtons == null ? 0 : mButtons.length;
         mDoubleTapButtonType = convertIndexToButtonType(message.optInt("doubleTapButton", -1), buttonCount);
         mPreviousInputValue = null;
 
         JSONArray inputs = getSafeArray(message, "inputs");
         mInputs = new PromptInput[inputs.length()];
         for (int i = 0; i < mInputs.length; i++) {
             try {
-                mInputs[i] = PromptInput.getInput(inputs.getJSONObject(i));
+                mInputs[i] = PromptInput.getInput(inputs.getJSONObject(i), mContext);
                 mInputs[i].setListener(this);
             } catch (Exception ex) { }
         }
 
         PromptListItem[] menuitems = PromptListItem.getArray(message.optJSONArray("listitems"));
         String selected = message.optString("choiceMode");
 
         int choiceMode = ListView.CHOICE_MODE_NONE;
@@ -381,17 +381,17 @@ public class Prompt implements OnClickLi
     /* Wraps an input in a linearlayout. We do this so that we can set padding that appears outside the background
      * drawable for the view.
      */
     private View wrapInput(final PromptInput input) {
         final LinearLayout linearLayout = new LinearLayout(mContext);
         linearLayout.setOrientation(LinearLayout.VERTICAL);
         applyInputStyle(linearLayout, input);
 
-        linearLayout.addView(input.getView(mContext));
+        linearLayout.addView(input.getView());
 
         return linearLayout;
     }
 
     /* Add the requested input elements to the dialog.
      *
      * @param builder
      *        the alert builder currently building this dialog.
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/PromptInput.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/PromptInput.java
@@ -38,200 +38,192 @@ import android.widget.TimePicker;
 public abstract class PromptInput {
     protected final String mLabel;
     protected final String mType;
     protected final String mId;
     protected final String mValue;
     protected final String mMinValue;
     protected final String mMaxValue;
     protected OnChangeListener mListener;
-    protected View mView;
     public static final String LOGTAG = "GeckoPromptInput";
 
     public interface OnChangeListener {
         void onChange(PromptInput input);
     }
 
     public void setListener(OnChangeListener listener) {
         mListener = listener;
     }
 
     public static class EditInput extends PromptInput {
         protected final String mHint;
         protected final boolean mAutofocus;
+        protected TextInputLayout mInputLayout;
         public static final String INPUT_TYPE = "textbox";
 
-        public EditInput(JSONObject object) {
+        public EditInput(JSONObject object, final Context context) {
             super(object);
             mHint = object.optString("hint");
             mAutofocus = object.optBoolean("autofocus");
-        }
 
-        @Override
-        public View getView(final Context context) throws UnsupportedOperationException {
             EditText input = new EditText(context);
             input.setInputType(InputType.TYPE_CLASS_TEXT);
             input.setText(mValue);
 
+            mInputLayout = new TextInputLayout(context);
+            mInputLayout.addView(input);
+
             if (!TextUtils.isEmpty(mHint)) {
                 input.setHint(mHint);
             }
 
             if (mAutofocus) {
                 input.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                     @Override
                     public void onFocusChange(View v, boolean hasFocus) {
                         if (hasFocus) {
                             ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(v, 0);
                         }
                     }
                 });
                 input.requestFocus();
             }
+        }
 
-            TextInputLayout inputLayout = new TextInputLayout(context);
-            inputLayout.addView(input);
-
-            mView = (View) inputLayout;
-            return mView;
+        @Override
+        public View getView() throws UnsupportedOperationException {
+            return mInputLayout;
         }
 
         @Override
         public Object getValue() {
-            final TextInputLayout inputLayout = (TextInputLayout) mView;
-            return inputLayout.getEditText().getText();
+            return mInputLayout.getEditText().getText();
         }
     }
 
     public static class NumberInput extends EditInput {
         public static final String INPUT_TYPE = "number";
-        public NumberInput(JSONObject obj) {
-            super(obj);
-        }
+
+        public NumberInput(JSONObject obj, Context context) {
+            super(obj, context);
 
-        @Override
-        public View getView(final Context context) throws UnsupportedOperationException {
-            final TextInputLayout inputLayout = (TextInputLayout) super.getView(context);
-            final EditText input = inputLayout.getEditText();
-            input.setRawInputType(Configuration.KEYBOARD_12KEY);
-            input.setInputType(InputType.TYPE_CLASS_NUMBER |
-                               InputType.TYPE_NUMBER_FLAG_SIGNED);
-            return input;
+            mInputLayout.getEditText().setRawInputType(Configuration.KEYBOARD_12KEY);
+            mInputLayout.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER |
+                    InputType.TYPE_NUMBER_FLAG_SIGNED);
         }
     }
 
     public static class PasswordInput extends EditInput {
         public static final String INPUT_TYPE = "password";
-        public PasswordInput(JSONObject obj) {
-            super(obj);
-        }
 
-        @Override
-        public View getView(Context context) throws UnsupportedOperationException {
-            final TextInputLayout inputLayout = (TextInputLayout) super.getView(context);
-            inputLayout.getEditText().setInputType(InputType.TYPE_CLASS_TEXT |
+        public PasswordInput(JSONObject obj, Context context) {
+            super(obj, context);
+
+            mInputLayout.getEditText().setInputType(InputType.TYPE_CLASS_TEXT |
                                InputType.TYPE_TEXT_VARIATION_PASSWORD |
                                InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
-            return inputLayout;
         }
     }
 
     public static class CheckboxInput extends PromptInput {
         public static final String INPUT_TYPE = "checkbox";
-        private final boolean mChecked;
+        private final CheckBox mCheckbox;
 
-        public CheckboxInput(JSONObject obj) {
+        public CheckboxInput(JSONObject obj, Context context) {
             super(obj);
-            mChecked = obj.optBoolean("checked");
+            final boolean isChecked = obj.optBoolean("checked");
+
+            mCheckbox = new AppCompatCheckBox(context);
+            mCheckbox.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+            mCheckbox.setText(mLabel);
+            mCheckbox.setChecked(isChecked);
         }
 
         @Override
-        public View getView(Context context) throws UnsupportedOperationException {
-            final CheckBox checkbox = new AppCompatCheckBox(context);
-            checkbox.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-            checkbox.setText(mLabel);
-            checkbox.setChecked(mChecked);
-            mView = (View)checkbox;
-            return mView;
+        public View getView(){
+            return mCheckbox;
         }
 
         @Override
         public Object getValue() {
-            CheckBox checkbox = (CheckBox)mView;
-            return checkbox.isChecked() ? Boolean.TRUE : Boolean.FALSE;
+            return Boolean.valueOf(mCheckbox.isChecked());
         }
     }
 
     public static class DateTimeInput extends PromptInput {
         public static final String[] INPUT_TYPES = new String[] {
             "date",
             "week",
             "time",
             "datetime-local",
             "datetime",
             "month"
         };
 
-        public DateTimeInput(JSONObject obj) {
+        private View mView;
+
+        public DateTimeInput(JSONObject obj, Context context) {
             super(obj);
-        }
 
-        @Override
-        public View getView(Context context) throws UnsupportedOperationException {
             if (mType.equals("date")) {
                 try {
                     DateTimePicker input = new DateTimePicker(context, "yyyy-MM-dd", mValue,
-                                                              DateTimePicker.PickersState.DATE, mMinValue, mMaxValue);
+                            DateTimePicker.PickersState.DATE, mMinValue, mMaxValue);
                     input.toggleCalendar(true);
-                    mView = (View)input;
+                    mView = (View) input;
                 } catch (UnsupportedOperationException ex) {
                     // We can't use our custom version of the DatePicker widget because the sdk is too old.
                     // But we can fallback on the native one.
                     DatePicker input = new DatePicker(context);
                     try {
                         if (!TextUtils.isEmpty(mValue)) {
                             GregorianCalendar calendar = new GregorianCalendar();
                             calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(mValue));
                             input.updateDate(calendar.get(Calendar.YEAR),
-                                             calendar.get(Calendar.MONTH),
-                                             calendar.get(Calendar.DAY_OF_MONTH));
+                                    calendar.get(Calendar.MONTH),
+                                    calendar.get(Calendar.DAY_OF_MONTH));
                         }
                     } catch (Exception e) {
                         Log.e(LOGTAG, "error parsing format string: " + e);
                     }
-                    mView = (View)input;
+                    mView = (View) input;
                 }
             } else if (mType.equals("week")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-'W'ww", mValue,
-                                                          DateTimePicker.PickersState.WEEK, mMinValue, mMaxValue);
-                mView = (View)input;
+                        DateTimePicker.PickersState.WEEK, mMinValue, mMaxValue);
+                mView = (View) input;
             } else if (mType.equals("time")) {
                 TimePicker input = new TimePicker(context);
                 input.setIs24HourView(DateFormat.is24HourFormat(context));
 
                 GregorianCalendar calendar = new GregorianCalendar();
                 if (!TextUtils.isEmpty(mValue)) {
                     try {
                         calendar.setTime(new SimpleDateFormat("HH:mm").parse(mValue));
-                    } catch (Exception e) { }
+                    } catch (Exception e) {
+                    }
                 }
                 input.setCurrentHour(calendar.get(GregorianCalendar.HOUR_OF_DAY));
                 input.setCurrentMinute(calendar.get(GregorianCalendar.MINUTE));
-                mView = (View)input;
+                mView = input;
             } else if (mType.equals("datetime-local") || mType.equals("datetime")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-MM-dd HH:mm", mValue.replace("T", " ").replace("Z", ""),
-                                                          DateTimePicker.PickersState.DATETIME,
-                                                          mMinValue.replace("T", " ").replace("Z", ""), mMaxValue.replace("T", " ").replace("Z", ""));
+                        DateTimePicker.PickersState.DATETIME,
+                        mMinValue.replace("T", " ").replace("Z", ""), mMaxValue.replace("T", " ").replace("Z", ""));
                 input.toggleCalendar(true);
-                mView = (View)input;
+                mView = (View) input;
             } else if (mType.equals("month")) {
                 DateTimePicker input = new DateTimePicker(context, "yyyy-MM", mValue,
-                                                          DateTimePicker.PickersState.MONTH, mMinValue, mMaxValue);
-                mView = (View)input;
+                        DateTimePicker.PickersState.MONTH, mMinValue, mMaxValue);
+                mView = input;
             }
+        }
+
+        @Override
+        public View getView() {
             return mView;
         }
 
         private static String formatDateString(String dateFormat, Calendar calendar) {
             return new SimpleDateFormat(dateFormat).format(calendar.getTime());
         }
 
         @Override
@@ -265,119 +257,125 @@ 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;
 
         public Spinner spinner;
         public AllCapsTextView textView;
+        private View mView;
 
-        public MenulistInput(JSONObject obj) {
+        public MenulistInput(JSONObject obj, Context context) {
             super(obj);
             mListitems = Prompt.getStringArray(obj, "values");
             mSelected = obj.optInt("selected");
-        }
 
-        @Override
-        public View getView(final Context context) throws UnsupportedOperationException {
             spinner = new Spinner(context, Spinner.MODE_DIALOG);
             try {
                 if (mListitems.length > 0) {
                     ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, mListitems);
                     adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
 
                     spinner.setAdapter(adapter);
                     spinner.setSelection(mSelected);
                 }
             } catch (Exception ex) {
             }
 
+            mView = spinner;
+
             if (!TextUtils.isEmpty(mLabel)) {
                 LinearLayout container = new LinearLayout(context);
                 container.setOrientation(LinearLayout.VERTICAL);
 
                 textView = new AllCapsTextView(context, null);
                 textView.setText(mLabel);
                 container.addView(textView);
 
                 container.addView(spinner);
-                return container;
+                mView = container;
             }
+        }
 
-            return spinner;
+        @Override
+        public View getView() throws UnsupportedOperationException {
+            return mView;
         }
 
         @Override
         public Object getValue() {
             return spinner.getSelectedItemPosition();
         }
     }
 
     public static class LabelInput extends PromptInput {
         public static final String INPUT_TYPE = "label";
-        public LabelInput(JSONObject obj) {
+
+        private final TextView mText;
+
+        public LabelInput(JSONObject obj, final Context context) {
             super(obj);
+
+            // not really an input, but a way to add labels and such to the dialog
+            mText = new TextView(context);
+            mText.setText(Html.fromHtml(mLabel));
         }
 
         @Override
-        public View getView(Context context) throws UnsupportedOperationException {
-            // not really an input, but a way to add labels and such to the dialog
-            TextView view = new TextView(context);
-            view.setText(Html.fromHtml(mLabel));
-            mView = view;
-            return mView;
+        public View getView() {
+            return mText;
         }
     }
 
     public PromptInput(JSONObject obj) {
         mLabel = obj.optString("label");
         mType = obj.optString("type");
         String id = obj.optString("id");
         mId = TextUtils.isEmpty(id) ? mType : id;
         mValue = obj.optString("value");
         mMaxValue = obj.optString("max");
         mMinValue = obj.optString("min");
     }
 
-    public static PromptInput getInput(JSONObject obj) {
+    public static PromptInput getInput(JSONObject obj, Context context) throws UnsupportedOperationException {
         String type = obj.optString("type");
         switch (type) {
             case EditInput.INPUT_TYPE:
-                return new EditInput(obj);
+                return new EditInput(obj, context);
             case NumberInput.INPUT_TYPE:
-                return new NumberInput(obj);
+                return new NumberInput(obj, context);
             case PasswordInput.INPUT_TYPE:
-                return new PasswordInput(obj);
+                return new PasswordInput(obj, context);
             case CheckboxInput.INPUT_TYPE:
-                return new CheckboxInput(obj);
+                return new CheckboxInput(obj, context);
             case MenulistInput.INPUT_TYPE:
-                return new MenulistInput(obj);
+                return new MenulistInput(obj, context);
             case LabelInput.INPUT_TYPE:
-                return new LabelInput(obj);
+                return new LabelInput(obj, context);
             case IconGridInput.INPUT_TYPE:
-                return new IconGridInput(obj);
+                return new IconGridInput(obj, context);
             case ColorPickerInput.INPUT_TYPE:
-                return new ColorPickerInput(obj);
+                return new ColorPickerInput(obj, context);
             case TabInput.INPUT_TYPE:
-                return new TabInput(obj);
+                return new TabInput(obj, context);
             default:
                 for (String dtType : DateTimeInput.INPUT_TYPES) {
                     if (dtType.equals(type)) {
-                        return new DateTimeInput(obj);
+                        return new DateTimeInput(obj, context);
                     }
                 }
 
                 break;
         }
 
         return null;
     }
 
-    public abstract View getView(Context context) throws UnsupportedOperationException;
+    public abstract View getView();
 
     public String getId() {
         return mId;
     }
 
     public Object getValue() {
         return null;
     }
--- a/mobile/android/base/java/org/mozilla/gecko/prompts/TabInput.java
+++ b/mobile/android/base/java/org/mozilla/gecko/prompts/TabInput.java
@@ -28,34 +28,32 @@ public class TabInput extends PromptInpu
     public static final String LOGTAG = "GeckoTabInput";
 
     /* Keeping the order of this in sync with the JSON is important. */
     final private LinkedHashMap<String, PromptListItem[]> mTabs;
 
     private TabHost mHost;
     private int mPosition;
 
-    public TabInput(JSONObject obj) {
+    public TabInput(JSONObject obj, final Context context) {
         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);
         }
-    }
 
-    @Override
-    public View getView(final Context context) throws UnsupportedOperationException {
+
         final LayoutInflater inflater = LayoutInflater.from(context);
         mHost = (TabHost) inflater.inflate(R.layout.tab_prompt_input, null);
         mHost.setup();
 
         for (String title : mTabs.keySet()) {
             final TabHost.TabSpec spec = mHost.newTabSpec(title);
             spec.setContent(new TabHost.TabContentFactory() {
                 @Override
@@ -67,17 +65,20 @@ public class TabInput extends PromptInpu
                     listView.setAdapter(adapter);
                     return listView;
                 }
             });
 
             spec.setIndicator(title);
             mHost.addTab(spec);
         }
-        mView = mHost;
+    }
+
+    @Override
+    public View getView() {
         return mHost;
     }
 
     @Override
     public Object getValue() {
         JSONObject obj = new JSONObject();
         try {
             obj.put("tab", mHost.getCurrentTab());
--- a/mobile/android/base/java/org/mozilla/gecko/widget/DefaultDoorHanger.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/DefaultDoorHanger.java
@@ -104,21 +104,21 @@ public class DefaultDoorHanger extends D
         if (inputs != null) {
             mInputs = new ArrayList<PromptInput>();
 
             final ViewGroup group = (ViewGroup) findViewById(R.id.doorhanger_inputs);
             group.setVisibility(VISIBLE);
 
             for (int i = 0; i < inputs.length(); i++) {
                 try {
-                    PromptInput input = PromptInput.getInput(inputs.getJSONObject(i));
+                    PromptInput input = PromptInput.getInput(inputs.getJSONObject(i), getContext());
                     mInputs.add(input);
 
                     final int padding = mResources.getDimensionPixelSize(R.dimen.doorhanger_section_padding_medium);
-                    View v = input.getView(getContext());
+                    View v = input.getView();
                     styleInput(input, v);
                     v.setPadding(0, 0, 0, padding);
                     group.addView(v);
                 } catch (JSONException ex) { }
             }
         }
 
         final String checkBoxText = options.optString("checkbox");