Add BIND_CONNECTION_SERVICE permission.

- Added system permission.
- Added enforcement in ConnectionService API class.

Bug: 16171070
Change-Id: Idbd26a31e8f6bb59d3e881a1e5885a44026f2fbd
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 931d1c6..aee3090 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1257,6 +1257,14 @@
         android:description="@string/permdesc_bind_call_service"
         android:label="@string/permlab_bind_call_service" />
 
+    <!-- @SystemApi Allows an application to bind to ConnectionService implementations.
+         @hide -->
+    <permission android:name="android.permission.BIND_CONNECTION_SERVICE"
+                android:permissionGroup="android.permission-group.PHONE_CALLS"
+                android:protectionLevel="system|signature"
+                android:description="@string/permdesc_bind_connection_service"
+                android:label="@string/permlab_bind_connection_service" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d74aaeb..5011421 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2117,6 +2117,11 @@
     <string name="permdesc_bind_call_service">Allows the app to control when and how the user sees the in-call screen.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bind_connection_service">interact with telephony services</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bind_connection_service">Allows the app to interact with telephony services to make/receive calls.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_readNetworkUsageHistory">read historical network usage</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_readNetworkUsageHistory">Allows the app to read historical network usage for specific networks and apps.</string>
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index d5e4f1b..5653f5e 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -16,6 +16,7 @@
 
 package android.telecomm;
 
+import android.Manifest;
 import android.annotation.SdkConstant;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -26,6 +27,8 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Parcel;
+import android.os.RemoteException;
 import android.telephony.DisconnectCause;
 
 import com.android.internal.os.SomeArgs;
@@ -45,7 +48,6 @@
  * Android device.
  */
 public abstract class ConnectionService extends Service {
-
     /**
      * The {@link Intent} that must be declared as handled by the service.
      */
@@ -81,6 +83,18 @@
     private final ConnectionServiceAdapter mAdapter = new ConnectionServiceAdapter();
 
     private final IBinder mBinder = new IConnectionService.Stub() {
+        /**
+         * Enforces the requirement that all calls into the ConnectionService require the
+         * {@code BIND_CONNECTION_SERVICE} permission.
+         */
+        @Override
+        public boolean onTransact(int code, Parcel data, Parcel reply,
+                int flags) throws RemoteException
+        {
+            enforceBindConnectionServicePermission();
+            return super.onTransact(code, data, reply, flags);
+        }
+
         @Override
         public void addConnectionServiceAdapter(IConnectionServiceAdapter adapter) {
             mHandler.obtainMessage(MSG_ADD_CONNECTION_SERVICE_ADAPTER, adapter).sendToTarget();
@@ -617,7 +631,8 @@
                     public void onError(String request, int code, String reason) {
                         // no-op
                     }
-                });
+                }
+        );
     }
 
     private void splitFromConference(String callId) {
@@ -830,4 +845,10 @@
         return Connection.getNullConnection();
     }
 
+    /**
+     * Enforces the {@code BIND_CONNECTION_SERVICE} permission for connection service calls.
+     */
+    private void enforceBindConnectionServicePermission() {
+        enforceCallingPermission(Manifest.permission.BIND_CONNECTION_SERVICE, null);
+    }
 }