Merge "Change isRinging and isInAPhoneCall to execute from binder thread."
diff --git a/src/com/android/telecomm/CallLogManager.java b/src/com/android/telecomm/CallLogManager.java
index 142e43b..712551e 100644
--- a/src/com/android/telecomm/CallLogManager.java
+++ b/src/com/android/telecomm/CallLogManager.java
@@ -42,20 +42,25 @@
* @param presentation Number presentation of the phone number to be logged.
* @param callType The type of call (e.g INCOMING_TYPE). @see
* {@link android.provider.CallLog} for the list of values.
+ * @param features The features of the call (e.g. FEATURES_VIDEO). @see
+ * {@link android.provider.CallLog} for the list of values.
* @param creationDate Time when the call was created (milliseconds since epoch).
* @param durationInMillis Duration of the call (milliseconds).
+ * @param dataUsage Data usage in bytes, or null if not applicable.
*/
public AddCallArgs(Context context, ContactInfo contactInfo, String number,
- int presentation, int callType, PhoneAccount account,
- long creationDate, long durationInMillis) {
+ int presentation, int callType, int features, PhoneAccount account,
+ long creationDate, long durationInMillis, Long dataUsage) {
this.context = context;
this.contactInfo = contactInfo;
this.number = number;
this.presentation = presentation;
this.callType = callType;
+ this.features = features;
this.mAccount = account;
this.timestamp = creationDate;
this.durationInSec = (int)(durationInMillis / 1000);
+ this.dataUsage = dataUsage;
}
// Since the members are accessed directly, we don't use the
// mXxxx notation.
@@ -64,9 +69,11 @@
public final String number;
public final int presentation;
public final int callType;
+ public final int features;
public final PhoneAccount mAccount;
public final long timestamp;
public final int durationInSec;
+ public final Long dataUsage;
}
private static final String TAG = CallLogManager.class.getSimpleName();
@@ -114,7 +121,9 @@
final int presentation = getPresentation(call, contactInfo);
final PhoneAccount account = call.getPhoneAccount();
- logCall(contactInfo, logNumber, presentation, callLogType, account, creationTime, age);
+ // TODO: Once features and data usage are available, wire them up here.
+ logCall(contactInfo, logNumber, presentation, callLogType, Calls.FEATURES_NONE, account,
+ creationTime, age, null);
}
/**
@@ -124,17 +133,21 @@
* @param number The number the call was made to or from.
* @param presentation
* @param callType The type of call.
+ * @param features The features of the call.
* @param start The start time of the call, in milliseconds.
* @param duration The duration of the call, in milliseconds.
+ * @param dataUsage The data usage for the call, null if not applicable.
*/
private void logCall(
ContactInfo contactInfo,
String number,
int presentation,
int callType,
+ int features,
PhoneAccount account,
long start,
- long duration) {
+ long duration,
+ Long dataUsage) {
boolean isEmergencyNumber = PhoneNumberUtils.isLocalEmergencyNumber(mContext, number);
// On some devices, to avoid accidental redialing of emergency numbers, we *never* log
@@ -151,7 +164,7 @@
+ Log.pii(number) + "," + presentation + ", " + callType
+ ", " + start + ", " + duration);
AddCallArgs args = new AddCallArgs(mContext, contactInfo, number, presentation,
- callType, account, start, duration);
+ callType, features, account, start, duration, dataUsage);
logCallAsync(args);
} else {
Log.d(TAG, "Not adding emergency call to call log.");
@@ -223,7 +236,8 @@
try {
// May block.
result[i] = Calls.addCall(null, c.context, c.number, c.presentation,
- c.callType, c.mAccount, c.timestamp, c.durationInSec);
+ c.callType, c.features, c.mAccount, c.timestamp, c.durationInSec,
+ c.dataUsage);
} catch (Exception e) {
// This is very rare but may happen in legitimate cases.
// E.g. If the phone is encrypted and thus write request fails, it may cause
diff --git a/src/com/android/telecomm/ConnectionServiceWrapper.java b/src/com/android/telecomm/ConnectionServiceWrapper.java
index b2dd085..9d59aed 100644
--- a/src/com/android/telecomm/ConnectionServiceWrapper.java
+++ b/src/com/android/telecomm/ConnectionServiceWrapper.java
@@ -482,7 +482,7 @@
@Override
public void setAudioModeIsVoip(String callId, boolean isVoip) {
- logIncoming("setAudioModeIsVoip %s %d", callId, isVoip);
+ logIncoming("setAudioModeIsVoip %s %b", callId, isVoip);
mCallIdMapper.checkValidCallId(callId);
mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
callId).sendToTarget();
diff --git a/src/com/android/telecomm/OutgoingCallProcessor.java b/src/com/android/telecomm/OutgoingCallProcessor.java
index c33b17e..1f6e4f3 100644
--- a/src/com/android/telecomm/OutgoingCallProcessor.java
+++ b/src/com/android/telecomm/OutgoingCallProcessor.java
@@ -16,6 +16,7 @@
package com.android.telecomm;
+import android.content.ComponentName;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
@@ -196,8 +197,12 @@
for (ConnectionServiceWrapper service : services) {
CallServiceDescriptor descriptor = service.getDescriptor();
// TODO(sail): Remove once there's a way to pick the service.
- if (descriptor.getServiceComponent().getPackageName().equals(
- "com.google.android.talk")) {
+ ComponentName sipName = new ComponentName("com.android.phone",
+ "com.android.services.telephony.sip.SipConnectionService");
+ ComponentName hangoutsName = new ComponentName("com.google.android.talk",
+ "com.google.android.apps.babel.telephony.TeleConnectionService");
+ ComponentName serviceName = descriptor.getServiceComponent();
+ if (serviceName.equals(sipName) || serviceName.equals(hangoutsName)) {
Log.i(this, "Moving connection service %s to top of list", descriptor);
mCallServiceDescriptors.add(0, descriptor);
} else {
diff --git a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
index ff52157..60f4250 100644
--- a/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
+++ b/tests/src/com/android/telecomm/testapps/CallServiceNotifier.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.telecomm.CallServiceDescriptor;
import android.telecomm.TelecommConstants;
+import android.telecomm.VideoCallProfile;
import android.util.Log;
/**
@@ -38,6 +39,12 @@
private static final int CALL_NOTIFICATION_ID = 1;
/**
+ * Whether the added call should be started as a video call. Referenced by
+ * {@link TestConnectionService} to know whether to provide a call video provider.
+ */
+ public static boolean mStartVideoCall;
+
+ /**
* Singleton accessor.
*/
public static CallServiceNotifier getInstance() {
@@ -81,7 +88,7 @@
builder.setOngoing(true);
builder.setPriority(Notification.PRIORITY_HIGH);
- final PendingIntent intent = createIncomingCallIntent(context);
+ final PendingIntent intent = createIncomingCallIntent(context, false /* isVideoCall */);
builder.setContentIntent(intent);
builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
@@ -89,6 +96,7 @@
builder.setContentTitle("TestConnectionService");
addAddCallAction(builder, context);
+ addAddVideoCallAction(builder, context);
addExitAction(builder, context);
return builder.build();
@@ -107,7 +115,7 @@
/**
* Creates the intent to add an incoming call through Telecomm.
*/
- private PendingIntent createIncomingCallIntent(Context context) {
+ private PendingIntent createIncomingCallIntent(Context context, boolean isVideoCall) {
log("Creating incoming call pending intent.");
// Build descriptor for TestConnectionService.
CallServiceDescriptor.Builder descriptorBuilder = CallServiceDescriptor.newBuilder(context);
@@ -121,6 +129,8 @@
intent.setPackage("com.android.telecomm");
intent.putExtra(TelecommConstants.EXTRA_CALL_SERVICE_DESCRIPTOR, descriptorBuilder.build());
+ mStartVideoCall = isVideoCall;
+
return PendingIntent.getActivity(context, 0, intent, 0);
}
@@ -130,7 +140,14 @@
*/
private void addAddCallAction(Notification.Builder builder, Context context) {
// Set pending intent on the notification builder.
- builder.addAction(0, "Add a Call", createIncomingCallIntent(context));
+ builder.addAction(0, "Add Call", createIncomingCallIntent(context, false /* isVideoCall */));
+ }
+
+ /**
+ * Adds an action to the Notification Builder to add an incoming video call through Telecomm.
+ */
+ private void addAddVideoCallAction(Notification.Builder builder, Context context) {
+ builder.addAction(0, "Add Video", createIncomingCallIntent(context, true /* isVideoCall */));
}
/**
@@ -140,6 +157,10 @@
builder.addAction(0, "Exit", createExitIntent(context));
}
+ public boolean shouldStartVideoCall() {
+ return mStartVideoCall;
+ }
+
private static void log(String msg) {
Log.w("testcallservice", "[CallServiceNotifier] " + msg);
}
diff --git a/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java b/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
index 1c502f4..5b673ad 100644
--- a/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
+++ b/tests/src/com/android/telecomm/testapps/TestCallVideoProvider.java
@@ -16,6 +16,10 @@
package com.android.telecomm.testapps;
+import android.content.Context;
+import android.os.RemoteException;
+import android.telecomm.CallCameraCapabilities;
+import android.telecomm.CallVideoClient;
import android.telecomm.CallVideoProvider;
import android.telecomm.RemoteCallVideoClient;
import android.telecomm.VideoCallProfile;
@@ -23,14 +27,28 @@
import android.util.Log;
import android.view.Surface;
+import java.util.Random;
+
/**
* Implements the CallVideoProvider.
*/
public class TestCallVideoProvider extends CallVideoProvider {
+ private RemoteCallVideoClient mCallVideoClient;
+ private CallCameraCapabilities mCapabilities;
+ private Random random;
+
+ public TestCallVideoProvider(Context context) {
+ mCapabilities = new CallCameraCapabilities(false /* zoomSupported */, 0 /* maxZoom */);
+ random = new Random();
+ }
+
+ /**
+ * Save the reference to the CallVideoClient so callback can be invoked.
+ */
@Override
public void onSetCallVideoClient(RemoteCallVideoClient callVideoClient) {
-
+ mCallVideoClient = callVideoClient;
}
@Override
@@ -40,27 +58,56 @@
@Override
public void onSetPreviewSurface(Surface surface) {
-
+ log("Set preview surface");
}
@Override
public void onSetDisplaySurface(Surface surface) {
-
+ log("Set display surface");
}
@Override
public void onSetDeviceOrientation(int rotation) {
-
+ log("Set device orientation");
}
+ /**
+ * Sets the zoom value, creating a new CallCameraCapabalities object. If the zoom value is
+ * non-positive, assume that zoom is not supported.
+ */
@Override
public void onSetZoom(float value) {
+ log("Set zoom to " + value);
+ if (value <= 0) {
+ mCapabilities = new CallCameraCapabilities(false /* zoomSupported */, 0 /* maxZoom */);
+ } else {
+ mCapabilities = new CallCameraCapabilities(true /* zoomSupported */, value);
+ }
+
+ try {
+ mCallVideoClient.handleCameraCapabilitiesChange(mCapabilities);
+ } catch (RemoteException ignored) {
+ }
}
+ /**
+ * "Sends" a request with a video call profile. Assumes that this response succeeds and sends
+ * the response back via the CallVideoClient.
+ */
@Override
public void onSendSessionModifyRequest(VideoCallProfile requestProfile) {
+ log("Sent session modify request");
+ VideoCallProfile responseProfile = new VideoCallProfile(
+ requestProfile.getVideoState(), requestProfile.getQuality());
+ try {
+ mCallVideoClient.receiveSessionModifyResponse(
+ CallVideoClient.SESSION_MODIFY_REQUEST_SUCCESS,
+ requestProfile,
+ responseProfile);
+ } catch (RemoteException ignored) {
+ }
}
@Override
@@ -68,22 +115,40 @@
}
+ /**
+ * Returns a CallCameraCapabilities object without supporting zoom.
+ */
@Override
public void onRequestCameraCapabilities() {
-
+ log("Requested camera capabilities");
+ try {
+ mCallVideoClient.handleCameraCapabilitiesChange(mCapabilities);
+ } catch (RemoteException ignored) {
+ }
}
+ /**
+ * Randomly reports data usage of value ranging from 10MB to 60MB.
+ */
@Override
public void onRequestCallDataUsage() {
-
+ log("Requested call data usage");
+ int dataUsageKb = (10 *1024) + random.nextInt(50 * 1024);
+ try {
+ mCallVideoClient.updateCallDataUsage(dataUsageKb);
+ } catch (RemoteException ignored) {
+ }
}
+ /**
+ * We do not have a need to set a paused image.
+ */
@Override
public void onSetPauseImage(String uri) {
-
+ // Not implemented.
}
private static void log(String msg) {
Log.w("TestCallServiceProvider", "[TestCallServiceProvider] " + msg);
}
-}
+}
\ No newline at end of file
diff --git a/tests/src/com/android/telecomm/testapps/TestConnectionService.java b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
index e84b461..f24f779 100644
--- a/tests/src/com/android/telecomm/testapps/TestConnectionService.java
+++ b/tests/src/com/android/telecomm/testapps/TestConnectionService.java
@@ -10,7 +10,7 @@
* 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.
- Ca* See the License for the specific language governing permissions and
+ * See the License for the specific language governing permissions and
* limitations under the License.
*/
@@ -30,6 +30,8 @@
import android.telecomm.Response;
import android.telecomm.SimpleResponse;
import android.telecomm.StatusHints;
+import android.telecomm.PhoneAccount;
+import android.telecomm.VideoCallProfile;
import android.telephony.DisconnectCause;
import android.text.TextUtils;
import android.util.Log;
@@ -236,6 +238,7 @@
if (remoteConnection != null) {
TestConnection connection = new TestConnection(
remoteConnection, Connection.State.DIALING);
+
mCalls.add(connection);
mCallback.onSuccess(mOriginalRequest, connection);
} else {
@@ -298,7 +301,7 @@
mCalls.remove(connection);
// Stops audio if there are no more calls.
- if (mCalls.isEmpty() && mMediaPlayer.isPlaying()) {
+ if (mCalls.isEmpty() && mMediaPlayer != null && mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = createMediaPlayer();
@@ -375,15 +378,21 @@
@Override
public void onCreateIncomingConnection(
ConnectionRequest request, Response<ConnectionRequest, Connection> callback) {
-
// Use dummy number for testing incoming calls.
Uri handle = Uri.fromParts(SCHEME_TEL, "5551234", null);
+ boolean isVideoCall = CallServiceNotifier.getInstance().shouldStartVideoCall();
TestConnection connection = new TestConnection(null, Connection.State.DIALING);
+ if (isVideoCall) {
+ connection.setCallVideoProvider(new TestCallVideoProvider(getApplicationContext()));
+ }
+
mCalls.add(connection);
- callback.onResult(
- new ConnectionRequest(request.getCallId(), handle, request.getExtras(),
- request.getVideoState()),
- connection);
+
+ ConnectionRequest newRequest = new ConnectionRequest(request.getCallId(), handle,
+ request.getExtras(),
+ isVideoCall ? VideoCallProfile.VIDEO_STATE_BIDIRECTIONAL : request.getVideoState());
+
+ callback.onResult(newRequest, connection);
}
}