Merge "Implement TelecomService#createLaunchEmergencyDialer API."
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index b4623f7..454321b 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -139,6 +139,7 @@
boolean onCanceledViaNewOutgoingCallBroadcast(Call call, long disconnectionTimeout);
void onHoldToneRequested(Call call);
void onCallHoldFailed(Call call);
+ void onCallSwitchFailed(Call call);
void onConnectionEvent(Call call, String event, Bundle extras);
void onExternalCallChanged(Call call, boolean isExternalCall);
void onRttInitiationFailure(Call call, int reason);
@@ -215,6 +216,8 @@
@Override
public void onCallHoldFailed(Call call) {}
@Override
+ public void onCallSwitchFailed(Call call) {}
+ @Override
public void onConnectionEvent(Call call, String event, Bundle extras) {}
@Override
public void onExternalCallChanged(Call call, boolean isExternalCall) {}
@@ -580,6 +583,13 @@
private boolean mHasGoneActiveBefore = false;
/**
+ * Indicates the package name of the {@link android.telecom.CallScreeningService} which should
+ * be sent the {@link android.telecom.TelecomManager#ACTION_POST_CALL} intent upon disconnection
+ * of a call.
+ */
+ private String mPostCallPackageName;
+
+ /**
* Persists the specified parameters and initializes the new instance.
* @param context The context.
* @param repository The connection service repository.
@@ -3222,6 +3232,10 @@
for (Listener l : mListeners) {
l.onCallHoldFailed(this);
}
+ } else if (Connection.EVENT_CALL_SWITCH_FAILED.equals(event)) {
+ for (Listener l : mListeners) {
+ l.onCallSwitchFailed(this);
+ }
} else {
for (Listener l : mListeners) {
l.onConnectionEvent(this, event, extras);
@@ -3413,4 +3427,23 @@
}
return CALL_DIRECTION_UNDEFINED;
}
+
+ /**
+ * Set the package name of the {@link android.telecom.CallScreeningService} which should be sent
+ * the {@link android.telecom.TelecomManager#ACTION_POST_CALL} upon disconnection of a call.
+ * @param packageName post call screen service package name.
+ */
+ public void setPostCallPackageName(String packageName) {
+ mPostCallPackageName = packageName;
+ }
+
+ /**
+ * Return the package name of the {@link android.telecom.CallScreeningService} which should be
+ * sent the {@link android.telecom.TelecomManager#ACTION_POST_CALL} upon disconnection of a
+ * call.
+ * @return post call screen service package name.
+ */
+ public String getPostCallPackageName() {
+ return mPostCallPackageName;
+ }
}
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index ffe1ee7..afd1c6b 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -16,6 +16,18 @@
package com.android.server.telecom;
+import static android.telecom.TelecomManager.ACTION_POST_CALL;
+import static android.telecom.TelecomManager.DURATION_LONG;
+import static android.telecom.TelecomManager.DURATION_MEDIUM;
+import static android.telecom.TelecomManager.DURATION_SHORT;
+import static android.telecom.TelecomManager.DURATION_VERY_SHORT;
+import static android.telecom.TelecomManager.EXTRA_CALL_DURATION;
+import static android.telecom.TelecomManager.EXTRA_DISCONNECT_CAUSE;
+import static android.telecom.TelecomManager.EXTRA_HANDLE;
+import static android.telecom.TelecomManager.MEDIUM_CALL_TIME_MS;
+import static android.telecom.TelecomManager.SHORT_CALL_TIME_MS;
+import static android.telecom.TelecomManager.VERY_SHORT_CALL_TIME_MS;
+
import android.Manifest;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -600,6 +612,7 @@
@Override
public void onSuccessfulOutgoingCall(Call call, int callState) {
Log.v(this, "onSuccessfulOutgoingCall, %s", call);
+ call.setPostCallPackageName(getRoleManagerAdapter().getDefaultCallScreeningApp());
setCallState(call, callState, "successful outgoing call");
if (!mCalls.contains(call)) {
@@ -739,6 +752,9 @@
}
if (result.shouldAllowCall) {
+ incomingCall.setPostCallPackageName(
+ getRoleManagerAdapter().getDefaultCallScreeningApp());
+
if (hasMaximumManagedRingingCalls(incomingCall)) {
if (shouldSilenceInsteadOfReject(incomingCall)) {
incomingCall.silence();
@@ -1030,12 +1046,22 @@
@Override
public void onCallHoldFailed(Call call) {
- // Normally, we don't care whether a call hold has failed. However, if a call was held in
- // order to answer an incoming call, that incoming call needs to be brought out of the
- // ANSWERED state so that the user can try the operation again.
+ markAllAnsweredCallAsRinging(call, "hold");
+ }
+
+ @Override
+ public void onCallSwitchFailed(Call call) {
+ markAllAnsweredCallAsRinging(call, "switch");
+ }
+
+ private void markAllAnsweredCallAsRinging(Call call, String actionName) {
+ // Normally, we don't care whether a call hold or switch has failed.
+ // However, if a call was held or switched in order to answer an incoming call, that
+ // incoming call needs to be brought out of the ANSWERED state so that the user can
+ // try the operation again.
for (Call call1 : mCalls) {
if (call1 != call && call1.getState() == CallState.ANSWERED) {
- setCallState(call1, CallState.RINGING, "hold failed on other call");
+ setCallState(call1, CallState.RINGING, actionName + " failed on other call");
}
}
}
@@ -3224,6 +3250,10 @@
// TODO: Define expected state transitions here, and log when an
// unexpected transition occurs.
if (call.setState(newState, tag)) {
+ if ((oldState != CallState.AUDIO_PROCESSING) &&
+ (newState == CallState.DISCONNECTED)) {
+ maybeSendPostCallScreenIntent(call);
+ }
maybeShowErrorDialogOnDisconnect(call);
Trace.beginSection("onCallStateChanged");
@@ -4803,4 +4833,28 @@
public LinkedList<HandlerThread> getGraphHandlerThreads() {
return mGraphHandlerThreads;
}
+
+ private void maybeSendPostCallScreenIntent(Call call) {
+ if (call.isEmergencyCall() || (call.isNetworkIdentifiedEmergencyCall()) ||
+ (call.getPostCallPackageName() == null)) {
+ return;
+ }
+
+ Intent intent = new Intent(ACTION_POST_CALL);
+ intent.setPackage(call.getPostCallPackageName());
+ intent.putExtra(EXTRA_HANDLE, call.getHandle());
+ intent.putExtra(EXTRA_DISCONNECT_CAUSE, call.getDisconnectCause().getCode());
+ long duration = call.getAgeMillis();
+ int durationCode = DURATION_VERY_SHORT;
+ if ((duration >= VERY_SHORT_CALL_TIME_MS) && (duration < SHORT_CALL_TIME_MS)) {
+ durationCode = DURATION_SHORT;
+ } else if ((duration >= SHORT_CALL_TIME_MS) && (duration < MEDIUM_CALL_TIME_MS)) {
+ durationCode = DURATION_MEDIUM;
+ } else if (duration >= MEDIUM_CALL_TIME_MS) {
+ durationCode = DURATION_LONG;
+ }
+ intent.putExtra(EXTRA_CALL_DURATION, durationCode);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ mContext.startActivityAsUser(intent, mCurrentUserHandle);
+ }
}
diff --git a/testapps/AndroidManifest.xml b/testapps/AndroidManifest.xml
index f19c13e..4238191 100644
--- a/testapps/AndroidManifest.xml
+++ b/testapps/AndroidManifest.xml
@@ -273,5 +273,13 @@
android:excludeFromRecents="true"
android:launchMode="singleInstance">
</activity>
+
+ <activity android:name=".PostCallActivity"
+ android:label="@string/postCallActivityLabel">
+ <intent-filter>
+ <action android:name="android.telecom.action.POST_CALL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/testapps/res/values/donottranslate_strings.xml b/testapps/res/values/donottranslate_strings.xml
index aa34070..fcd6eff 100644
--- a/testapps/res/values/donottranslate_strings.xml
+++ b/testapps/res/values/donottranslate_strings.xml
@@ -96,6 +96,8 @@
<string name="rttUiLabel">Test RTT UI</string>
+ <string name="postCallActivityLabel">Test Post Call Screen</string>
+
<string-array name="rtt_mode_array">
<item>Full</item>
<item>HCO</item>
diff --git a/testapps/src/com/android/server/telecom/testapps/PostCallActivity.java b/testapps/src/com/android/server/telecom/testapps/PostCallActivity.java
new file mode 100644
index 0000000..101a68e
--- /dev/null
+++ b/testapps/src/com/android/server/telecom/testapps/PostCallActivity.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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.server.telecom.testapps;
+
+import static android.telecom.TelecomManager.EXTRA_CALL_DURATION;
+import static android.telecom.TelecomManager.EXTRA_DISCONNECT_CAUSE;
+import static android.telecom.TelecomManager.EXTRA_HANDLE;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.telecom.Log;
+
+public class PostCallActivity extends Activity {
+
+ public static final String ACTION_POST_CALL = "android.telecom.action.POST_CALL";
+ public static final int DEFAULT_DISCONNECT_CAUSE = -1;
+ public static final int DEFAULT_DURATION = -1;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final Intent intent = getIntent();
+ final String action = intent != null ? intent.getAction() : null;
+ Log.i(this, "action: %s", action);
+ if (ACTION_POST_CALL.equals(action)) {
+ Log.i(this, "extra handle: " +
+ intent.getParcelableExtra(EXTRA_HANDLE));
+ Log.i(this, "extra disconnect cause: " +
+ intent.getIntExtra(EXTRA_DISCONNECT_CAUSE, DEFAULT_DISCONNECT_CAUSE));
+ Log.i(this, "extra duration: " +
+ intent.getIntExtra(EXTRA_CALL_DURATION, DEFAULT_DURATION));
+ }
+ }
+}