Connect to BLE server by BLE scanning.
Set default text in edittext.

Bug: 18248330
Change-Id: If311b6092a8738f72ca41bb1d8919478d9c75b07
diff --git a/apps/CtsVerifier/res/layout/ble_client_connect.xml b/apps/CtsVerifier/res/layout/ble_client_connect.xml
index 54a0a99..30b4edb 100644
--- a/apps/CtsVerifier/res/layout/ble_client_connect.xml
+++ b/apps/CtsVerifier/res/layout/ble_client_connect.xml
@@ -20,22 +20,19 @@
         android:padding="10dip"
         >
 
-    <LinearLayout android:orientation="horizontal"
+    <LinearLayout android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_centerInParent="true"
             >
-        <EditText android:id="@+id/ble_address"
-                android:layout_weight="1"
-                android:layout_width="0dp"
-                android:layout_height="wrap_content"
-                android:hint="@string/ble_address"
-                />
-        <Button android:id="@+id/ble_connect"
+        <Button android:id="@+id/ble_scan_start"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:text="@string/ble_connect"
-                />
+                android:text="@string/ble_scan_start"/>
+        <Button android:id="@+id/ble_scan_stop"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/ble_scan_stop"/>
     </LinearLayout>
 
     <include android:layout_width="match_parent"
@@ -43,4 +40,4 @@
             android:layout_alignParentBottom="true"
             layout="@layout/pass_fail_buttons"
             />
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ble_client_read_write.xml b/apps/CtsVerifier/res/layout/ble_client_read_write.xml
index 7edba62..a263916 100644
--- a/apps/CtsVerifier/res/layout/ble_client_read_write.xml
+++ b/apps/CtsVerifier/res/layout/ble_client_read_write.xml
@@ -32,6 +32,7 @@
                     android:layout_width="0dp"
                     android:layout_weight="1"
                     android:layout_height="wrap_content"
+                    android:text="@string/ble_test_text"
                     android:hint="@string/ble_write_hint"
                     android:padding="10dip"
                     />
@@ -67,4 +68,4 @@
             android:layout_alignParentBottom="true"
             layout="@layout/pass_fail_buttons"
             />
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ble_reliable_write.xml b/apps/CtsVerifier/res/layout/ble_reliable_write.xml
index 7db78ff..05b1812 100644
--- a/apps/CtsVerifier/res/layout/ble_reliable_write.xml
+++ b/apps/CtsVerifier/res/layout/ble_reliable_write.xml
@@ -27,6 +27,7 @@
         <EditText android:id="@+id/write_text"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:text="@string/ble_test_text"
                 android:hint="@string/ble_write_hint"
                 android:padding="5dip"
                 />
@@ -60,4 +61,4 @@
             android:layout_alignParentBottom="true"
             layout="@layout/pass_fail_buttons"
             />
-</RelativeLayout>
\ No newline at end of file
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 9d8287b..e63014b 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -214,6 +214,7 @@
     <string name="ble_waiting_notification">Waiting on notification</string>
     <string name="ble_read_rssi">Read RSSI</string>
     <string name="ble_disconnect">Disconnect</string>
+    <string name="ble_test_text">TEST</string>
 
     <!-- BLE server side strings -->
     <string name="ble_server_service_name">Bluetooth LE GATT Server Handler Service</string>
@@ -263,6 +264,8 @@
     <string name="ble_scanner_scan_filter_instruction">Scan filter is to scan data with service UUID = 0x6666 only. If you scan without scan filter, data with service UUID = 0x5555 and 0x6666 will show up on screen.\nFor monsoon test:\n\tClick scan with filter, lock the screen, connect to monsoon. It will not wake up when advertiser is advertising unscannable data packets, but will show a peak in power usage when advertiser is advertising scannable data.\nFor logcat test:\n\tClick scan with filter, logcat the scanner. No data will be received by GattService when advertiser is advertising unscannable data.</string>
     <string name="ble_scan_with_filter">Scan with filter</string>
     <string name="ble_scan_without_filter">Scan without filter</string>
+    <string name="ble_scan_start">Start scan</string>
+    <string name="ble_scan_stop">Stop scan</string>
 
     <!-- Strings for FeatureSummaryActivity -->
     <string name="feature_summary">Hardware/Software Feature Summary</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
index fb351b1..4e1c268 100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientConnectActivity.java
@@ -45,22 +45,25 @@
                          R.string.ble_client_send_connect_info, -1);
         getPassButton().setEnabled(false);
 
-        mEditText = (EditText) findViewById(R.id.ble_address);
-
-        ((Button) findViewById(R.id.ble_connect)).setOnClickListener(new OnClickListener() {
+        ((Button) findViewById(R.id.ble_scan_start)).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
-                String address = mEditText.getText().toString();
-                if (!BluetoothAdapter.checkBluetoothAddress(address)) {
-                    showMessage("Invalid bluetooth address.");
-                } else {
-                    Intent intent = new Intent(BleClientConnectActivity.this,
-                                               BleClientService.class);
-                    intent.putExtra(BleClientService.EXTRA_COMMAND,
-                                    BleClientService.COMMAND_CONNECT);
-                    intent.putExtra(BluetoothDevice.EXTRA_DEVICE, address);
-                    startService(intent);
-                }
+                Intent intent = new Intent(BleClientConnectActivity.this,
+                        BleClientService.class);
+                intent.putExtra(BleClientService.EXTRA_COMMAND,
+                        BleClientService.COMMAND_SCAN_START);
+                startService(intent);
+            }
+        });
+
+        ((Button) findViewById(R.id.ble_scan_stop)).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Intent intent = new Intent(BleClientConnectActivity.this,
+                        BleClientService.class);
+                intent.putExtra(BleClientService.EXTRA_COMMAND,
+                        BleClientService.COMMAND_SCAN_STOP);
+                startService(intent);
             }
         });
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
index 556ad06..6765362 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleClientService.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.bluetooth;
 
+import java.util.Arrays;
 import java.util.UUID;
 import java.util.List;
 
@@ -29,10 +30,16 @@
 import android.bluetooth.BluetoothGattService;
 import android.bluetooth.BluetoothManager;
 import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ParcelUuid;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -53,6 +60,8 @@
     public static final int COMMAND_BEGIN_WRITE = 9;
     public static final int COMMAND_EXECUTE_WRITE = 10;
     public static final int COMMAND_ABORT_RELIABLE = 11;
+    public static final int COMMAND_SCAN_START = 12;
+    public static final int COMMAND_SCAN_STOP = 13;
 
     public static final String BLE_BLUETOOTH_CONNECTED =
             "com.android.cts.verifier.bluetooth.BLE_BLUETOOTH_CONNECTED";
@@ -102,6 +111,8 @@
     private BluetoothDevice mDevice;
     private BluetoothGatt mBluetoothGatt;
     private Handler mHandler;
+    private Context mContext;
+    private BluetoothLeScanner mScanner;
 
     @Override
     public void onCreate() {
@@ -110,6 +121,8 @@
         mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
         mBluetoothAdapter = mBluetoothManager.getAdapter();
         mHandler = new Handler();
+        mContext = this;
+        mScanner = mBluetoothAdapter.getBluetoothLeScanner();
     }
 
     @Override
@@ -128,6 +141,7 @@
         super.onDestroy();
         mBluetoothGatt.disconnect();
         mBluetoothGatt.close();
+        stopScan();
     }
 
     private void handleIntent(Intent intent) {
@@ -177,6 +191,12 @@
             case COMMAND_ABORT_RELIABLE:
                 if (mBluetoothGatt != null) mBluetoothGatt.abortReliableWrite(mDevice);
                 break;
+            case COMMAND_SCAN_START:
+                startScan();
+                break;
+            case COMMAND_SCAN_STOP:
+                stopScan();
+                break;
             default:
                 showMessage("Unrecognized command: " + command);
                 break;
@@ -343,8 +363,8 @@
         @Override
         public void onCharacteristicWrite(BluetoothGatt gatt,
                                           BluetoothGattCharacteristic characteristic, int status) {
-            if (DEBUG) Log.d(TAG, "onCharacteristicWrite: characteristic.val=" + characteristic.getStringValue(0)
-                                  + " status=" + status);
+            if (DEBUG) Log.d(TAG, "onCharacteristicWrite: characteristic.val="
+                    + characteristic.getStringValue(0) + " status=" + status);
             BluetoothGattCharacteristic mCharacteristic = getCharacteristic(CHARACTERISTIC_UUID);
             if ((status == BluetoothGatt.GATT_SUCCESS) &&
                 (characteristic.getStringValue(0).equals(mCharacteristic.getStringValue(0)))) {
@@ -387,4 +407,25 @@
             if (status == BluetoothGatt.GATT_SUCCESS) notifyReadRemoteRssi(rssi);
         }
     };
-}
\ No newline at end of file
+
+    private final ScanCallback mScanCallback = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            mBluetoothGatt = result.getDevice().connectGatt(mContext, false, mGattCallbacks);
+        }
+    };
+
+    private void startScan() {
+        if (DEBUG) Log.d(TAG, "startScan");
+        List<ScanFilter> filter = Arrays.asList(new ScanFilter.Builder().setServiceUuid(
+                new ParcelUuid(BleServerService.ADV_SERVICE_UUID)).build());
+        ScanSettings setting = new ScanSettings.Builder()
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).build();
+        mScanner.startScan(filter, setting, mScanCallback);
+    }
+
+    private void stopScan() {
+        if (DEBUG) Log.d(TAG, "stopScan");
+        mScanner.stopScan(mScanCallback);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReadWriteActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReadWriteActivity.java
index 22233ef..8041ce0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReadWriteActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReadWriteActivity.java
@@ -124,4 +124,4 @@
             }
         }
     };
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReliableWriteActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReliableWriteActivity.java
index c7460b5..9b65bb4 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReliableWriteActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleReliableWriteActivity.java
@@ -114,4 +114,4 @@
             }
         }
     };
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
index 91b3a6c..8718f57 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
@@ -33,10 +33,15 @@
 import android.bluetooth.BluetoothGattService;
 import android.bluetooth.BluetoothManager;
 import android.bluetooth.BluetoothProfile;
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseData;
+import android.bluetooth.le.AdvertiseSettings;
+import android.bluetooth.le.BluetoothLeAdvertiser;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.ParcelUuid;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -76,6 +81,8 @@
             UUID.fromString("00009997-0000-1000-8000-00805f9b34fb");
     private static final UUID DESCRIPTOR_UUID =
             UUID.fromString("00009996-0000-1000-8000-00805f9b34fb");
+    public static final UUID ADV_SERVICE_UUID=
+            UUID.fromString("00003333-0000-1000-8000-00805f9b34fb");
 
     private BluetoothManager mBluetoothManager;
     private BluetoothGattServer mGattServer;
@@ -84,12 +91,14 @@
     private Timer mNotificationTimer;
     private Handler mHandler;
     private String mReliableWriteValue;
+    private BluetoothLeAdvertiser mAdvertiser;
 
     @Override
     public void onCreate() {
         super.onCreate();
 
         mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
+        mAdvertiser = mBluetoothManager.getAdapter().getBluetoothLeAdvertiser();
         mGattServer = mBluetoothManager.openGattServer(this, mCallbacks);
         mService = createService();
         if (mGattServer != null) {
@@ -106,6 +115,7 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
+        startAdvertise();
         return START_NOT_STICKY;
     }
 
@@ -117,6 +127,7 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
+        stopAdvertise();
         if (mGattServer == null) {
            return;
         }
@@ -366,5 +377,26 @@
             }
         }
     };
+
+    private void startAdvertise() {
+        if (DEBUG) Log.d(TAG, "startAdvertise");
+        AdvertiseData data = new AdvertiseData.Builder()
+            .addServiceData(new ParcelUuid(ADV_SERVICE_UUID), new byte[]{1,2,3})
+            .addServiceUuid(new ParcelUuid(ADV_SERVICE_UUID))
+            .build();
+        AdvertiseSettings setting = new AdvertiseSettings.Builder()
+            .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
+            .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
+            .setConnectable(true)
+            .build();
+        mAdvertiser.startAdvertising(setting, data, mAdvertiseCallback);
+    }
+
+    private void stopAdvertise() {
+        if (DEBUG) Log.d(TAG, "stopAdvertise");
+        mAdvertiser.stopAdvertising(mAdvertiseCallback);
+    }
+
+    private final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback(){};
 }