1/*
2 * Copyright (C) 2010 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
17package com.android.statusbartest;
18
19import java.util.GregorianCalendar;
20
21import android.app.Activity;
22import android.app.Notification;
23import android.app.NotificationManager;
24import android.app.PendingIntent;
25import android.content.Context;
26import android.content.ContentResolver;
27import android.content.Intent;
28import android.graphics.Bitmap;
29import android.graphics.drawable.BitmapDrawable;
30import android.net.Uri;
31import android.os.Bundle;
32import android.os.Environment;
33import android.os.Handler;
34import android.os.Vibrator;
35import android.os.Handler;
36import android.text.SpannableStringBuilder;
37import android.text.TextUtils;
38import android.util.Log;
39import android.net.Uri;
40import android.os.SystemClock;
41import android.view.View;
42import android.widget.CompoundButton;
43import android.widget.RadioButton;
44import android.widget.RadioGroup;
45import android.widget.RemoteViews;
46import android.os.PowerManager;
47
48public class NotificationBuilderTest extends Activity
49{
50    private final static String TAG = "NotificationTestList";
51
52    NotificationManager mNM;
53    Handler mHandler;
54    int mStartDelay;
55
56    @Override
57    public void onCreate(Bundle icicle) {
58        super.onCreate(icicle);
59        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
60        mHandler = new Handler();
61        setContentView(R.layout.notification_builder_test);
62        if (icicle == null) {
63            setDefaults();
64        }
65        for (int id: new int[] {
66                    R.id.clear_1,
67                    R.id.clear_2,
68                    R.id.clear_3,
69                    R.id.clear_4,
70                    R.id.clear_5,
71                    R.id.clear_6,
72                    R.id.clear_7,
73                    R.id.clear_8,
74                    R.id.clear_9,
75                    R.id.clear_10,
76                    R.id.notify_1,
77                    R.id.notify_2,
78                    R.id.notify_3,
79                    R.id.notify_4,
80                    R.id.notify_5,
81                    R.id.notify_6,
82                    R.id.notify_7,
83                    R.id.notify_8,
84                    R.id.notify_9,
85                    R.id.notify_10,
86                    R.id.ten,
87                    R.id.clear_all,
88                }) {
89            findViewById(id).setOnClickListener(mClickListener);
90        }
91    }
92
93    private void setDefaults() {
94        setChecked(R.id.when_now);
95        setChecked(R.id.icon_surprise);
96        setChecked(R.id.title_medium);
97        setChecked(R.id.text_medium);
98        setChecked(R.id.info_none);
99        setChecked(R.id.number_0);
100        setChecked(R.id.intent_alert);
101        setChecked(R.id.delete_none);
102        setChecked(R.id.full_screen_none);
103        setChecked(R.id.ticker_none);
104        setChecked(R.id.large_icon_none);
105        setChecked(R.id.sound_none);
106        setChecked(R.id.vibrate_none);
107        setChecked(R.id.pri_default);
108        setChecked(R.id.lights_red);
109        setChecked(R.id.lights_off);
110        setChecked(R.id.delay_none);
111//        setChecked(R.id.default_vibrate);
112//        setChecked(R.id.default_sound);
113//        setChecked(R.id.default_lights);
114    }
115
116    private View.OnClickListener mClickListener = new View.OnClickListener() {
117        public void onClick(View v) {
118            switch (v.getId()) {
119                case R.id.clear_1:
120                    mNM.cancel(1);
121                    break;
122                case R.id.clear_2:
123                    mNM.cancel(2);
124                    break;
125                case R.id.clear_3:
126                    mNM.cancel(3);
127                    break;
128                case R.id.clear_4:
129                    mNM.cancel(4);
130                    break;
131                case R.id.clear_5:
132                    mNM.cancel(5);
133                    break;
134                case R.id.clear_6:
135                    mNM.cancel(6);
136                    break;
137                case R.id.clear_7:
138                    mNM.cancel(7);
139                    break;
140                case R.id.clear_8:
141                    mNM.cancel(8);
142                    break;
143                case R.id.clear_9:
144                    mNM.cancel(9);
145                    break;
146                case R.id.clear_10:
147                    mNM.cancel(10);
148                    break;
149                case R.id.notify_1:
150                    sendNotification(1);
151                    break;
152                case R.id.notify_2:
153                    sendNotification(2);
154                    break;
155                case R.id.notify_3:
156                    sendNotification(3);
157                    break;
158                case R.id.notify_4:
159                    sendNotification(4);
160                    break;
161                case R.id.notify_5:
162                    sendNotification(5);
163                    break;
164                case R.id.notify_6:
165                    sendNotification(6);
166                    break;
167                case R.id.notify_7:
168                    sendNotification(7);
169                    break;
170                case R.id.notify_8:
171                    sendNotification(8);
172                    break;
173                case R.id.notify_9:
174                    sendNotification(9);
175                    break;
176                case R.id.notify_10:
177                    sendNotification(10);
178                    break;
179                case R.id.ten: {
180                    for (int id=1; id<=10; id++) {
181                        sendNotification(id);
182                    }
183                    break;
184                }
185                case R.id.clear_all: {
186                    for (int id=1; id<=10; id++) {
187                        mNM.cancel(id);
188                    }
189                    break;
190                }
191            }
192        }
193    };
194
195    private void sendNotification(final int id) {
196        final Notification n = buildNotification(id);
197        mHandler.postDelayed(new Runnable() {
198            public void run() {
199                mNM.notify(id, n);
200            }
201        }, mStartDelay);
202    }
203
204    private static CharSequence subst(CharSequence in, char ch, CharSequence sub) {
205        int i=0;
206        SpannableStringBuilder edit = new SpannableStringBuilder(in);
207        while (i<edit.length()) {
208            if (edit.charAt(i) == ch) {
209                edit.replace(i, i+1, sub);
210                i += sub.length();
211            } else {
212                i ++;
213            }
214        }
215        return edit;
216    }
217
218    private Notification buildNotification(int id) {
219        Notification.Builder b = new Notification.Builder(this);
220
221        // when
222        switch (getRadioChecked(R.id.group_when)) {
223            case R.id.when_midnight: {
224                GregorianCalendar c = new GregorianCalendar();
225                c.set(GregorianCalendar.HOUR_OF_DAY, 0);
226                c.set(GregorianCalendar.MINUTE, 0);
227                c.set(GregorianCalendar.SECOND, 0);
228                b.setWhen(c.getTimeInMillis());
229                break;
230            }
231            case R.id.when_now:
232                b.setWhen(System.currentTimeMillis());
233                break;
234            case R.id.when_now_plus_1h:
235                break;
236            case R.id.when_tomorrow:
237                break;
238        }
239
240        // icon
241        switch (getRadioChecked(R.id.group_icon)) {
242            case R.id.icon_im:
243                b.setSmallIcon(R.drawable.icon1);
244                break;
245            case R.id.icon_alert:
246                b.setSmallIcon(R.drawable.icon2);
247                break;
248            case R.id.icon_surprise:
249                b.setSmallIcon(R.drawable.emo_im_kissing);
250                break;
251        }
252
253        // title
254        final CharSequence title = getRadioTag(R.id.group_title);
255        if (!TextUtils.isEmpty(title)) {
256            b.setContentTitle(title);
257        }
258
259        // text
260        final CharSequence text = getRadioTag(R.id.group_text);
261        if (!TextUtils.isEmpty(text)) {
262            if (getRadioChecked(R.id.group_text) == R.id.text_emoji) {
263                // UTF-16 for +1F335
264                b.setContentText(subst(text,
265                        '_', "\ud83c\udf35"));
266            } else {
267                b.setContentText(text);
268            }
269        }
270
271        // info
272        final CharSequence info = getRadioTag(R.id.group_info);
273        if (!TextUtils.isEmpty(info)) {
274            b.setContentInfo(info);
275        }
276
277        // number
278        b.setNumber(getRadioInt(R.id.group_number, 0));
279
280        // contentIntent
281        switch (getRadioChecked(R.id.group_intent)) {
282            case R.id.intent_none:
283                break;
284            case R.id.intent_alert:
285                b.setContentIntent(makeContentIntent(id));
286                break;
287        }
288
289        // deleteIntent
290        switch (getRadioChecked(R.id.group_delete)) {
291            case R.id.delete_none:
292                break;
293            case R.id.delete_alert:
294                b.setDeleteIntent(makeDeleteIntent(id));
295                break;
296        }
297
298        // fullScreenIntent TODO
299
300        // ticker
301        switch (getRadioChecked(R.id.group_ticker)) {
302            case R.id.ticker_none:
303                break;
304            case R.id.ticker_short:
305            case R.id.ticker_wrap:
306            case R.id.ticker_haiku:
307                b.setTicker(getRadioTag(R.id.group_ticker));
308                break;
309            case R.id.ticker_emoji:
310                // UTF-16 for +1F335
311                b.setTicker(subst(getRadioTag(R.id.group_ticker),
312                        '_', "\ud83c\udf35"));
313                break;
314            case R.id.ticker_custom:
315                // TODO
316                break;
317        }
318
319        // largeIcon
320        switch (getRadioChecked(R.id.group_large_icon)) {
321            case R.id.large_icon_none:
322                break;
323            case R.id.large_icon_pineapple:
324                b.setLargeIcon(loadBitmap(R.drawable.pineapple));
325                break;
326            case R.id.large_icon_pineapple2:
327                b.setLargeIcon(loadBitmap(R.drawable.pineapple2));
328                break;
329            case R.id.large_icon_small:
330                b.setLargeIcon(loadBitmap(R.drawable.icon2));
331                break;
332        }
333
334        // sound TODO
335
336        // vibrate
337        switch (getRadioChecked(R.id.group_vibrate)) {
338            case R.id.vibrate_none:
339                b.setVibrate(null);
340                break;
341            case R.id.vibrate_zero:
342                b.setVibrate(new long[] { 0 });
343                break;
344            case R.id.vibrate_short:
345                b.setVibrate(new long[] { 0, 100 });
346                break;
347            case R.id.vibrate_long:
348                b.setVibrate(new long[] { 0, 1000 });
349                break;
350            case R.id.vibrate_pattern:
351                b.setVibrate(new long[] { 0, 50,  200, 50,  200, 50,  500,
352                                             500, 200, 500, 200, 500, 500,
353                                             50,  200, 50,  200, 50        });
354                break;
355        }
356
357        // lights
358        final int color = getRadioHex(R.id.group_lights_color, 0xff0000);
359        int onMs;
360        int offMs;
361        switch (getRadioChecked(R.id.group_lights_blink)) {
362            case R.id.lights_slow:
363                onMs = 1300;
364                offMs = 1300;
365                break;
366            case R.id.lights_fast:
367                onMs = 300;
368                offMs = 300;
369                break;
370            case R.id.lights_on:
371                onMs = 1;
372                offMs = 0;
373                break;
374            case R.id.lights_off:
375            default:
376                onMs = 0;
377                offMs = 0;
378                break;
379        }
380        if (onMs != 0 && offMs != 0) {
381            b.setLights(color, onMs, offMs);
382        }
383
384        // priority
385        switch (getRadioChecked(R.id.group_priority)) {
386            case R.id.pri_min:
387                b.setPriority(Notification.PRIORITY_MIN);
388                break;
389            case R.id.pri_low:
390                b.setPriority(Notification.PRIORITY_LOW);
391                break;
392            case R.id.pri_default:
393                b.setPriority(Notification.PRIORITY_DEFAULT);
394                break;
395            case R.id.pri_high:
396                b.setPriority(Notification.PRIORITY_HIGH);
397                break;
398            case R.id.pri_max:
399                b.setPriority(Notification.PRIORITY_MAX);
400                break;
401        }
402
403        // start delay
404        switch (getRadioChecked(R.id.group_delay)) {
405            case R.id.delay_none:
406                mStartDelay = 0;
407                break;
408            case R.id.delay_5:
409                mStartDelay = 5000;
410                break;
411        }
412
413        // flags
414        b.setOngoing(getChecked(R.id.flag_ongoing));
415        b.setOnlyAlertOnce(getChecked(R.id.flag_once));
416        b.setAutoCancel(getChecked(R.id.flag_auto_cancel));
417
418        // defaults
419        int defaults = 0;
420        if (getChecked(R.id.default_sound)) {
421            defaults |= Notification.DEFAULT_SOUND;
422        }
423        if (getChecked(R.id.default_vibrate)) {
424            defaults |= Notification.DEFAULT_VIBRATE;
425        }
426        if (getChecked(R.id.default_lights)) {
427            defaults |= Notification.DEFAULT_LIGHTS;
428        }
429        b.setDefaults(defaults);
430
431        return b.build();
432    }
433
434    private void setChecked(int id) {
435        final CompoundButton b = (CompoundButton)findViewById(id);
436        b.setChecked(true);
437    }
438
439    private int getRadioChecked(int id) {
440        final RadioGroup g = (RadioGroup)findViewById(id);
441        return g.getCheckedRadioButtonId();
442    }
443
444    private String getRadioTag(int id) {
445        final RadioGroup g = (RadioGroup)findViewById(id);
446        final View v = findViewById(g.getCheckedRadioButtonId());
447        return (String) v.getTag();
448    }
449
450    private int getRadioInt(int id, int def) {
451        String str = getRadioTag(id);
452        if (TextUtils.isEmpty(str)) {
453            return def;
454        } else {
455            try {
456                return Integer.parseInt(str.toString());
457            } catch (NumberFormatException ex) {
458                return def;
459            }
460        }
461    }
462
463    private int getRadioHex(int id, int def) {
464        String str = getRadioTag(id);
465        if (TextUtils.isEmpty(str)) {
466            return def;
467        } else {
468            if (str.startsWith("0x")) {
469                str = str.substring(2);
470            }
471            try {
472                return Integer.parseInt(str.toString(), 16);
473            } catch (NumberFormatException ex) {
474                return def;
475            }
476        }
477    }
478
479    private boolean getChecked(int id) {
480        final CompoundButton b = (CompoundButton)findViewById(id);
481        return b.isChecked();
482    }
483
484    private Bitmap loadBitmap(int id) {
485        final BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(id);
486        return Bitmap.createBitmap(bd.getBitmap());
487    }
488
489    private PendingIntent makeDeleteIntent(int id) {
490        Intent intent = new Intent(this, ConfirmationActivity.class);
491        intent.setData(Uri.fromParts("content", "//status_bar_test/delete/" + id, null));
492        intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Delete intent");
493        intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
494        return PendingIntent.getActivity(this, 0, intent, 0);
495    }
496
497    private PendingIntent makeContentIntent(int id) {
498        Intent intent = new Intent(this, ConfirmationActivity.class);
499        intent.setData(Uri.fromParts("content", "//status_bar_test/content/" + id, null));
500        intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Content intent");
501        intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
502        return PendingIntent.getActivity(this, 0, intent, 0);
503    }
504}
505
506