set softAP on a specified band, including both 2.4 and 5 GHz band

Bug:18929692
Change-Id: I6109b477937b0ecab95f5a2b414f2bec9b30e1cd
diff --git a/api/current.txt b/api/current.txt
index 1f86b03..f556abe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -17899,6 +17899,7 @@
 
   public class WifiConfiguration implements android.os.Parcelable {
     ctor public WifiConfiguration();
+    method public static int chooseApChannel(int);
     method public int describeContents();
     method public void writeToParcel(android.os.Parcel, int);
     field public java.lang.String BSSID;
@@ -17909,6 +17910,8 @@
     field public java.util.BitSet allowedKeyManagement;
     field public java.util.BitSet allowedPairwiseCiphers;
     field public java.util.BitSet allowedProtocols;
+    field public int apBand;
+    field public int apChannel;
     field public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
     field public boolean hiddenSSID;
     field public int networkId;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 748018d..891f572 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1352,8 +1352,15 @@
             if (wifiConfig == null) {
                 mConnector.execute("softap", "set", wlanIface);
             } else {
+                int apChannel;
+                if (wifiConfig.apChannel == 0) {
+                    apChannel = WifiConfiguration.chooseApChannel(wifiConfig.apBand);
+                } else {
+                    apChannel = wifiConfig.apChannel;
+                }
                 mConnector.execute("softap", "set", wlanIface, wifiConfig.SSID,
-                                   "broadcast", "6", getSecurityType(wifiConfig),
+                                   "broadcast", Integer.toString(apChannel),
+                                   getSecurityType(wifiConfig),
                                    new SensitiveArg(wifiConfig.preSharedKey));
             }
             mConnector.execute("softap", "startap");
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 6543c03..8b24f9f 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -25,8 +25,11 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.TextUtils;
+import android.util.Log;
 import android.annotation.SystemApi;
 
+import java.util.Random;
+import java.util.Calendar;
 import java.util.HashMap;
 import java.util.BitSet;
 import java.util.ArrayList;
@@ -59,6 +62,9 @@
     public static final String updateIdentiferVarName = "update_identifier";
     /** {@hide} */
     public static final int INVALID_NETWORK_ID = -1;
+    /**{@hide}*/
+    private static Random mRandom = new Random(Calendar.getInstance().getTimeInMillis());
+
     /**
      * Recognized key management schemes.
      */
@@ -233,6 +239,22 @@
      * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
      */
     public String BSSID;
+
+    /**
+     * The band which AP resides on
+     * 0-2G  1-5G
+     * By default, 2G is chosen
+     */
+    public int apBand = 0;
+
+    /**
+     * The channel which AP resides on,currently, US only
+     * 2G  1-11
+     * 5G  36,40,44,48,149,153,157,161,165
+     * 0 - find a random available channel according to the apBand
+     */
+    public int apChannel = 0;
+
     /**
      * Fully qualified domain name (FQDN) of AAA server or RADIUS server
      * e.g. {@code "mail.example.com"}.
@@ -1315,6 +1337,18 @@
         }
     }
 
+    public static int chooseApChannel(int apBand) {
+        int apChannel;
+        if (apBand == 0) {
+            apChannel = 1 + mRandom.nextInt(11);
+        } else {
+            int channel[] = {36,40,44,48,149,153,157,161,165};
+            apChannel = channel[mRandom.nextInt(channel.length)];
+        }
+        Log.d(TAG, "AP set on channel " +  apChannel);
+        return apChannel;
+     }
+
     /** @hide */
     public int getAuthType() {
         if (isValid() == false) {
@@ -1464,6 +1498,9 @@
             naiRealm = source.naiRealm;
             preSharedKey = source.preSharedKey;
 
+            apBand = source.apBand;
+            apChannel = source.apChannel;
+
             wepKeys = new String[4];
             for (int i = 0; i < wepKeys.length; i++) {
                 wepKeys[i] = source.wepKeys[i];
@@ -1553,6 +1590,8 @@
         dest.writeInt(disableReason);
         dest.writeString(SSID);
         dest.writeString(BSSID);
+        dest.writeInt(apBand);
+        dest.writeInt(apChannel);
         dest.writeString(autoJoinBSSID);
         dest.writeString(FQDN);
         dest.writeString(naiRealm);
@@ -1615,6 +1654,8 @@
                 config.disableReason = in.readInt();
                 config.SSID = in.readString();
                 config.BSSID = in.readString();
+                config.apBand = in.readInt();
+                config.apChannel = in.readInt();
                 config.autoJoinBSSID = in.readString();
                 config.FQDN = in.readString();
                 config.naiRealm = in.readString();