Home | History | Annotate | Download | only in data
      1 /*
      2  * Copyright (C) 2016 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 com.android.deskclock.data;
     18 
     19 import android.app.Notification;
     20 import android.app.PendingIntent;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.res.Resources;
     24 import android.os.SystemClock;
     25 import android.support.annotation.DrawableRes;
     26 import android.support.annotation.StringRes;
     27 import android.support.v4.app.NotificationCompat;
     28 import android.support.v4.app.NotificationCompat.Action;
     29 import android.support.v4.app.NotificationCompat.Builder;
     30 import android.support.v4.content.ContextCompat;
     31 import android.widget.RemoteViews;
     32 
     33 import com.android.deskclock.R;
     34 import com.android.deskclock.Utils;
     35 import com.android.deskclock.events.Events;
     36 import com.android.deskclock.stopwatch.StopwatchService;
     37 
     38 import java.util.ArrayList;
     39 import java.util.List;
     40 
     41 import static android.view.View.GONE;
     42 import static android.view.View.VISIBLE;
     43 
     44 /**
     45  * Builds notification to reflect the latest state of the stopwatch and recorded laps.
     46  */
     47 class StopwatchNotificationBuilder {
     48 
     49     public Notification build(Context context, NotificationModel nm, Stopwatch stopwatch) {
     50         @StringRes final int eventLabel = R.string.label_notification;
     51 
     52         // Intent to load the app when the notification is tapped.
     53         final Intent showApp = new Intent(context, StopwatchService.class)
     54                 .setAction(StopwatchService.ACTION_SHOW_STOPWATCH)
     55                 .putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);
     56 
     57         final PendingIntent pendingShowApp = PendingIntent.getService(context, 0, showApp,
     58                 PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
     59 
     60         // Compute some values required below.
     61         final boolean running = stopwatch.isRunning();
     62         final String pname = context.getPackageName();
     63         final Resources res = context.getResources();
     64         final long base = SystemClock.elapsedRealtime() - stopwatch.getTotalTime();
     65 
     66         final RemoteViews content = new RemoteViews(pname, R.layout.chronometer_notif_content);
     67         content.setChronometer(R.id.chronometer, base, null, running);
     68 
     69         final List<Action> actions = new ArrayList<>(2);
     70 
     71         if (running) {
     72             // Left button: Pause
     73             final Intent pause = new Intent(context, StopwatchService.class)
     74                     .setAction(StopwatchService.ACTION_PAUSE_STOPWATCH)
     75                     .putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);
     76 
     77             @DrawableRes final int icon1 = R.drawable.ic_pause_24dp;
     78             final CharSequence title1 = res.getText(R.string.sw_pause_button);
     79             final PendingIntent intent1 = Utils.pendingServiceIntent(context, pause);
     80             actions.add(new Action.Builder(icon1, title1, intent1).build());
     81 
     82             // Right button: Add Lap
     83             if (DataModel.getDataModel().canAddMoreLaps()) {
     84                 final Intent lap = new Intent(context, StopwatchService.class)
     85                         .setAction(StopwatchService.ACTION_LAP_STOPWATCH)
     86                         .putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);
     87 
     88                 @DrawableRes final int icon2 = R.drawable.ic_sw_lap_24dp;
     89                 final CharSequence title2 = res.getText(R.string.sw_lap_button);
     90                 final PendingIntent intent2 = Utils.pendingServiceIntent(context, lap);
     91                 actions.add(new Action.Builder(icon2, title2, intent2).build());
     92             }
     93 
     94             // Show the current lap number if any laps have been recorded.
     95             final int lapCount = DataModel.getDataModel().getLaps().size();
     96             if (lapCount > 0) {
     97                 final int lapNumber = lapCount + 1;
     98                 final String lap = res.getString(R.string.sw_notification_lap_number, lapNumber);
     99                 content.setTextViewText(R.id.state, lap);
    100                 content.setViewVisibility(R.id.state, VISIBLE);
    101             } else {
    102                 content.setViewVisibility(R.id.state, GONE);
    103             }
    104         } else {
    105             // Left button: Start
    106             final Intent start = new Intent(context, StopwatchService.class)
    107                     .setAction(StopwatchService.ACTION_START_STOPWATCH)
    108                     .putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);
    109 
    110             @DrawableRes final int icon1 = R.drawable.ic_start_24dp;
    111             final CharSequence title1 = res.getText(R.string.sw_start_button);
    112             final PendingIntent intent1 = Utils.pendingServiceIntent(context, start);
    113             actions.add(new Action.Builder(icon1, title1, intent1).build());
    114 
    115             // Right button: Reset (dismisses notification and resets stopwatch)
    116             final Intent reset = new Intent(context, StopwatchService.class)
    117                     .setAction(StopwatchService.ACTION_RESET_STOPWATCH)
    118                     .putExtra(Events.EXTRA_EVENT_LABEL, eventLabel);
    119 
    120             @DrawableRes final int icon2 = R.drawable.ic_reset_24dp;
    121             final CharSequence title2 = res.getText(R.string.sw_reset_button);
    122             final PendingIntent intent2 = Utils.pendingServiceIntent(context, reset);
    123             actions.add(new Action.Builder(icon2, title2, intent2).build());
    124 
    125             // Indicate the stopwatch is paused.
    126             content.setTextViewText(R.id.state, res.getString(R.string.swn_paused));
    127             content.setViewVisibility(R.id.state, VISIBLE);
    128         }
    129 
    130         final Builder notification = new NotificationCompat.Builder(context)
    131                 .setLocalOnly(true)
    132                 .setOngoing(running)
    133                 .setCustomContentView(content)
    134                 .setContentIntent(pendingShowApp)
    135                 .setAutoCancel(stopwatch.isPaused())
    136                 .setPriority(Notification.PRIORITY_MAX)
    137                 .setSmallIcon(R.drawable.stat_notify_stopwatch)
    138                 .setStyle(new NotificationCompat.DecoratedCustomViewStyle())
    139                 .setColor(ContextCompat.getColor(context, R.color.default_background));
    140 
    141         if (Utils.isNOrLater()) {
    142             notification.setGroup(nm.getStopwatchNotificationGroupKey());
    143         }
    144 
    145         for (Action action : actions) {
    146             notification.addAction(action);
    147         }
    148 
    149         return notification.build();
    150     }
    151 }
    152