Merge "Marking call as DIALING from CallsManager instead of Call."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 79b0f49..22db037 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,7 +16,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- package="com.android.telecomm">
+ package="com.android.telecomm"
+ coreApp="true"
+ android:sharedUserId="android.uid.phone">
<!-- Prevents the activity manager from delaying any activity-start
requests by this package, including requests immediately after
diff --git a/src/com/android/telecomm/AsyncRingtonePlayer.java b/src/com/android/telecomm/AsyncRingtonePlayer.java
index ae78c5b..1c5cafe 100644
--- a/src/com/android/telecomm/AsyncRingtonePlayer.java
+++ b/src/com/android/telecomm/AsyncRingtonePlayer.java
@@ -16,6 +16,7 @@
package com.android.telecomm;
+import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.os.Handler;
@@ -149,7 +150,9 @@
private Ringtone getCurrentRingtone() {
// TODO: Needs support for custom ringtones.
- return RingtoneManager.getRingtone(
+ Ringtone ringtone = RingtoneManager.getRingtone(
TelecommApp.getInstance(), Settings.System.DEFAULT_RINGTONE_URI);
+ ringtone.setStreamType(AudioManager.STREAM_RING);
+ return ringtone;
}
}
diff --git a/src/com/android/telecomm/CallsManager.java b/src/com/android/telecomm/CallsManager.java
index 078209e..b21be69 100644
--- a/src/com/android/telecomm/CallsManager.java
+++ b/src/com/android/telecomm/CallsManager.java
@@ -85,6 +85,8 @@
private final CallAudioManager mCallAudioManager;
+ private final Ringer mRinger;
+
private final Set<CallsManagerListener> mListeners = Sets.newHashSet();
/** Singleton accessor. */
@@ -99,12 +101,13 @@
TelecommApp app = TelecommApp.getInstance();
mCallAudioManager = new CallAudioManager();
-
InCallTonePlayer.Factory playerFactory = new InCallTonePlayer.Factory(mCallAudioManager);
+ mRinger = new Ringer(mCallAudioManager, this, playerFactory, app);
+
mListeners.add(new CallLogManager(app));
mListeners.add(new PhoneStateBroadcaster());
mListeners.add(new InCallController());
- mListeners.add(new Ringer(mCallAudioManager, this, playerFactory, app));
+ mListeners.add(mRinger);
mListeners.add(new RingbackPlayer(this, playerFactory));
mListeners.add(new InCallToneMonitor(playerFactory, this));
mListeners.add(mCallAudioManager);
@@ -163,6 +166,10 @@
return mForegroundCall;
}
+ Ringer getRinger() {
+ return mRinger;
+ }
+
boolean hasEmergencyCall() {
for (Call call : mCalls) {
if (call.isEmergencyCall()) {
diff --git a/src/com/android/telecomm/Ringer.java b/src/com/android/telecomm/Ringer.java
index 367a1de..3272103 100644
--- a/src/com/android/telecomm/Ringer.java
+++ b/src/com/android/telecomm/Ringer.java
@@ -46,7 +46,7 @@
* Used to keep ordering of unanswered incoming calls. There can easily exist multiple incoming
* calls and explicit ordering is useful for maintaining the proper state of the ringer.
*/
- private final List<Call> mUnansweredCalls = Lists.newLinkedList();
+ private final List<Call> mRingingCalls = Lists.newLinkedList();
private final CallAudioManager mCallAudioManager;
private final CallsManager mCallsManager;
@@ -80,10 +80,10 @@
@Override
public void onCallAdded(Call call) {
if (call.isIncoming() && call.getState() == CallState.RINGING) {
- if (mUnansweredCalls.contains(call)) {
+ if (mRingingCalls.contains(call)) {
Log.wtf(this, "New ringing call is already in list of unanswered calls");
}
- mUnansweredCalls.add(call);
+ mRingingCalls.add(call);
updateRinging();
}
}
@@ -113,12 +113,21 @@
@Override
public void onForegroundCallChanged(Call oldForegroundCall, Call newForegroundCall) {
- if (mUnansweredCalls.contains(oldForegroundCall) ||
- mUnansweredCalls.contains(newForegroundCall)) {
+ if (mRingingCalls.contains(oldForegroundCall) ||
+ mRingingCalls.contains(newForegroundCall)) {
updateRinging();
}
}
+ /**
+ * Silences the ringer for any actively ringing calls.
+ */
+ void silence() {
+ // Remove all calls from the "ringing" set and then update the ringer.
+ mRingingCalls.clear();
+ updateRinging();
+ }
+
private void onRespondedToIncomingCall(Call call) {
// Only stop the ringer if this call is the top-most incoming call.
if (getTopMostUnansweredCall() == call) {
@@ -126,26 +135,26 @@
stopCallWaiting();
}
- // We do not remove the call from mUnansweredCalls until the call state changes from RINGING
+ // We do not remove the call from mRingingCalls until the call state changes from RINGING
// or the call is removed. see onCallStateChanged or onCallRemoved.
}
private Call getTopMostUnansweredCall() {
- return mUnansweredCalls.isEmpty() ? null : mUnansweredCalls.get(0);
+ return mRingingCalls.isEmpty() ? null : mRingingCalls.get(0);
}
/**
* Removes the specified call from the list of unanswered incoming calls and updates the ringer
- * based on the new state of {@link #mUnansweredCalls}. Safe to call with a call that is not
+ * based on the new state of {@link #mRingingCalls}. Safe to call with a call that is not
* present in the list of incoming calls.
*/
private void removeFromUnansweredCall(Call call) {
- mUnansweredCalls.remove(call);
+ mRingingCalls.remove(call);
updateRinging();
}
private void updateRinging() {
- if (mUnansweredCalls.isEmpty()) {
+ if (mRingingCalls.isEmpty()) {
stopRinging();
stopCallWaiting();
} else {
@@ -157,7 +166,7 @@
Call foregroundCall = mCallsManager.getForegroundCall();
Log.v(this, "startRingingOrCallWaiting, foregroundCall: %s.", foregroundCall);
- if (mUnansweredCalls.contains(foregroundCall)) {
+ if (mRingingCalls.contains(foregroundCall)) {
// The foreground call is one of incoming calls so play the ringer out loud.
stopCallWaiting();
diff --git a/src/com/android/telecomm/TelecommApp.java b/src/com/android/telecomm/TelecommApp.java
index 49554da..48f6ba5 100644
--- a/src/com/android/telecomm/TelecommApp.java
+++ b/src/com/android/telecomm/TelecommApp.java
@@ -36,7 +36,9 @@
@Override public void onCreate() {
super.onCreate();
sInstance = this;
+
mMissedCallNotifier = new MissedCallNotifier(this);
+ TelecommServiceImpl.init();
}
public static TelecommApp getInstance() {
diff --git a/src/com/android/telecomm/TelecommServiceImpl.java b/src/com/android/telecomm/TelecommServiceImpl.java
new file mode 100644
index 0000000..beb046b
--- /dev/null
+++ b/src/com/android/telecomm/TelecommServiceImpl.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.telecomm;
+
+import android.os.Handler;
+import android.os.Message;
+import android.os.ServiceManager;
+
+import com.android.internal.telecomm.ITelecommService;
+
+/**
+ * Implementation of the ITelecomm interface.
+ */
+public class TelecommServiceImpl extends ITelecommService.Stub {
+ private static final String TAG = TelecommServiceImpl.class.getSimpleName();
+
+ private static final String SERVICE_NAME = "telecomm";
+
+ private static final int MSG_SILENCE_RINGER = 1;
+
+ /** The singleton instance. */
+ private static TelecommServiceImpl sInstance;
+
+ /**
+ * A handler that processes messages on the main thread in the phone process. Since many
+ * of the Phone calls are not thread safe this is needed to shuttle the requests from the
+ * inbound binder threads to the main thread in the phone process.
+ */
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SILENCE_RINGER:
+ silenceRingerInternal();
+ break;
+ }
+ }
+ };
+
+ /**
+ * Initialize the singleton TelecommServiceImpl instance.
+ * This is only done once, at startup, from TelecommApp.onCreate().
+ */
+ static TelecommServiceImpl init() {
+ synchronized (TelecommServiceImpl.class) {
+ if (sInstance == null) {
+ sInstance = new TelecommServiceImpl();
+ } else {
+ Log.wtf(TAG, "init() called multiple times! sInstance %s", sInstance);
+ }
+ return sInstance;
+ }
+ }
+
+ /** Private constructor; @see init() */
+ private TelecommServiceImpl() {
+ publish();
+ }
+
+ private void publish() {
+ Log.d(this, "publish: %s", this);
+ ServiceManager.addService(SERVICE_NAME, this);
+ }
+
+ //
+ // Implementation of the ITelephony interface.
+ //
+
+ @Override
+ public void silenceRinger() {
+ Log.d(this, "silenceRinger");
+ // TODO: find a more appropriate permission to check here.
+ enforceModifyPermission();
+ mHandler.sendEmptyMessage(MSG_SILENCE_RINGER);
+ }
+
+ /**
+ * Internal implemenation of silenceRinger().
+ * This should only be called from the main thread of the Phone app.
+ * @see #silenceRinger
+ */
+ private void silenceRingerInternal() {
+ CallsManager.getInstance().getRinger().silence();
+ }
+
+ /**
+ * Make sure the caller has the MODIFY_PHONE_STATE permission.
+ *
+ * @throws SecurityException if the caller does not have the required permission
+ */
+ private void enforceModifyPermission() {
+ TelecommApp.getInstance().enforceCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_PHONE_STATE, null);
+ }
+}