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