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 }