Improve InCallService and add tools for call management.

Bug: b/28794830

Change-Id: Ic199cc288294d315921bbe6d10cc1eddab59e30c
(cherry picked from commit fd45787feb15efaff244db175f99a17c5f5ed846)
diff --git a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
index 6290f9c..19ac424 100644
--- a/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/bluetooth/BluetoothConnectionFacade.java
@@ -263,37 +263,68 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
+            Log.d("Action received: " + action);
+
             BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
             // Check if received the specified device
             if (!BluetoothFacade.deviceMatch(device, mDeviceID)) {
+                Log.e("Action devices does match act: " + device + " exp " + mDeviceID);
                 return;
             }
-            if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1);
-                if (state == BluetoothA2dp.STATE_CONNECTED) {
-                    Bundle a2dpGoodNews = (Bundle) mGoodNews.clone();
-                    a2dpGoodNews.putString("Type", "a2dp");
-                    mEventFacade.postEvent("A2dpConnect" + mDeviceID, a2dpGoodNews);
-                    unregisterCachedListener("A2dpConnecting" + mDeviceID);
-                }
-            } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_STATE, -1);
-                if (state == BluetoothInputDevice.STATE_CONNECTED) {
-                    mEventFacade.postEvent("HidConnect" + mDeviceID, mGoodNews);
-                    unregisterCachedListener("HidConnecting" + mDeviceID);
-                }
-            } else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1);
-                if (state == BluetoothHeadset.STATE_CONNECTED) {
-                    mEventFacade.postEvent("HspConnect" + mDeviceID, mGoodNews);
-                    unregisterCachedListener("HspConnecting" + mDeviceID);
-                }
-            } else if (action.equals(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothPan.EXTRA_STATE, -1);
-                if (state == BluetoothPan.STATE_CONNECTED) {
-                    mEventFacade.postEvent("PanConnect" + mDeviceID, mGoodNews);
-                    unregisterCachedListener("PanConnecting" + mDeviceID);
-                }
+
+            int profile = -1;
+            String listener = "";
+            switch (action) {
+                case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.A2DP;
+                    listener = "A2dpConnecting" + mDeviceID;
+                    break;
+                case BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.INPUT_DEVICE;
+                    listener = "HidConnecting" + mDeviceID;
+                    break;
+                case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.HEADSET;
+                    listener = "HspConnecting" + mDeviceID;
+                    break;
+                case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.PAN;
+                    listener = "PanConnecting" + mDeviceID;
+                    break;
+                case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.HEADSET_CLIENT;
+                    listener = "HfpClientConnecting" + mDeviceID;
+                    break;
+                case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.A2DP_SINK;
+                    listener = "A2dpSinkConnecting" + mDeviceID;
+                    break;
+                case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED:
+                    profile = BluetoothProfile.PBAP_CLIENT;
+                    listener = "PbapClientConnecting" + mDeviceID;
+                    break;
+            }
+
+            if (profile == -1) {
+                Log.e("Action does not match any given profiles " + action);
+                return;
+            }
+
+            // Find the state.
+            int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
+            if (state == -1) {
+                Log.e("Action does not have a state.");
+                return;
+            }
+
+            // Post an event to Facade.
+            if (state == BluetoothProfile.STATE_CONNECTED) {
+                Bundle news = new Bundle();
+                news.putInt("profile", profile);
+                news.putInt("state", state);
+                news.putString("addr", device.getAddress());
+                mEventFacade.postEvent("BluetoothProfileConnectionStateChanged", news);
+                unregisterCachedListener(listener);
             }
         }
     }
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java b/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java
index 969daf6..ec01f7c 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/InCallServiceImpl.java
@@ -16,8 +16,8 @@
 
 package com.googlecode.android_scripting.facade.telephony;
 
-import java.util.HashMap;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 
@@ -648,7 +648,7 @@
             return "";
     }
 
-    private static Call getCallById(String callId) {
+    public static Call getCallById(String callId) {
 
         CallContainer cc = mCallContainerMap.get(callId);
 
diff --git a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java b/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java
index a92fcc0..0db34bb 100644
--- a/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java
+++ b/Common/src/com/googlecode/android_scripting/facade/telephony/TelecomCallFacade.java
@@ -17,6 +17,7 @@
 package com.googlecode.android_scripting.facade.telephony;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 
@@ -58,6 +59,14 @@
     }
 
     /**
+     * Returns a particular call by its id.
+     */
+    @Rpc(description = "Get call by particular Id")
+    public Call telecomCallGetCallById(String callId) {
+        return InCallServiceImpl.getCallById(callId);
+    }
+
+    /**
      * Returns an identifier of the call. When a phone number is available, the number will be
      * returned. Otherwise, the standard object toString result of the Call object. e.g. A
      * conference call does not have a single number associated with it, thus the toString Id will
diff --git a/ScriptingLayerForAndroid/AndroidManifest.xml b/ScriptingLayerForAndroid/AndroidManifest.xml
index fdcfae1..bce4fc7 100644
--- a/ScriptingLayerForAndroid/AndroidManifest.xml
+++ b/ScriptingLayerForAndroid/AndroidManifest.xml
@@ -34,6 +34,8 @@
     <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
     <uses-permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE" />
     <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+    <uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" />
     <uses-permission android:name="android.permission.LOCATION_HARDWARE" />
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />