blob: 075f790c43571410802d95f990c225afac809dc7 [file] [log] [blame]
Alexandre Lisionf02190d2013-12-12 17:26:12 -05001package org.sflphone.utils;
2
3import android.content.Context;
4import android.media.AudioManager;
5import android.net.Uri;
6import android.os.Vibrator;
7import android.util.Log;
8
9
10/**
11 * Ringer manager for the Phone app.
12 */
13public class Ringer {
14 private static final String THIS_FILE = "Ringer";
15
16 private static final int VIBRATE_LENGTH = 1000; // ms
17 private static final int PAUSE_LENGTH = 1000; // ms
18
19 // Uri for the ringtone.
20 Uri customRingtoneUri;
21
22 Vibrator vibrator;
23 VibratorThread vibratorThread;
24 Context context;
25
26 public Ringer(Context aContext) {
27 context = aContext;
28 vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
29 }
30
31 /**
32 * Starts the ringtone and/or vibrator.
33 *
34 */
35 public void ring(String remoteContact, String defaultRingtone) {
36 Log.d(THIS_FILE, "==> ring() called...");
37
38 synchronized (this) {
39
40 AudioManager audioManager =
41 (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
42
43 //Save ringtone at the begining in case we raise vol
44// ringtone = getRingtone(remoteContact, defaultRingtone);
45
46 //No ring no vibrate
47 int ringerMode = audioManager.getRingerMode();
48 if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
49 Log.d(THIS_FILE, "skipping ring and vibrate because profile is Silent");
50 return;
51 }
52
53 // Vibrate
54 int vibrateSetting = audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
55 Log.d(THIS_FILE, "v=" + vibrateSetting + " rm=" + ringerMode);
56 if (vibratorThread == null &&
57 (vibrateSetting == AudioManager.VIBRATE_SETTING_ON ||
58 ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
59 vibratorThread = new VibratorThread();
60 Log.d(THIS_FILE, "Starting vibrator...");
61 vibratorThread.start();
62 }
63
64 // Vibrate only
65 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE ||
66 audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0 ) {
67 Log.d(THIS_FILE, "skipping ring because profile is Vibrate OR because volume is zero");
68 return;
69 }
70
71 }
72 }
73
74 /**
75 * @return true if we're playing a ringtone and/or vibrating
76 * to indicate that there's an incoming call.
77 * ("Ringing" here is used in the general sense. If you literally
78 * need to know if we're playing a ringtone or vibrating, use
79 * isRingtonePlaying() or isVibrating() instead.)
80 */
81 public boolean isRinging() {
82 return (vibratorThread != null);
83 }
84
85 /**
86 * Stops the ringtone and/or vibrator if any of these are actually
87 * ringing/vibrating.
88 */
89 public void stopRing() {
90 synchronized (this) {
91 Log.d(THIS_FILE, "==> stopRing() called...");
92
93 stopVibrator();
94 }
95 }
96
97
98 private void stopVibrator() {
99
100 if (vibratorThread != null) {
101 vibratorThread.interrupt();
102 try {
103 vibratorThread.join(250); // Should be plenty long (typ.)
104 } catch (InterruptedException e) {
105 } // Best efforts (typ.)
106 vibratorThread = null;
107 }
108 }
109
110 public void updateRingerMode() {
111
112 AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
113 synchronized (this) {
114 int ringerMode = audioManager.getRingerMode();
115 // Silent : stop everything
116 if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
117 stopRing();
118 return;
119 }
120
121 // Vibrate
122 int vibrateSetting = audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
123 // If not already started restart it
124 if (vibratorThread == null && (vibrateSetting == AudioManager.VIBRATE_SETTING_ON || ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
125 vibratorThread = new VibratorThread();
126 vibratorThread.start();
127 }
128
129 // Vibrate only
130 if (ringerMode == AudioManager.RINGER_MODE_VIBRATE || audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0) {
131 return;
132 }
133
134 }
135 }
136
137 private class VibratorThread extends Thread {
138 public void run() {
139 try {
140 while (true) {
141 vibrator.vibrate(VIBRATE_LENGTH);
142 Thread.sleep(VIBRATE_LENGTH + PAUSE_LENGTH);
143 }
144 } catch (InterruptedException ex) {
145 Log.d(THIS_FILE, "Vibrator thread interrupt");
146 } finally {
147 vibrator.cancel();
148 }
149 Log.d(THIS_FILE, "Vibrator thread exiting");
150 }
151 }
152
153}