1 /*
2  * Copyright (C) 2020 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.alarms
18 
19 import android.annotation.TargetApi
20 import android.content.Context
21 import android.media.AudioAttributes
22 import android.os.Build
23 import android.os.Vibrator
24 
25 import com.android.deskclock.AsyncRingtonePlayer
26 import com.android.deskclock.LogUtils
27 import com.android.deskclock.Utils
28 import com.android.deskclock.data.DataModel
29 import com.android.deskclock.provider.AlarmInstance
30 import com.android.deskclock.provider.ClockContract.AlarmSettingColumns
31 
32 /**
33  * Manages playing alarm ringtones and vibrating the device.
34  */
35 internal object AlarmKlaxon {
36 
37     private val VIBRATE_PATTERN = longArrayOf(500, 500)
38 
39     private var sStarted = false
40     private var sAsyncRingtonePlayer: AsyncRingtonePlayer? = null
41 
42     @JvmStatic
stopnull43     fun stop(context: Context) {
44         if (sStarted) {
45             LogUtils.v("AlarmKlaxon.stop()")
46             sStarted = false
47             getAsyncRingtonePlayer(context)!!.stop()
48             (context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator).cancel()
49         }
50     }
51 
52     @JvmStatic
startnull53     fun start(context: Context, instance: AlarmInstance) {
54         // Make sure we are stopped before starting
55         stop(context)
56         LogUtils.v("AlarmKlaxon.start()")
57 
58         if (!AlarmSettingColumns.NO_RINGTONE_URI.equals(instance.mRingtone)) {
59             val crescendoDuration = DataModel.dataModel.alarmCrescendoDuration
60             getAsyncRingtonePlayer(context)!!.play(instance.mRingtone, crescendoDuration)
61         }
62 
63         if (instance.mVibrate) {
64             val vibrator: Vibrator = getVibrator(context)
65             if (Utils.isLOrLater()) {
66                 vibrateLOrLater(vibrator)
67             } else {
68                 vibrator.vibrate(VIBRATE_PATTERN, 0)
69             }
70         }
71 
72         sStarted = true
73     }
74 
75     @TargetApi(Build.VERSION_CODES.LOLLIPOP)
vibrateLOrLaternull76     private fun vibrateLOrLater(vibrator: Vibrator) {
77         vibrator.vibrate(VIBRATE_PATTERN, 0, AudioAttributes.Builder()
78                 .setUsage(AudioAttributes.USAGE_ALARM)
79                 .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
80                 .build())
81     }
82 
getVibratornull83     private fun getVibrator(context: Context): Vibrator {
84         return context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
85     }
86 
87     @Synchronized
getAsyncRingtonePlayernull88     private fun getAsyncRingtonePlayer(context: Context): AsyncRingtonePlayer? {
89         if (sAsyncRingtonePlayer == null) {
90             sAsyncRingtonePlayer = AsyncRingtonePlayer(context.getApplicationContext())
91         }
92 
93         return sAsyncRingtonePlayer
94     }
95 }