1 /* 2 * Copyright (C) 2021 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 package com.android.calendar.alerts 17 18 import android.app.Notification 19 import android.app.NotificationManager 20 import android.app.Service 21 import android.content.Intent 22 import android.os.IBinder 23 import android.os.Looper 24 import android.provider.CalendarContract.CalendarAlerts 25 import java.util.ArrayList 26 27 /** 28 * This service is used to handle calendar event reminders. 29 */ 30 class AlertService : Service() { 31 @Volatile 32 private var mServiceLooper: Looper? = null 33 34 // Added wrapper for testing 35 class NotificationWrapper { 36 var mNotification: Notification 37 var mEventId: Long = 0 38 var mBegin: Long = 0 39 var mEnd: Long = 0 40 var mNw: ArrayList<NotificationWrapper>? = null 41 42 constructor( 43 n: Notification, 44 notificationId: Int, 45 eventId: Long, 46 startMillis: Long, 47 endMillis: Long, 48 doPopup: Boolean 49 ) { 50 mNotification = n 51 mEventId = eventId 52 mBegin = startMillis 53 mEnd = endMillis 54 55 // popup? 56 // notification id? 57 } 58 59 constructor(n: Notification) { 60 mNotification = n 61 } 62 addnull63 fun add(nw: NotificationWrapper?) { 64 val temp = mNw 65 if (temp == null) { 66 mNw = ArrayList<NotificationWrapper>() 67 } 68 mNw?.add(nw as AlertService.NotificationWrapper) 69 } 70 } 71 72 // Added wrapper for testing 73 class NotificationMgrWrapper(nm: NotificationManager) : NotificationMgr() { 74 var mNm: NotificationManager 75 @Override cancelnull76 override fun cancel(id: Int) { 77 mNm.cancel(id) 78 } 79 80 @Override notifynull81 override fun notify(id: Int, nw: NotificationWrapper?) { 82 mNm.notify(id, nw?.mNotification) 83 } 84 85 init { 86 mNm = nm 87 } 88 } 89 90 internal class NotificationInfo( 91 var eventName: String, 92 var location: String, 93 var description: String, 94 var startMillis: Long, 95 var endMillis: Long, 96 var eventId: Long, 97 var allDay: Boolean, 98 var newAlert: Boolean 99 ) 100 101 @Override onCreatenull102 override fun onCreate() { 103 } 104 105 @Override onStartCommandnull106 override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 107 return START_REDELIVER_INTENT 108 } 109 110 @Override onDestroynull111 override fun onDestroy() { 112 mServiceLooper?.quit() 113 } 114 115 @Override onBindnull116 override fun onBind(intent: Intent?): IBinder? { 117 return null 118 } 119 120 companion object { 121 const val DEBUG = true 122 private const val TAG = "AlertService" 123 val ALERT_PROJECTION = arrayOf<String>( 124 CalendarAlerts._ID, // 0 125 CalendarAlerts.EVENT_ID, // 1 126 CalendarAlerts.STATE, // 2 127 CalendarAlerts.TITLE, // 3 128 CalendarAlerts.EVENT_LOCATION, // 4 129 CalendarAlerts.SELF_ATTENDEE_STATUS, // 5 130 CalendarAlerts.ALL_DAY, // 6 131 CalendarAlerts.ALARM_TIME, // 7 132 CalendarAlerts.MINUTES, // 8 133 CalendarAlerts.BEGIN, // 9 134 CalendarAlerts.END, // 10 135 CalendarAlerts.DESCRIPTION 136 ) 137 private const val ALERT_INDEX_ID = 0 138 private const val ALERT_INDEX_EVENT_ID = 1 139 private const val ALERT_INDEX_STATE = 2 140 private const val ALERT_INDEX_TITLE = 3 141 private const val ALERT_INDEX_EVENT_LOCATION = 4 142 private const val ALERT_INDEX_SELF_ATTENDEE_STATUS = 5 143 private const val ALERT_INDEX_ALL_DAY = 6 144 private const val ALERT_INDEX_ALARM_TIME = 7 145 private const val ALERT_INDEX_MINUTES = 8 146 private const val ALERT_INDEX_BEGIN = 9 147 private const val ALERT_INDEX_END = 10 148 private const val ALERT_INDEX_DESCRIPTION = 11 149 private val ACTIVE_ALERTS_SELECTION = ("(" + CalendarAlerts.STATE.toString() + "=? OR " + 150 CalendarAlerts.STATE.toString() + "=?) AND " + 151 CalendarAlerts.ALARM_TIME.toString() + "<=") 152 private val ACTIVE_ALERTS_SELECTION_ARGS = arrayOf<String>( 153 Integer.toString(CalendarAlerts.STATE_FIRED), 154 Integer.toString(CalendarAlerts.STATE_SCHEDULED) 155 ) 156 private const val ACTIVE_ALERTS_SORT = "begin DESC, end DESC" 157 private val DISMISS_OLD_SELECTION: String = (CalendarAlerts.END.toString() + "<? AND " + 158 CalendarAlerts.STATE + "=?") 159 private const val MINUTE_MS = 60 * 1000 160 161 // The grace period before changing a notification's priority bucket. 162 private const val MIN_DEPRIORITIZE_GRACE_PERIOD_MS = 15 * MINUTE_MS 163 164 // Hard limit to the number of notifications displayed. 165 const val MAX_NOTIFICATIONS = 20 166 } 167 }