Implement post call screen.

Test: CTS test
Bug: 135929421
Change-Id: Ifc368b86366beed35957cfe66a82a3217436f6ea
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index b4623f7..e0c53c2 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -580,6 +580,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.
@@ -3413,4 +3420,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..8902a52 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();
@@ -3224,6 +3240,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 +4823,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));
+        }
+    }
+}