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
17package com.android.deskclock.controller;
18
19import android.annotation.TargetApi;
20import android.content.ComponentName;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ShortcutInfo;
24import android.content.pm.ShortcutManager;
25import android.graphics.drawable.Icon;
26import android.os.Build;
27import android.os.UserManager;
28import android.provider.AlarmClock;
29import android.support.annotation.StringRes;
30
31import com.android.deskclock.DeskClock;
32import com.android.deskclock.HandleApiCalls;
33import com.android.deskclock.HandleShortcuts;
34import com.android.deskclock.LogUtils;
35import com.android.deskclock.R;
36import com.android.deskclock.ScreensaverActivity;
37import com.android.deskclock.data.DataModel;
38import com.android.deskclock.data.Lap;
39import com.android.deskclock.data.Stopwatch;
40import com.android.deskclock.data.StopwatchListener;
41import com.android.deskclock.events.Events;
42import com.android.deskclock.events.ShortcutEventTracker;
43import com.android.deskclock.stopwatch.StopwatchService;
44import com.android.deskclock.uidata.UiDataModel;
45
46import java.util.Arrays;
47import java.util.Collections;
48
49@TargetApi(Build.VERSION_CODES.N_MR1)
50class ShortcutController {
51
52    private final Context mContext;
53    private final ComponentName mComponentName;
54    private final ShortcutManager mShortcutManager;
55    private final UserManager mUserManager;
56
57    ShortcutController(Context context) {
58        mContext = context;
59        mComponentName = new ComponentName(mContext, DeskClock.class);
60        mShortcutManager = mContext.getSystemService(ShortcutManager.class);
61        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
62        Controller.getController().addEventTracker(new ShortcutEventTracker(mContext));
63        DataModel.getDataModel().addStopwatchListener(new StopwatchWatcher());
64    }
65
66    void updateShortcuts() {
67        if (!mUserManager.isUserUnlocked()) {
68            LogUtils.i("Skipping shortcut update because user is locked.");
69            return;
70        }
71        try {
72            final ShortcutInfo alarm = createNewAlarmShortcut();
73            final ShortcutInfo timer = createNewTimerShortcut();
74            final ShortcutInfo stopwatch = createStopwatchShortcut();
75            final ShortcutInfo screensaver = createScreensaverShortcut();
76            mShortcutManager.setDynamicShortcuts(
77                    Arrays.asList(alarm, timer, stopwatch, screensaver));
78        } catch (IllegalStateException e) {
79            LogUtils.wtf(e);
80        }
81    }
82
83    private ShortcutInfo createNewAlarmShortcut() {
84        final Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
85                .setClass(mContext, HandleApiCalls.class)
86                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
87                .putExtra(Events.EXTRA_EVENT_LABEL, R.string.label_shortcut);
88        final String setAlarmShortcut = UiDataModel.getUiDataModel()
89                .getShortcutId(R.string.category_alarm, R.string.action_create);
90        return new ShortcutInfo.Builder(mContext, setAlarmShortcut)
91                .setIcon(Icon.createWithResource(mContext, R.drawable.shortcut_new_alarm))
92                .setActivity(mComponentName)
93                .setShortLabel(mContext.getString(R.string.shortcut_new_alarm_short))
94                .setLongLabel(mContext.getString(R.string.shortcut_new_alarm_long))
95                .setIntent(intent)
96                .setRank(0)
97                .build();
98    }
99
100    private ShortcutInfo createNewTimerShortcut() {
101        final Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
102                .setClass(mContext, HandleApiCalls.class)
103                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
104                .putExtra(Events.EXTRA_EVENT_LABEL, R.string.label_shortcut);
105        final String setTimerShortcut = UiDataModel.getUiDataModel()
106                .getShortcutId(R.string.category_timer, R.string.action_create);
107        return new ShortcutInfo.Builder(mContext, setTimerShortcut)
108                .setIcon(Icon.createWithResource(mContext, R.drawable.shortcut_new_timer))
109                .setActivity(mComponentName)
110                .setShortLabel(mContext.getString(R.string.shortcut_new_timer_short))
111                .setLongLabel(mContext.getString(R.string.shortcut_new_timer_long))
112                .setIntent(intent)
113                .setRank(1)
114                .build();
115    }
116
117    private ShortcutInfo createStopwatchShortcut() {
118        final @StringRes int action = DataModel.getDataModel().getStopwatch().isRunning()
119                ? R.string.action_pause : R.string.action_start;
120        final String shortcutId = UiDataModel.getUiDataModel()
121                .getShortcutId(R.string.category_stopwatch, action);
122        final ShortcutInfo.Builder shortcut = new ShortcutInfo.Builder(mContext, shortcutId)
123                .setIcon(Icon.createWithResource(mContext, R.drawable.shortcut_stopwatch))
124                .setActivity(mComponentName)
125                .setRank(2);
126        final Intent intent;
127        if (DataModel.getDataModel().getStopwatch().isRunning()) {
128            intent = new Intent(StopwatchService.ACTION_PAUSE_STOPWATCH)
129                    .putExtra(Events.EXTRA_EVENT_LABEL, R.string.label_shortcut);
130            shortcut.setShortLabel(mContext.getString(R.string.shortcut_pause_stopwatch_short))
131                    .setLongLabel(mContext.getString(R.string.shortcut_pause_stopwatch_long));
132        } else {
133            intent = new Intent(StopwatchService.ACTION_START_STOPWATCH)
134                    .putExtra(Events.EXTRA_EVENT_LABEL, R.string.label_shortcut);
135            shortcut.setShortLabel(mContext.getString(R.string.shortcut_start_stopwatch_short))
136                    .setLongLabel(mContext.getString(R.string.shortcut_start_stopwatch_long));
137        }
138        intent.setClass(mContext, HandleShortcuts.class)
139                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
140        return shortcut
141                .setIntent(intent)
142                .build();
143    }
144
145    private ShortcutInfo createScreensaverShortcut() {
146        final Intent intent = new Intent(Intent.ACTION_MAIN)
147                .setClass(mContext, ScreensaverActivity.class)
148                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
149                .putExtra(Events.EXTRA_EVENT_LABEL, R.string.label_shortcut);
150        final String screensaverShortcut = UiDataModel.getUiDataModel()
151                .getShortcutId(R.string.category_screensaver, R.string.action_show);
152        return new ShortcutInfo.Builder(mContext, screensaverShortcut)
153                .setIcon(Icon.createWithResource(mContext, R.drawable.shortcut_screensaver))
154                .setActivity(mComponentName)
155                .setShortLabel((mContext.getString(R.string.shortcut_start_screensaver_short)))
156                .setLongLabel((mContext.getString(R.string.shortcut_start_screensaver_long)))
157                .setIntent(intent)
158                .setRank(3)
159                .build();
160    }
161
162    private class StopwatchWatcher implements StopwatchListener {
163
164        @Override
165        public void stopwatchUpdated(Stopwatch before, Stopwatch after) {
166            if (!mUserManager.isUserUnlocked()) {
167                LogUtils.i("Skipping stopwatch shortcut update because user is locked.");
168                return;
169            }
170            try {
171                mShortcutManager.updateShortcuts(
172                        Collections.singletonList(createStopwatchShortcut()));
173            } catch (IllegalStateException e) {
174                LogUtils.wtf(e);
175            }
176        }
177
178        @Override
179        public void lapAdded(Lap lap) {
180        }
181    }
182}
183