PageRenderTime 81ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/android/server/telecom/Ringer.java

https://gitlab.com/Tu-dou520/android_packages_services_Telecomm
Java | 335 lines | 227 code | 53 blank | 55 comment | 52 complexity | 563bd619462ada36ef8a160b74ba86a1 MD5 | raw file
  1. /*
  2. * Copyright (C) 2014 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.server.telecom;
  17. import android.app.Notification;
  18. import android.app.NotificationManager;
  19. import android.content.ContentResolver;
  20. import android.content.Context;
  21. import android.media.AudioAttributes;
  22. import android.media.AudioManager;
  23. import android.net.Uri;
  24. import android.os.Bundle;
  25. import android.os.SystemVibrator;
  26. import android.os.Vibrator;
  27. import android.provider.Settings;
  28. import android.text.TextUtils;
  29. import cyanogenmod.providers.CMSettings;
  30. import android.telephony.SubscriptionManager;
  31. import java.util.LinkedList;
  32. import java.util.List;
  33. /**
  34. * Controls the ringtone player.
  35. * TODO: Turn this into a proper state machine: Ringing, CallWaiting, Stopped.
  36. */
  37. final class Ringer extends CallsManagerListenerBase {
  38. private static final long[] VIBRATION_PATTERN = new long[] {
  39. 0, // No delay before starting
  40. 1000, // How long to vibrate
  41. 1000, // How long to wait before vibrating again
  42. };
  43. private static final int STATE_RINGING = 1;
  44. private static final int STATE_CALL_WAITING = 2;
  45. private static final int STATE_STOPPED = 3;
  46. private static final AudioAttributes VIBRATION_ATTRIBUTES = new AudioAttributes.Builder()
  47. .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
  48. .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
  49. .build();
  50. /** Indicate that we want the pattern to repeat at the step which turns on vibration. */
  51. private static final int VIBRATION_PATTERN_REPEAT = 1;
  52. private final AsyncRingtonePlayer mRingtonePlayer;
  53. /**
  54. * Used to keep ordering of unanswered incoming calls. There can easily exist multiple incoming
  55. * calls and explicit ordering is useful for maintaining the proper state of the ringer.
  56. */
  57. private final List<Call> mRingingCalls = new LinkedList<>();
  58. private final CallAudioManager mCallAudioManager;
  59. private final CallsManager mCallsManager;
  60. private final InCallTonePlayer.Factory mPlayerFactory;
  61. private final Context mContext;
  62. private final Vibrator mVibrator;
  63. private int mState = STATE_STOPPED;
  64. private InCallTonePlayer mCallWaitingPlayer;
  65. /**
  66. * Used to track the status of {@link #mVibrator} in the case of simultaneous incoming calls.
  67. */
  68. private boolean mIsVibrating = false;
  69. /** Initializes the Ringer. */
  70. Ringer(
  71. CallAudioManager callAudioManager,
  72. CallsManager callsManager,
  73. InCallTonePlayer.Factory playerFactory,
  74. Context context) {
  75. mCallAudioManager = callAudioManager;
  76. mCallsManager = callsManager;
  77. mPlayerFactory = playerFactory;
  78. mContext = context;
  79. // We don't rely on getSystemService(Context.VIBRATOR_SERVICE) to make sure this
  80. // vibrator object will be isolated from others.
  81. mVibrator = new SystemVibrator(context);
  82. mRingtonePlayer = new AsyncRingtonePlayer(context);
  83. }
  84. @Override
  85. public void onCallAdded(final Call call) {
  86. if (call.isIncoming() && call.getState() == CallState.RINGING) {
  87. if (mRingingCalls.contains(call)) {
  88. Log.wtf(this, "New ringing call is already in list of unanswered calls");
  89. }
  90. mRingingCalls.add(call);
  91. updateRinging(call);
  92. }
  93. }
  94. @Override
  95. public void onCallRemoved(Call call) {
  96. removeFromUnansweredCall(call);
  97. }
  98. @Override
  99. public void onCallStateChanged(Call call, int oldState, int newState) {
  100. if (newState != CallState.RINGING) {
  101. removeFromUnansweredCall(call);
  102. }
  103. }
  104. @Override
  105. public void onIncomingCallAnswered(Call call) {
  106. onRespondedToIncomingCall(call);
  107. }
  108. @Override
  109. public void onIncomingCallRejected(Call call, boolean rejectWithMessage, String textMessage) {
  110. onRespondedToIncomingCall(call);
  111. }
  112. @Override
  113. public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
  114. Call ringingCall = null;
  115. if (mRingingCalls.contains(newForegroundCall)) {
  116. ringingCall = newForegroundCall;
  117. } else if (mRingingCalls.contains(oldForegroundCall)) {
  118. ringingCall = oldForegroundCall;
  119. }
  120. if (ringingCall != null) {
  121. updateRinging(ringingCall);
  122. }
  123. }
  124. /**
  125. * Silences the ringer for any actively ringing calls.
  126. */
  127. void silence() {
  128. for (Call call : mRingingCalls) {
  129. call.silence();
  130. }
  131. // Remove all calls from the "ringing" set and then update the ringer.
  132. mRingingCalls.clear();
  133. updateRinging(null);
  134. }
  135. private void onRespondedToIncomingCall(Call call) {
  136. // Only stop the ringer if this call is the top-most incoming call.
  137. if (getTopMostUnansweredCall() == call) {
  138. removeFromUnansweredCall(call);
  139. }
  140. }
  141. private Call getTopMostUnansweredCall() {
  142. return mRingingCalls.isEmpty() ? null : mRingingCalls.get(0);
  143. }
  144. /**
  145. * Removes the specified call from the list of unanswered incoming calls and updates the ringer
  146. * based on the new state of {@link #mRingingCalls}. Safe to call with a call that is not
  147. * present in the list of incoming calls.
  148. */
  149. private void removeFromUnansweredCall(Call call) {
  150. mRingingCalls.remove(call);
  151. updateRinging(call);
  152. }
  153. private void updateRinging(Call call) {
  154. if (mRingingCalls.isEmpty()) {
  155. stopRinging(call, "No more ringing calls found");
  156. stopCallWaiting(call);
  157. } else {
  158. startRingingOrCallWaiting(call);
  159. }
  160. }
  161. private void startRingingOrCallWaiting(Call call) {
  162. Call foregroundCall = mCallsManager.getForegroundCall();
  163. Log.v(this, "startRingingOrCallWaiting, foregroundCall: %s.", foregroundCall);
  164. if (Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.THEATER_MODE_ON,
  165. 0) == 1) {
  166. return;
  167. }
  168. if (mRingingCalls.contains(foregroundCall) && (!mCallsManager.hasActiveOrHoldingCall())) {
  169. // The foreground call is one of incoming calls so play the ringer out loud.
  170. stopCallWaiting(call);
  171. if (!shouldRingForContact(foregroundCall.getContactUri())) {
  172. return;
  173. }
  174. AudioManager audioManager =
  175. (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
  176. if (audioManager.getStreamVolume(AudioManager.STREAM_RING) >= 0) {
  177. if (mState != STATE_RINGING) {
  178. Log.event(call, Log.Events.START_RINGER);
  179. mState = STATE_RINGING;
  180. }
  181. float startVolume = 0;
  182. int rampUpTime = 0;
  183. final ContentResolver cr = mContext.getContentResolver();
  184. if (CMSettings.System.getInt(cr, CMSettings.System.INCREASING_RING, 0) != 0) {
  185. startVolume = CMSettings.System.getFloat(cr,
  186. CMSettings.System.INCREASING_RING_START_VOLUME, 0.1f);
  187. rampUpTime = CMSettings.System.getInt(cr,
  188. CMSettings.System.INCREASING_RING_RAMP_UP_TIME, 20);
  189. }
  190. mCallAudioManager.setIsRinging(call, true);
  191. // Because we wait until a contact info query to complete before processing a
  192. // call (for the purposes of direct-to-voicemail), the information about custom
  193. // ringtones should be available by the time this code executes. We can safely
  194. // request the custom ringtone from the call and expect it to be current.
  195. String foregroundCallId = foregroundCall.getTargetPhoneAccount().getId();
  196. int phoneId = 0;
  197. // Also make sure that the id passed into the call object is a valid digit
  198. // before attempting to fetch the phone id from subscriptionmanager
  199. // (CYNGNOS-2261)
  200. if (TextUtils.isDigitsOnly(foregroundCallId)) {
  201. phoneId = SubscriptionManager.getPhoneId(Integer.valueOf(foregroundCallId));
  202. }
  203. mRingtonePlayer.setPhoneId(phoneId);
  204. mRingtonePlayer.play(foregroundCall.getRingtone(), startVolume, rampUpTime);
  205. } else {
  206. Log.v(this, "startRingingOrCallWaiting, skipping because volume is 0");
  207. }
  208. if (shouldVibrate(mContext) && !mIsVibrating) {
  209. mVibrator.vibrate(VIBRATION_PATTERN, VIBRATION_PATTERN_REPEAT,
  210. VIBRATION_ATTRIBUTES);
  211. mIsVibrating = true;
  212. }
  213. } else if (foregroundCall != null) {
  214. // The first incoming call added to Telecom is not a foreground call at this point
  215. // in time. If the current foreground call is null at point, don't play call-waiting
  216. // as the call will eventually be promoted to the foreground call and play the
  217. // ring tone.
  218. Log.v(this, "Playing call-waiting tone.");
  219. // All incoming calls are in background so play call waiting.
  220. stopRinging(call, "Stop for call-waiting");
  221. if (mState != STATE_CALL_WAITING) {
  222. Log.event(call, Log.Events.START_CALL_WAITING_TONE);
  223. mState = STATE_CALL_WAITING;
  224. }
  225. if (mCallWaitingPlayer == null) {
  226. mCallWaitingPlayer =
  227. mPlayerFactory.createPlayer(InCallTonePlayer.TONE_CALL_WAITING);
  228. mCallWaitingPlayer.startTone();
  229. }
  230. }
  231. }
  232. private boolean shouldRingForContact(Uri contactUri) {
  233. final NotificationManager manager =
  234. (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
  235. final Bundle extras = new Bundle();
  236. if (contactUri != null) {
  237. extras.putStringArray(Notification.EXTRA_PEOPLE, new String[] {contactUri.toString()});
  238. }
  239. return manager.matchesCallFilter(extras);
  240. }
  241. private void stopRinging(Call call, String reasonTag) {
  242. if (mState == STATE_RINGING) {
  243. Log.event(call, Log.Events.STOP_RINGER, reasonTag);
  244. mState = STATE_STOPPED;
  245. }
  246. mRingtonePlayer.stop();
  247. if (mIsVibrating) {
  248. mVibrator.cancel();
  249. mIsVibrating = false;
  250. }
  251. // Even though stop is asynchronous it's ok to update the audio manager. Things like audio
  252. // focus are voluntary so releasing focus too early is not detrimental.
  253. mCallAudioManager.setIsRinging(call, false);
  254. }
  255. private void stopCallWaiting(Call call) {
  256. Log.v(this, "stop call waiting.");
  257. if (mCallWaitingPlayer != null) {
  258. mCallWaitingPlayer.stopTone();
  259. mCallWaitingPlayer = null;
  260. }
  261. if (mState == STATE_CALL_WAITING) {
  262. Log.event(call, Log.Events.STOP_CALL_WAITING_TONE);
  263. mState = STATE_STOPPED;
  264. }
  265. }
  266. private boolean shouldVibrate(Context context) {
  267. AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
  268. int ringerMode = audioManager.getRingerModeInternal();
  269. if (getVibrateWhenRinging(context)) {
  270. return ringerMode != AudioManager.RINGER_MODE_SILENT;
  271. } else {
  272. return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
  273. }
  274. }
  275. private boolean getVibrateWhenRinging(Context context) {
  276. if (!mVibrator.hasVibrator()) {
  277. return false;
  278. }
  279. return Settings.System.getInt(context.getContentResolver(),
  280. Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
  281. }
  282. }