Merge "TWSP-HFP: set active device to null if setHfpActive to peer earbud failed" into q-keystone-qcom-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index aa3881f..ff6ab4f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -70,7 +70,11 @@
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
     <uses-permission android:name="com.android.email.permission.ACCESS_PROVIDER"/>
     <uses-permission android:name="com.android.email.permission.READ_ATTACHMENT"/>
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
 
     <!-- Allows access to read media audio -->
     <uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
diff --git a/res/values/config.xml b/res/values/config.xml
index 12944d8..7236b2f 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -26,8 +26,8 @@
     <bool name="pbap_use_profile_for_owner_vcard">true</bool>
     <bool name="profile_supported_map">true</bool>
     <bool name="profile_supported_avrcp_target">true</bool>
-    <bool name="profile_supported_avrcp_controller">false</bool>
-    <bool name="profile_supported_sap">false</bool>
+    <bool name="profile_supported_avrcp_controller">true</bool>
+    <bool name="profile_supported_sap">true</bool>
     <bool name="profile_supported_pbapclient">false</bool>
     <bool name="profile_supported_mapmce">false</bool>
     <bool name="profile_supported_hid_device">true</bool>
diff --git a/src/com/android/bluetooth/btservice/AbstractionLayer.java b/src/com/android/bluetooth/btservice/AbstractionLayer.java
index ef29b52..6ee0d6e 100644
--- a/src/com/android/bluetooth/btservice/AbstractionLayer.java
+++ b/src/com/android/bluetooth/btservice/AbstractionLayer.java
@@ -125,6 +125,7 @@
     public static final int AVRCP = 1;
     public static final int PBAP = 2;
     public static final int MAP = 3;
+    public static final int MAX_POW = 4;
 
     // Profile features supported in profile_conf
     public static final int PROFILE_VERSION =1;
@@ -133,6 +134,10 @@
     public static final int USE_SIM_SUPPORT = 4;
     public static final int MAP_EMAIL_SUPPORT = 5;
     public static final int PBAP_0102_SUPPORT = 6;
+    public static final int BR_MAX_POW_SUPPORT = 7;
+    public static final int EDR_MAX_POW_SUPPORT = 8;
+    public static final int BLE_MAX_POW_SUPPORT = 9;
+
 
     static final int BT_VENDOR_PROPERTY_TWS_PLUS_DEVICE_TYPE = 0x01;
     static final int BT_VENDOR_PROPERTY_TWS_PLUS_PEER_ADDR = 0x02;
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index b05d18b..de1e64c 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -116,6 +116,7 @@
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.net.NetworkInfo;
+import android.net.wifi.WifiConfiguration;
 
 import com.google.protobuf.InvalidProtocolBufferException;
 
@@ -325,6 +326,13 @@
         return mVendor.isSplitA2dpEnabled();
     }
 
+    public boolean isSwbEnabled() {
+        return mVendor.isSwbEnabled();
+    }
+    public boolean isSwbPmEnabled() {
+        return mVendor.isSwbPmEnabled();
+    }
+
     private static final int MESSAGE_PROFILE_SERVICE_STATE_CHANGED = 1;
     private static final int MESSAGE_PROFILE_SERVICE_REGISTERED = 2;
     private static final int MESSAGE_PROFILE_SERVICE_UNREGISTERED = 3;
@@ -392,6 +400,13 @@
                         mAdapterStateMachine.sendMessage(AdapterState.BREDR_STARTED);
                         //update wifi state to lower layers
                         fetchWifiState();
+                        if (isVendorIntfEnabled()) {
+                            if (isPowerbackRequired()) {
+                                mVendor.setPowerBackoff(true);
+                            } else {
+                                mVendor.setPowerBackoff(false);
+                            }
+                        }
                     }
                     break;
                 case BluetoothAdapter.STATE_OFF:
@@ -512,6 +527,11 @@
 
         mSdpManager = SdpManager.init(this);
         registerReceiver(mAlarmBroadcastReceiver, new IntentFilter(ACTION_ALARM_WAKEUP));
+        IntentFilter wifiFilter = new IntentFilter();
+        wifiFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        wifiFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
+        wifiFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+        registerReceiver(mWifiStateBroadcastReceiver, wifiFilter);
         mProfileObserver = new ProfileObserver(getApplicationContext(), this, new Handler());
         mProfileObserver.start();
 
@@ -830,6 +850,7 @@
         mCleaningUp = true;
 
         unregisterReceiver(mAlarmBroadcastReceiver);
+        unregisterReceiver(mWifiStateBroadcastReceiver);
 
         if (mPendingAlarm != null) {
             mAlarmManager.cancel(mPendingAlarm);
@@ -3541,19 +3562,29 @@
     private final BroadcastReceiver mWifiStateBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) && isEnabled()) {
-                NetworkInfo networkInfo = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-                NetworkInfo.DetailedState ds = networkInfo.getDetailedState();
-                if (ds == NetworkInfo.DetailedState.CONNECTED) {
-                    if(isVendorIntfEnabled())
-                        mVendor.setWifiState(true);
-                }
-                else if (ds == NetworkInfo.DetailedState.DISCONNECTED) {
-                    if(isVendorIntfEnabled())
-                        mVendor.setWifiState(false);
-                }
-            }
-        }
+            String action = (intent != null) ? intent.getAction():null;
+            debugLog(action);
+            if (action == null) return;
+            if (isEnabled() && (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION))) {
+                 WifiManager wifiMgr = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+                 if ((wifiMgr != null) && (wifiMgr.isWifiEnabled())) {
+                     WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
+                     if ((wifiInfo != null) && (wifiInfo.getNetworkId() != -1)) {
+                         mVendor.setWifiState(true);
+                     } else {
+                         mVendor.setWifiState(false);
+                     }
+                 }
+             } else if (isEnabled() &&
+                        (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) ||
+                        (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)))){
+                 if (isPowerbackRequired()) {
+                     mVendor.setPowerBackoff(true);
+                 } else {
+                     mVendor.setPowerBackoff(false);
+                 }
+             }
+         }
     };
 
     private boolean isGuest() {
@@ -3578,6 +3609,23 @@
          return obfuscateAddressNative(Utils.getByteAddress(device));
     }
 
+    private boolean isPowerbackRequired() {
+        try {
+
+            WifiManager mWifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
+            final WifiConfiguration config = mWifiManager.getWifiApConfiguration();
+            if ((mWifiManager != null) && ((mWifiManager.isWifiEnabled() ||
+                ((mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) &&
+                (config.apBand == WifiConfiguration.AP_BAND_5GHZ))))) {
+                return true;
+            }
+            return false;
+        } catch(SecurityException e) {
+            debugLog(e.toString());
+        }
+        return false;
+   }
+
     static native void classInitNative();
 
     native boolean initNative(boolean startRestricted, boolean isSingleUserMode);
diff --git a/src/com/android/bluetooth/hfp/HeadsetService.java b/src/com/android/bluetooth/hfp/HeadsetService.java
index e7b51f1..a06b457 100644
--- a/src/com/android/bluetooth/hfp/HeadsetService.java
+++ b/src/com/android/bluetooth/hfp/HeadsetService.java
@@ -128,8 +128,6 @@
     private boolean mIsTwsPlusEnabled = false;
     private boolean mIsTwsPlusShoEnabled = false;
     private vendorhfservice  mVendorHf;
-    private boolean mIsSwbEnabled = false;
-    private boolean mIsSwbPmEnabled = false;
 
     @Override
     public IProfileServiceBinder initBinder() {
@@ -168,24 +166,6 @@
             String twsPlusEnabled = SystemProperties.get("persist.vendor.btstack.enable.twsplus");
             String twsPlusShoEnabled =
                SystemProperties.get("persist.vendor.btstack.enable.twsplussho");
-            String swbEnabled = SystemProperties.get("persist.vendor.btstack.enable.swb");
-            String swbPmEnabled = SystemProperties.get("persist.vendor.btstack.enable.swbpm");
-
-            if(mAdapterService.isSWBVoicewithAptxAdaptiveAG()) {
-               Log.d(TAG, "SWB addon feature supported on FW");
-               if (swbEnabled.isEmpty()) {
-                   SystemProperties.set("persist.vendor.btstack.enable.swb", "true");
-                   SystemProperties.set("persist.vendor.btstack.enable.swbpm", "true");
-                   swbEnabled = "true";
-                   swbPmEnabled = "true";
-               }
-            } else {
-               Log.d(TAG, "SWB addon feature not supported on FW");
-               SystemProperties.set("persist.vendor.btstack.enable.swb", "false");
-               SystemProperties.set("persist.vendor.btstack.enable.swbpm", "false");
-               swbEnabled = "false";
-               swbPmEnabled = "false";
-            }
 
             if (!twsPlusEnabled.isEmpty() && "true".equals(twsPlusEnabled)) {
                 mIsTwsPlusEnabled = true;
@@ -198,16 +178,8 @@
                     mIsTwsPlusShoEnabled = false;
                 }
             }
-            if (!swbEnabled.isEmpty() && "true".equals(swbEnabled)) {
-                mIsSwbEnabled = true;
-            }
-            if (!swbPmEnabled.isEmpty() && "true".equals(swbPmEnabled)) {
-                mIsSwbPmEnabled = true;
-            }
             Log.i(TAG, "mIsTwsPlusEnabled: " + mIsTwsPlusEnabled);
             Log.i(TAG, "mIsTwsPlusShoEnabled: " + mIsTwsPlusShoEnabled);
-            Log.i(TAG, "mIsSwbEnabled: " + mIsSwbEnabled);
-            Log.i(TAG, "mIsSwbPmEnabled: " + mIsSwbPmEnabled);
             if (mIsTwsPlusEnabled && mMaxHeadsetConnections < 2){
                //set MaxConn to 2 if TWSPLUS enabled
                mMaxHeadsetConnections = 2;
@@ -251,7 +223,7 @@
         mHfpA2dpSyncInterface = new HeadsetA2dpSync(mSystemInterface, this);
         if (mVendorHf != null) {
             mVendorHf.init();
-            mVendorHf.enableSwb(mIsSwbEnabled);
+            mVendorHf.enableSwb(isSwbEnabled());
         }
 
         Log.i(TAG, " HeadsetService Started ");
@@ -2451,11 +2423,18 @@
     }
 
     public boolean isSwbEnabled() {
-        return mIsSwbEnabled;
+	if(mAdapterService.isSWBVoicewithAptxAdaptiveAG()) {
+            return mAdapterService.isSwbEnabled();
+        }
+        return false;
     }
 
     public boolean isSwbPmEnabled() {
-        return mIsSwbPmEnabled;
+        if(mAdapterService.isSWBVoicewithAptxAdaptiveAG() &&
+           mAdapterService.isSwbEnabled()) {
+            return mAdapterService.isSwbPmEnabled();
+        }
+        return false;
     }
 
     private static void logD(String message) {