1 /*
2  * Copyright (C) 2008 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.app.stubs;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.DatePickerDialog;
22 import android.app.Dialog;
23 import android.app.TimePickerDialog;
24 import android.app.DatePickerDialog.OnDateSetListener;
25 import android.app.TimePickerDialog.OnTimeSetListener;
26 import android.content.Context;
27 import android.content.DialogInterface;
28 import android.content.Intent;
29 import android.content.DialogInterface.OnCancelListener;
30 import android.os.Bundle;
31 import android.os.Handler;
32 import android.os.Message;
33 import android.test.ActivityInstrumentationTestCase2;
34 import android.util.Log;
35 import android.view.KeyEvent;
36 import android.view.LayoutInflater;
37 import android.view.View;
38 import android.widget.DatePicker;
39 import android.widget.TimePicker;
40 
41 /*
42  * Stub class for  Dialog, AlertDialog, DatePickerDialog, TimePickerDialog etc.
43  */
44 public class DialogStubActivity extends Activity {
45     public static final int TEST_DIALOG_WITHOUT_THEME = 0;
46     public static final int TEST_DIALOG_WITH_THEME = 1;
47     public static final int TEST_ALERTDIALOG = 2;
48     public static final int TEST_CUSTOM_ALERTDIALOG = 3;
49     public static final int TEST_DATEPICKERDIALOG = 4;
50     public static final int TEST_DATEPICKERDIALOG_WITH_THEME = 5;
51     public static final int TEST_TIMEPICKERDIALOG = 6;
52     public static final int TEST_TIMEPICKERDIALOG_WITH_THEME = 7;
53     public static final int TEST_ONSTART_AND_ONSTOP = 8;
54     public static final int TEST_ALERTDIALOG_DEPRECATED = 9;
55     public static final int TEST_ALERTDIALOG_CALLBACK = 10;
56     public static final int TEST_CUSTOM_ALERTDIALOG_VIEW = 11;
57     public static final int TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE = 12;
58     public static final int TEST_ALERTDIALOG_THEME = 13;
59     public static final int TEST_ALERTDIALOG_CANCELABLE = 14;
60     public static final int TEST_ALERTDIALOG_NOT_CANCELABLE = 15;
61     public static final int TEST_PROTECTED_CANCELABLE = 16;
62     public static final int TEST_PROTECTED_NOT_CANCELABLE = 17;
63     public static final int TEST_ALERT_DIALOG_ICON_DRAWABLE = 18;
64     public static final int TEST_ALERT_DIALOG_ICON_ATTRIBUTE = 19;
65     public static final int TEST_ALERTDIALOG_WITH_MESSAGE = 20;
66 
67     public static final int SPACING_LEFT = 10;
68     public static final int SPACING_TOP = 20;
69     public static final int SPACING_RIGHT = 30;
70     public static final int SPACING_BOTTOM = 40;
71     public static int buttonIndex;
72 
73     public static final String DEFAULT_ALERTDIALOG_TITLE = "AlertDialog";
74     public static final String DEFAULT_ALERTDIALOG_MESSAGE = "AlertDialog message";
75     private static final String LOG_TAG = "DialogStubActivity";
76 
77     public boolean isPositiveButtonClicked = false;
78     public boolean isNegativeButtonClicked = false;
79     public boolean isNeutralButtonClicked = false;
80     public boolean isCallBackCalled;
81     public boolean onCancelCalled;
82     public boolean onKeyDownCalled;
83     public boolean onKeyUpCalled;
84     public boolean onCreateCalled;
85     public boolean onCancelListenerCalled;
86     public boolean onClickCalled;
87     public static boolean onDateChangedCalled;
88     public static boolean onRestoreInstanceStateCalled;
89     public boolean onSaveInstanceStateCalled;
90     public int updatedYear;
91     public int updatedMonth;
92     public int updatedDay;
93 
94     public final int INITIAL_YEAR = 2008;
95     public final int INITIAL_MONTH = 7;
96     public final int INITIAL_DAY_OF_MONTH = 27;
97     private final int INITIAL_HOUR = 10;
98     private final int INITIAL_MINUTE = 35;
99     private Dialog mDialog;
100     private AlertDialog mAlertDialog;
101     private OnDateSetListener mOnDateSetListener = new OnDateSetListener() {
102         public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
103             updatedYear = year;
104             updatedMonth = monthOfYear;
105             updatedDay = dayOfMonth;
106         }
107     };
108 
109     @SuppressWarnings("deprecation")
110     @Override
onCreateDialog(int id)111     protected Dialog onCreateDialog(int id) {
112         switch (id) {
113             case TEST_DIALOG_WITHOUT_THEME:
114                 mDialog = new Dialog(this);
115                 mDialog.setTitle("Hello, Dialog");
116                 break;
117 
118             case TEST_DIALOG_WITH_THEME:
119                 mDialog = new Dialog(this, 1);
120                 break;
121 
122             case TEST_ALERTDIALOG:
123                 mDialog = getAlertDialogInstance(false);
124                 break;
125 
126             case TEST_CUSTOM_ALERTDIALOG:
127                 mDialog = getCustomAlertDialogInstance(false);
128                 break;
129 
130             case TEST_CUSTOM_ALERTDIALOG_VIEW:
131                 mDialog = getCustomAlertDialogInstance(true);
132                 break;
133 
134             case TEST_DATEPICKERDIALOG:
135                 mDialog = new MockDatePickerDialog(this, mOnDateSetListener, INITIAL_YEAR,
136                         INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
137                 break;
138 
139             case TEST_DATEPICKERDIALOG_WITH_THEME:
140                 mDialog = new MockDatePickerDialog(this,
141                         com.android.internal.R.style.Theme_Translucent, mOnDateSetListener,
142                         INITIAL_YEAR, INITIAL_MONTH, INITIAL_DAY_OF_MONTH);
143                 break;
144 
145             case TEST_TIMEPICKERDIALOG:
146                 mDialog = new TimePickerDialog(this, new OnTimeSetListener() {
147                     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
148                         isCallBackCalled = true;
149                     }
150                 }, INITIAL_HOUR, INITIAL_MINUTE, true);
151                 break;
152 
153             case TEST_TIMEPICKERDIALOG_WITH_THEME:
154                 mDialog = new TimePickerDialog(this,
155                         com.android.internal.R.style.Theme_Translucent, null, INITIAL_HOUR,
156                         INITIAL_MINUTE, true);
157                 break;
158 
159             case TEST_ONSTART_AND_ONSTOP:
160                 mDialog = new TestDialog(this);
161                 Log.i(LOG_TAG, "mTestDialog:" + mDialog);
162                 return mDialog;
163 
164             case TEST_ALERTDIALOG_DEPRECATED:
165                 mDialog = getAlertDialogInstance(true);
166                 break;
167 
168             case TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE:
169             case TEST_ALERTDIALOG_WITH_MESSAGE:
170                 final Handler handler = new Handler() {
171                     @Override
172                     public void handleMessage(Message msg) {
173                         buttonIndex = msg.what;
174                         super.handleMessage(msg);
175                     }
176                 };
177                 final Message positiveMessage = Message.obtain();
178                 positiveMessage.setTarget(handler);
179                 positiveMessage.what = DialogInterface.BUTTON_POSITIVE;
180 
181                 final Message negativeMessage = Message.obtain();
182                 negativeMessage.setTarget(handler);
183                 negativeMessage.what = DialogInterface.BUTTON_NEGATIVE;
184 
185                 final Message neutralMessage = Message.obtain();
186                 neutralMessage.setTarget(handler);
187                 neutralMessage.what = DialogInterface.BUTTON_NEUTRAL;
188                 mAlertDialog = getAlertDialogInstance(false);
189                 if (id == TEST_ALERTDIALOG_DEPRECATED_WITH_MESSAGE) {
190                     mAlertDialog.setButton(getString(R.string.alert_dialog_positive),
191                             positiveMessage);
192                     mAlertDialog.setButton2(getString(R.string.alert_dialog_negative),
193                             negativeMessage);
194                     mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral),
195                             neutralMessage);
196                 } else {
197                     mAlertDialog.setButton(AlertDialog.BUTTON_POSITIVE,
198                             getString(R.string.alert_dialog_positive), positiveMessage);
199                     mAlertDialog.setButton(AlertDialog.BUTTON_NEUTRAL,
200                             getString(R.string.alert_dialog_neutral), neutralMessage);
201                     mAlertDialog.setButton(AlertDialog.BUTTON_NEGATIVE,
202                             getString(R.string.alert_dialog_negative), negativeMessage);
203                 }
204                 mDialog = mAlertDialog;
205                 break;
206 
207             case TEST_ALERTDIALOG_CALLBACK:
208                 mDialog = new MockAlertDialog(this);
209                 break;
210             case TEST_ALERTDIALOG_THEME:
211                 mDialog = new MockAlertDialog(this, R.style.Theme_AlertDialog);
212                 break;
213             case TEST_ALERTDIALOG_CANCELABLE:
214                 mDialog = getAlertDialogCancelableInstance(true);
215                 break;
216             case TEST_ALERTDIALOG_NOT_CANCELABLE:
217                 mDialog = getAlertDialogCancelableInstance(false);
218                 break;
219             case TEST_PROTECTED_CANCELABLE:
220                 mDialog = new TestDialog(this, true, new OnCancelListener() {
221                     public void onCancel(DialogInterface dialog) {
222                         onCancelListenerCalled = true;
223                     }
224                 });
225                 break;
226             case TEST_PROTECTED_NOT_CANCELABLE:
227                 mDialog = new TestDialog(this, false, new OnCancelListener() {
228                     public void onCancel(DialogInterface dialog) {
229                         onCancelListenerCalled = true;
230                     }
231                 });
232                 break;
233             case TEST_ALERT_DIALOG_ICON_DRAWABLE:
234                 mAlertDialog = getAlertDialogInstance(false);
235                 mAlertDialog.setIcon(mAlertDialog.getContext().getDrawable(R.drawable.robot));
236                 mDialog = mAlertDialog;
237                 break;
238             case TEST_ALERT_DIALOG_ICON_ATTRIBUTE:
239                 mAlertDialog = getAlertDialogInstance(false);
240                 mAlertDialog.setIconAttribute(android.R.attr.alertDialogIcon);
241                 mDialog = mAlertDialog;
242                 break;
243 
244             default:
245                 break;
246         }
247 
248         Log.i(LOG_TAG, "mDialog:" + mDialog);
249         return mDialog;
250     }
251 
getAlertDialogCancelableInstance(boolean cancelable)252     private AlertDialog getAlertDialogCancelableInstance(boolean cancelable) {
253         OnCancelListener cancelListener = new OnCancelListener() {
254             public void onCancel(DialogInterface dialog) {
255                 onCancelCalled = true;
256             }
257         };
258         return new MockAlertDialog(this, cancelable, cancelListener);
259     }
260 
261     @SuppressWarnings("deprecation")
getAlertDialogInstance(boolean deprecated)262     private AlertDialog getAlertDialogInstance(boolean deprecated) {
263         mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
264         mAlertDialog.setIcon(R.drawable.pass);
265         mAlertDialog.setTitle(DEFAULT_ALERTDIALOG_TITLE);
266         mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
267         mAlertDialog.setInverseBackgroundForced(true);
268         final DialogInterface.OnClickListener positiveListener = new MockOnClickListener(
269                 DialogInterface.BUTTON_POSITIVE);
270         final DialogInterface.OnClickListener netativeListener = new MockOnClickListener(
271                 DialogInterface.BUTTON_NEGATIVE);
272         final DialogInterface.OnClickListener neutralListener = new MockOnClickListener(
273                 DialogInterface.BUTTON_NEUTRAL);
274 
275         if (deprecated) {
276             mAlertDialog.setButton(getString(R.string.alert_dialog_positive), positiveListener);
277             mAlertDialog.setButton2(getString(R.string.alert_dialog_negative), netativeListener);
278             mAlertDialog.setButton3(getString(R.string.alert_dialog_neutral), neutralListener);
279         } else {
280             mAlertDialog.setButton(DialogInterface.BUTTON_POSITIVE,
281                     getString(R.string.alert_dialog_positive), positiveListener);
282             mAlertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
283                     getString(R.string.alert_dialog_negative), netativeListener);
284             mAlertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
285                     getString(R.string.alert_dialog_neutral), neutralListener);
286         }
287         return mAlertDialog;
288 
289     }
290 
getCustomAlertDialogInstance(boolean withSpacing)291     private AlertDialog getCustomAlertDialogInstance(boolean withSpacing) {
292         final LayoutInflater inflate = getLayoutInflater();
293         final View customTitleViewCustom = inflate.inflate(R.layout.alertdialog_custom_title, null);
294         final View textEntryView = inflate.inflate(R.layout.alert_dialog_text_entry_2, null);
295         mAlertDialog = new AlertDialog.Builder(DialogStubActivity.this).create();
296         mAlertDialog.setCustomTitle(customTitleViewCustom);
297         mAlertDialog.setMessage(DEFAULT_ALERTDIALOG_MESSAGE);
298         if (withSpacing) {
299             mAlertDialog.setView(textEntryView, SPACING_LEFT, SPACING_TOP, SPACING_RIGHT,
300                     SPACING_BOTTOM);
301         } else {
302             mAlertDialog.setView(textEntryView);
303         }
304 
305         return mAlertDialog;
306 
307     }
308 
getDialog()309     public Dialog getDialog() {
310         return mDialog;
311     }
312 
getDialogTitle()313     public String getDialogTitle() {
314         return (String) mDialog.getWindow().getAttributes().getTitle();
315     }
316 
317     private static final String TEST_DIALOG_NUMBER_EXTRA = "testDialogNumber";
318 
startDialogActivity( ActivityInstrumentationTestCase2<T> testCase, int dialogNumber)319     public static <T extends Activity> T startDialogActivity(
320             ActivityInstrumentationTestCase2<T> testCase, int dialogNumber) {
321         Intent intent = new Intent(Intent.ACTION_MAIN);
322         intent.putExtra(TEST_DIALOG_NUMBER_EXTRA, dialogNumber);
323         testCase.setActivityIntent(intent);
324         return testCase.getActivity();
325     }
326 
327     @Override
onCreate(Bundle savedInstanceState)328     protected void onCreate(Bundle savedInstanceState) {
329         super.onCreate(savedInstanceState);
330 
331         setContentView(R.layout.dialog_stub_layout);
332 
333         Intent intent = getIntent();
334         int dialogNum = intent.getIntExtra(TEST_DIALOG_NUMBER_EXTRA, -1);
335         if (dialogNum != -1) {
336             showDialog(dialogNum);
337         }
338     }
339 
setUpTitle(final String title)340     public void setUpTitle(final String title) {
341         runOnUiThread(new Runnable() {
342             public void run() {
343                 getDialog().setTitle(title);
344             }
345         });
346     }
347 
setUpTitle(final int id)348     public void setUpTitle(final int id) {
349         runOnUiThread(new Runnable() {
350             public void run() {
351                 getDialog().setTitle(id);
352             }
353         });
354     }
355 
356     class MockAlertDialog extends AlertDialog {
MockAlertDialog(Context context)357         public MockAlertDialog(Context context) {
358             super(context);
359         }
360 
MockAlertDialog(Context context, int theme)361         public MockAlertDialog(Context context, int theme) {
362             super(context, theme);
363         }
364 
MockAlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener)365         public MockAlertDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
366             super(context, cancelable, cancelListener);
367         }
368 
369         @Override
onKeyDown(int keyCode, KeyEvent event)370         public boolean onKeyDown(int keyCode, KeyEvent event) {
371             onKeyDownCalled = true;
372             return super.onKeyDown(keyCode, event);
373         }
374 
375         @Override
onKeyUp(int keyCode, KeyEvent event)376         public boolean onKeyUp(int keyCode, KeyEvent event) {
377             onKeyUpCalled = true;
378             return super.onKeyUp(keyCode, event);
379         }
380 
381         @Override
onCreate(Bundle savedInstanceState)382         protected void onCreate(Bundle savedInstanceState) {
383             onCreateCalled = true;
384             super.onCreate(savedInstanceState);
385         }
386 
387     }
388 
389     class MockOnClickListener implements DialogInterface.OnClickListener {
390         private final int mId;
391 
MockOnClickListener(final int buttonId)392         public MockOnClickListener(final int buttonId) {
393             mId = buttonId;
394         }
395 
onClick(DialogInterface dialog, int which)396         public void onClick(DialogInterface dialog, int which) {
397             switch (mId) {
398                 case DialogInterface.BUTTON_POSITIVE:
399                     isPositiveButtonClicked = true;
400                     break;
401                 case DialogInterface.BUTTON_NEGATIVE:
402                     isNegativeButtonClicked = true;
403                     break;
404                 case DialogInterface.BUTTON_NEUTRAL:
405                     isNeutralButtonClicked = true;
406                     break;
407                 default:
408                     break;
409             }
410         }
411     }
412 
413     class MockDatePickerDialog extends DatePickerDialog {
MockDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)414         public MockDatePickerDialog(Context context, OnDateSetListener callBack, int year,
415                 int monthOfYear, int dayOfMonth) {
416             super(context, callBack, year, monthOfYear, dayOfMonth);
417         }
418 
MockDatePickerDialog(Context context, int theme, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth)419         public MockDatePickerDialog(Context context, int theme, OnDateSetListener callBack,
420                 int year, int monthOfYear, int dayOfMonth) {
421             super(context, theme, callBack, year, monthOfYear, dayOfMonth);
422         }
423 
424         @Override
onClick(DialogInterface dialog, int which)425         public void onClick(DialogInterface dialog, int which) {
426             onClickCalled = true;
427             super.onClick(dialog, which);
428         }
429 
430         @Override
onDateChanged(DatePicker view, int year, int month, int day)431         public void onDateChanged(DatePicker view, int year, int month, int day) {
432             onDateChangedCalled = true;
433             super.onDateChanged(view, year, month, day);
434         }
435 
436         @Override
onRestoreInstanceState(Bundle savedInstanceState)437         public void onRestoreInstanceState(Bundle savedInstanceState) {
438             onRestoreInstanceStateCalled = true;
439             super.onRestoreInstanceState(savedInstanceState);
440         }
441 
442         @Override
onSaveInstanceState()443         public Bundle onSaveInstanceState() {
444             onSaveInstanceStateCalled = true;
445             return super.onSaveInstanceState();
446         }
447 
448     }
449 }
450