Merge "Fix misleading phrasing of notification message for crashed phone apps and show phone app name in notification."
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index ed6a20a..9a36d3e 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -2555,6 +2555,15 @@
         }
     }
 
+    public void addConferenceParticipants(List<Uri> participants) {
+        if (mConnectionService == null) {
+            Log.w(this, "adding conference participants without a connection service.");
+        } else if (can(Connection.CAPABILITY_ADD_PARTICIPANT)) {
+            Log.addEvent(this, LogUtils.Events.ADD_PARTICIPANT);
+            mConnectionService.addConferenceParticipants(this, participants);
+        }
+    }
+
     /**
      * Initiates a request to the connection service to pull this call.
      * <p>
diff --git a/src/com/android/server/telecom/CallLogManager.java b/src/com/android/server/telecom/CallLogManager.java
index b84d37e..a88fec8 100755
--- a/src/com/android/server/telecom/CallLogManager.java
+++ b/src/com/android/server/telecom/CallLogManager.java
@@ -337,8 +337,8 @@
         int callFeatures = getCallFeatures(call.getVideoStateHistory(),
                 call.getDisconnectCause().getCode() == DisconnectCause.CALL_PULLED,
                 call.wasHighDefAudio(), call.wasWifi(),
-                (call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING_USED) ==
-                        Connection.PROPERTY_ASSISTED_DIALING_USED,
+                (call.getConnectionProperties() & Connection.PROPERTY_ASSISTED_DIALING) ==
+                        Connection.PROPERTY_ASSISTED_DIALING,
                 call.wasEverRttCall(),
                 call.wasVolte());
 
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 248374d..a3b23af 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -16,9 +16,12 @@
 
 package com.android.server.telecom;
 
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+
 import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
@@ -465,6 +468,32 @@
         public void addConferenceCall(String callId, ParcelableConference parcelableConference,
                 Session.Info sessionInfo) {
             Log.startSession(sessionInfo, LogUtils.Sessions.CSW_ADD_CONFERENCE_CALL);
+
+            if (parcelableConference.getConnectElapsedTimeMillis() != 0
+                    && mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
+                            != PackageManager.PERMISSION_GRANTED) {
+                Log.w(this, "addConferenceCall from caller without permission!");
+                parcelableConference = new ParcelableConference(
+                        parcelableConference.getPhoneAccount(),
+                        parcelableConference.getState(),
+                        parcelableConference.getConnectionCapabilities(),
+                        parcelableConference.getConnectionProperties(),
+                        parcelableConference.getConnectionIds(),
+                        parcelableConference.getVideoProvider(),
+                        parcelableConference.getVideoState(),
+                        0 /* connectTimeMillis */,
+                        0 /* connectElapsedRealTime */,
+                        parcelableConference.getStatusHints(),
+                        parcelableConference.getExtras(),
+                        parcelableConference.getHandle(),
+                        parcelableConference.getHandlePresentation(),
+                        "" /* callerDisplayName */,
+                        TelecomManager.PRESENTATION_UNKNOWN /* callerDisplayNamePresentation */,
+                        parcelableConference.getDisconnectCause(),
+                        parcelableConference.isRingbackRequested()
+                        );
+            }
+
             long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -752,6 +781,13 @@
         public void setAddress(String callId, Uri address, int presentation,
                 Session.Info sessionInfo) {
             Log.startSession(sessionInfo, "CSW.sA");
+
+            if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
+                    != PackageManager.PERMISSION_GRANTED) {
+                Log.w(this, "setAddress from caller without permission.");
+                return;
+            }
+
             long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -836,6 +872,13 @@
                 mAppOpsManager.checkPackage(Binder.getCallingUid(),
                         callingPhoneAccountHandle.getComponentName().getPackageName());
             }
+
+            if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
+                    != PackageManager.PERMISSION_GRANTED) {
+                Log.w(this, "addExistingConnection from caller without permission!");
+                return;
+            }
+
             long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -1038,6 +1081,13 @@
         public void setConferenceState(String callId, boolean isConference,
                 Session.Info sessionInfo) throws RemoteException {
             Log.startSession(sessionInfo, "CSW.sCS");
+
+            if (mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
+                    != PackageManager.PERMISSION_GRANTED) {
+                Log.w(this, "setConferenceState from caller without permission.");
+                return;
+            }
+
             long token = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
@@ -1680,6 +1730,18 @@
         }
     }
 
+    void addConferenceParticipants(Call call, List<Uri> participants) {
+        final String callId = mCallIdMapper.getCallId(call);
+        if (callId != null && isServiceValid("addConferenceParticipants")) {
+            try {
+                logOutgoing("addConferenceParticipants %s", callId);
+                mServiceInterface.addConferenceParticipants(callId, participants,
+                        Log.getExternalSession());
+            } catch (RemoteException ignored) {
+            }
+        }
+    }
+
     @VisibleForTesting
     public void pullExternalCall(Call call) {
         final String callId = mCallIdMapper.getCallId(call);
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index 3e2fa12..f47f212 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -474,6 +474,29 @@
     }
 
     @Override
+    public void addConferenceParticipants(String callId, List<Uri> participants) {
+        try {
+            Log.startSession("ICA.aCP", mOwnerPackageName);
+            long token = Binder.clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    Call call = mCallIdMapper.getCall(callId);
+                    if (call != null) {
+                        call.addConferenceParticipants(participants);
+                    } else {
+                        Log.w(this, "addConferenceParticipants, unknown call id: %s", callId);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        } finally {
+            Log.endSession();
+        }
+    }
+
+
+    @Override
     public void pullExternalCall(String callId) {
         try {
             Log.startSession("ICA.pEC", mOwnerPackageName);
diff --git a/src/com/android/server/telecom/LogUtils.java b/src/com/android/server/telecom/LogUtils.java
index f586a9d..0b7a1b5 100644
--- a/src/com/android/server/telecom/LogUtils.java
+++ b/src/com/android/server/telecom/LogUtils.java
@@ -127,6 +127,7 @@
         public static final String CONFERENCE_WITH = "CONF_WITH";
         public static final String SPLIT_FROM_CONFERENCE = "CONF_SPLIT";
         public static final String SWAP = "SWAP";
+        public static final String ADD_PARTICIPANT = "ADD_PARTICIPANT";
         public static final String ADD_CHILD = "ADD_CHILD";
         public static final String REMOVE_CHILD = "REMOVE_CHILD";
         public static final String SET_PARENT = "SET_PARENT";
diff --git a/src/com/android/server/telecom/ParcelableCallUtils.java b/src/com/android/server/telecom/ParcelableCallUtils.java
index d1d8f0d..3b77621 100644
--- a/src/com/android/server/telecom/ParcelableCallUtils.java
+++ b/src/com/android/server/telecom/ParcelableCallUtils.java
@@ -514,7 +514,9 @@
         android.telecom.Call.Details.CAPABILITY_CAN_PULL_CALL,
 
         Connection.CAPABILITY_SUPPORT_DEFLECT,
-        android.telecom.Call.Details.CAPABILITY_SUPPORT_DEFLECT
+        android.telecom.Call.Details.CAPABILITY_SUPPORT_DEFLECT,
+        Connection.CAPABILITY_ADD_PARTICIPANT,
+        android.telecom.Call.Details.CAPABILITY_ADD_PARTICIPANT
     };
 
     private static int convertConnectionToCallCapabilities(int connectionCapabilities) {
@@ -551,8 +553,8 @@
         Connection.PROPERTY_SELF_MANAGED,
         android.telecom.Call.Details.PROPERTY_SELF_MANAGED,
 
-        Connection.PROPERTY_ASSISTED_DIALING_USED,
-        android.telecom.Call.Details.PROPERTY_ASSISTED_DIALING_USED,
+        Connection.PROPERTY_ASSISTED_DIALING,
+        android.telecom.Call.Details.PROPERTY_ASSISTED_DIALING,
 
         Connection.PROPERTY_IS_RTT,
         android.telecom.Call.Details.PROPERTY_RTT,
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index b75c0a6..08d77a0 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -490,6 +490,18 @@
                         if (callingUid != Process.SHELL_UID) {
                             enforceUserHandleMatchesCaller(account.getAccountHandle());
                         }
+
+                        if (TextUtils.isEmpty(account.getGroupId())
+                                && mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE)
+                                != PackageManager.PERMISSION_GRANTED) {
+                            Log.w(this, "registerPhoneAccount - attempt to set a"
+                                    + " group from a non-system caller.");
+                            // Not permitted to set group, so null it out.
+                            account = new PhoneAccount.Builder(account)
+                                    .setGroupId(null)
+                                    .build();
+                        }
+
                         final long token = Binder.clearCallingIdentity();
                         try {
                             mPhoneAccountRegistrar.registerPhoneAccount(account);
diff --git a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
index 315b074..fb04577 100644
--- a/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
+++ b/tests/src/com/android/server/telecom/tests/ConnectionServiceFixture.java
@@ -359,6 +359,12 @@
                 Session.Info info) throws RemoteException { }
 
         @Override
+        public void addConferenceParticipants(String CallId, List<Uri> participants,
+                Session.Info sessionInfo) throws RemoteException {
+
+        }
+
+        @Override
         public void onPostDialContinue(String callId, boolean proceed,
                 Session.Info info) throws RemoteException { }