blob: bcf020c27ee8632c454a061f3ff866b075082147 [file] [log] [blame]
Alexandre Lisiona8b78722013-12-13 10:18:33 -05001/*
2 * Copyright (C) 2004-2013 Savoir-Faire Linux Inc.
3 *
4 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * Additional permission under GNU GPL version 3 section 7:
21 *
22 * If you modify this program, or any covered work, by linking or
23 * combining it with the OpenSSL project's OpenSSL library (or a
24 * modified version of that library), containing parts covered by the
25 * terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
26 * grants you additional permission to convey the resulting work.
27 * Corresponding Source for a non-source form of such a combination
28 * shall include the source code for the parts of OpenSSL used as well
29 * as that of the covered work.
30 */
31
Alexandre Lisionf02190d2013-12-12 17:26:12 -050032package org.sflphone.utils;
33
34import android.content.Context;
35import android.media.AudioManager;
36import android.net.Uri;
37import android.os.Vibrator;
38import android.util.Log;
39
40
41/**
42 * Ringer manager for the Phone app.
43 */
44public class Ringer {
45 private static final String THIS_FILE = "Ringer";
46
47 private static final int VIBRATE_LENGTH = 1000; // ms
48 private static final int PAUSE_LENGTH = 1000; // ms
49
50 // Uri for the ringtone.
51 Uri customRingtoneUri;
52
53 Vibrator vibrator;
54 VibratorThread vibratorThread;
55 Context context;
56
57 public Ringer(Context aContext) {
58 context = aContext;
59 vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
60 }
61
62 /**
63 * Starts the ringtone and/or vibrator.
64 *
65 */
66 public void ring(String remoteContact, String defaultRingtone) {
67 Log.d(THIS_FILE, "==> ring() called...");
68
69 synchronized (this) {
70
71 AudioManager audioManager =
72 (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
73
74 //Save ringtone at the begining in case we raise vol
75// ringtone = getRingtone(remoteContact, defaultRingtone);
76
77 //No ring no vibrate
78 int ringerMode = audioManager.getRingerMode();
79 if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
80 Log.d(THIS_FILE, "skipping ring and vibrate because profile is Silent");
81 return;
82 }
83
84 // Vibrate
85 int vibrateSetting = audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
86 Log.d(THIS_FILE, "v=" + vibrateSetting + " rm=" + ringerMode);
87 if (vibratorThread == null &&
88 (vibrateSetting == AudioManager.VIBRATE_SETTING_ON ||
89 ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
90 vibratorThread = new VibratorThread();
91 Log.d(THIS_FILE, "Starting vibrator...");
92 vibratorThread.start();
93 }
94
95 // Vibrate only
96 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE ||
97 audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0 ) {
98 Log.d(THIS_FILE, "skipping ring because profile is Vibrate OR because volume is zero");
99 return;
100 }
101
102 }
103 }
104
105 /**
106 * @return true if we're playing a ringtone and/or vibrating
107 * to indicate that there's an incoming call.
108 * ("Ringing" here is used in the general sense. If you literally
109 * need to know if we're playing a ringtone or vibrating, use
110 * isRingtonePlaying() or isVibrating() instead.)
111 */
112 public boolean isRinging() {
113 return (vibratorThread != null);
114 }
115
116 /**
117 * Stops the ringtone and/or vibrator if any of these are actually
118 * ringing/vibrating.
119 */
120 public void stopRing() {
121 synchronized (this) {
122 Log.d(THIS_FILE, "==> stopRing() called...");
123
124 stopVibrator();
125 }
126 }
127
128
129 private void stopVibrator() {
130
131 if (vibratorThread != null) {
132 vibratorThread.interrupt();
133 try {
134 vibratorThread.join(250); // Should be plenty long (typ.)
135 } catch (InterruptedException e) {
136 } // Best efforts (typ.)
137 vibratorThread = null;
138 }
139 }
140
141 public void updateRingerMode() {
142
143 AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
144 synchronized (this) {
145 int ringerMode = audioManager.getRingerMode();
146 // Silent : stop everything
147 if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
148 stopRing();
149 return;
150 }
151
152 // Vibrate
153 int vibrateSetting = audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
154 // If not already started restart it
155 if (vibratorThread == null && (vibrateSetting == AudioManager.VIBRATE_SETTING_ON || ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
156 vibratorThread = new VibratorThread();
157 vibratorThread.start();
158 }
159
160 // Vibrate only
161 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE || audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0) {
162 return;
163 }
164
165 }
166 }
167
168 private class VibratorThread extends Thread {
169 public void run() {
170 try {
171 while (true) {
172 vibrator.vibrate(VIBRATE_LENGTH);
173 Thread.sleep(VIBRATE_LENGTH + PAUSE_LENGTH);
174 }
175 } catch (InterruptedException ex) {
176 Log.d(THIS_FILE, "Vibrator thread interrupt");
177 } finally {
178 vibrator.cancel();
179 }
180 Log.d(THIS_FILE, "Vibrator thread exiting");
181 }
182 }
183
184}