Bluetooth Security Test

Bug 4793037

Add another Bluetooth test that requires two Android Bluetooth
devices. The test uses a specific UUID and checks that a
connection access request dialog was shown.

Change-Id: I786bd05ab5440f99855c8e89c6e2d901b0777355
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index d4926a0..825b518 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -149,8 +149,30 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/bt_device_communication" />
             <meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
-        </activity>       
+        </activity>
+
+        <activity android:name=".bluetooth.ConnectionAccessServerActivity"
+                android:label="@string/bt_connection_access_server"
+                android:configChanges="keyboardHidden|orientation">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/bt_device_communication" />
+            <meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+        </activity>
         
+        <activity android:name=".bluetooth.ConnectionAccessClientActivity"
+                android:label="@string/bt_connection_access_client"
+                android:configChanges="keyboardHidden|orientation">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST" />
+            </intent-filter>
+            <meta-data android:name="test_category" android:value="@string/bt_device_communication" />
+            <meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
+        </activity>
+
         <activity android:name=".bluetooth.DevicePickerActivity"
                 android:label="@string/bt_device_picker"
                 android:configChanges="keyboardHidden|orientation" />
diff --git a/apps/CtsVerifier/res/layout/bt_connection_access.xml b/apps/CtsVerifier/res/layout/bt_connection_access.xml
new file mode 100644
index 0000000..ae373f4
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/bt_connection_access.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    <ScrollView android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            >
+        <TextView android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/bt_ca_tips"
+                style="@style/InstructionsFont"
+                />
+    </ScrollView>
+
+    <LinearLayout android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            >
+        <Button android:id="@+id/bt_make_discoverable_button"
+                android:layout_width="1dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:drawableTop="@android:drawable/ic_menu_mylocation"
+                android:text="@string/bt_make_discoverable"
+                android:visibility="gone"
+                />
+        <Button android:id="@+id/bt_pick_server_button"
+                android:layout_width="1dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:drawableTop="@android:drawable/ic_menu_mylocation"
+                android:text="@string/bt_pick_server"
+                android:visibility="gone"
+                />
+        <Button android:id="@+id/bt_settings"
+                android:layout_width="1dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:drawableTop="@android:drawable/ic_menu_preferences"
+                android:text="@string/bt_settings"
+                />
+    </LinearLayout>
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/bt_toggle.xml b/apps/CtsVerifier/res/layout/bt_toggle.xml
index 3a07514..71def84 100644
--- a/apps/CtsVerifier/res/layout/bt_toggle.xml
+++ b/apps/CtsVerifier/res/layout/bt_toggle.xml
@@ -24,7 +24,7 @@
             android:layout_alignParentTop="true"
             android:gravity="center"
             android:text="@string/bt_toggle_instructions"
-            android:textSize="24dip"
+            style="@style/InstructionsFont"
             />
 
     <ToggleButton android:id="@+id/bt_toggle_button"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 75c73aa..e621335 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -132,16 +132,43 @@
     <string name="bt_disabling">Disabling Bluetooth...</string>
     <string name="bt_disabling_error">Could not disable Bluetooth...</string>
 
+    <string name="bt_connection_access_server">Connection Access Server</string>
+    <string name="bt_connection_access_client">Connection Access Client</string>
+    <string name="bt_connection_access_server_info">
+        Start the CTS Verifier on another device, start the Bluetooth test, and choose
+        \"Connection Access Client\" to setup the test. 
+        \n\nFirst, unpair the devices via Bluetooth settings. Then connect the devices together 
+        using the \"Make Discoverable\" and \"Pick Server\" buttons.
+        \n\nA connection access request should appear on the server and enable the pass button.
+    </string>
+    <string name="bt_connection_access_client_info">
+        Start the CTS Verifier on another device, start the Bluetooth test, and choose
+        \"Connection Access Server\" to complete the test. 
+        \n\nMake the device acting as the server discoverable and connect to it via the 
+        \"Pick Server\" button. Check that the server displays the connection access request 
+        dialog. The client device does not need to do anything else.
+    </string>
+    <string name="bt_ca_dialog">Was the connection access request dialog shown?</string>
+    <string name="bt_ca_tips">
+        Tap the \"Bluetooth Settings\" button and check that both devices are not paired
+        before running the test.
+        \n\nUse the \"Make Discoverable\" and \"Pick Server\" buttons to connect the two Bluetooth
+        devices together and start the test.
+    </string>
+
     <string name="bt_secure_server">Secure Server</string>
     <string name="bt_secure_server_instructions">Start the CTS Verifier on another device, start the Bluetooth test, and choose \"Secure Client\" to complete the test.</string>
     <string name="bt_insecure_server">Insecure Server</string>
     <string name="bt_insecure_server_instructions">Start the CTS Verifier on another device, start the Bluetooth test, and choose \"Insecure Client\" to complete the test.</string>
     <string name="bt_waiting">Waiting for client...</string>
+    <string name="bt_listening">Listening...</string>
     <string name="bt_connecting">Connecting...</string>
+    <string name="bt_connected">Connected</string>
     <string name="bt_received_messages">Received Messages</string>
     <string name="bt_sent_messages">Sent Messages</string>
     <string name="bt_no_messages">No messages</string>
     <string name="bt_make_discoverable">Make Discoverable</string>
+    <string name="bt_pick_server">Pick Server</string>
     <string name="bt_insecure_pairing_error_title">Pairing dialog shown?</string>
     <string name="bt_insecure_pairing_error_message">Insecure connections should not show the pairing dialog!</string>
 
diff --git a/apps/CtsVerifier/res/values/styles.xml b/apps/CtsVerifier/res/values/styles.xml
index c7fe859..b5dd7cc 100644
--- a/apps/CtsVerifier/res/values/styles.xml
+++ b/apps/CtsVerifier/res/values/styles.xml
@@ -3,6 +3,9 @@
     <style name="WelcomeFont" parent="@android:style/TextAppearance.Large">
         <item name="android:textColor">#9fbf3b</item>
     </style>
+    <style name="InstructionsFont" parent="@android:style/TextAppearance.Large">
+        <item name="android:padding">10dp</item>
+    </style>
     <style name="VersionFont" parent="@android:style/TextAppearance.Large">
         <item name="android:textColor">#ffffff</item>
     </style>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothChatService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothChatService.java
index 05c50e3..6eb587f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothChatService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BluetoothChatService.java
@@ -49,6 +49,13 @@
     public static final String DEVICE_NAME = "device_name";
     public static final String TOAST = "toast";
 
+    static final UUID SECURE_UUID =
+            UUID.fromString("8591d757-18ee-45e1-9b12-92875d06ba23");
+    static final UUID INSECURE_UUID =
+            UUID.fromString("301c214f-91a2-43bf-a795-09d1198a81a7");
+    static final UUID HANDSFREE_INSECURE_UUID =
+            UUID.fromString("0000111F-0000-1000-8000-00805F9B34FB");
+
     // Debugging
     private static final String TAG = "CtsBluetoothChatService";
     private static final boolean D = true;
@@ -57,15 +64,10 @@
     private static final String NAME_SECURE = "CtsBluetoothChatSecure";
     private static final String NAME_INSECURE = "CtsBluetoothChatInsecure";
 
-    // Unique UUID for this application
-    private static final UUID MY_UUID_SECURE =
-        UUID.fromString("8591d757-18ee-45e1-9b12-92875d06ba23");
-    private static final UUID MY_UUID_INSECURE =
-        UUID.fromString("301c214f-91a2-43bf-a795-09d1198a81a7");
-
     // Member fields
     private final BluetoothAdapter mAdapter;
     private final Handler mHandler;
+    private final UUID mUuid;
     private AcceptThread mSecureAcceptThread;
     private AcceptThread mInsecureAcceptThread;
     private ConnectThread mConnectThread;
@@ -83,10 +85,11 @@
      * @param context  The UI Activity Context
      * @param handler  A Handler to send messages back to the UI Activity
      */
-    public BluetoothChatService(Context context, Handler handler) {
+    public BluetoothChatService(Context context, Handler handler, UUID uuid) {
         mAdapter = BluetoothAdapter.getDefaultAdapter();
         mState = STATE_NONE;
         mHandler = handler;
+        mUuid = uuid;
     }
 
     /**
@@ -279,11 +282,9 @@
             // Create a new listening server socket
             try {
                 if (secure) {
-                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
-                        MY_UUID_SECURE);
+                    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, mUuid);
                 } else {
-                    tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
-                            NAME_INSECURE, MY_UUID_INSECURE);
+                    tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, mUuid);
                 }
             } catch (IOException e) {
                 Log.e(TAG, "Socket Type: " + mSocketType + " listen() failed", e);
@@ -368,11 +369,9 @@
             // given BluetoothDevice
             try {
                 if (secure) {
-                    tmp = device.createRfcommSocketToServiceRecord(
-                            MY_UUID_SECURE);
+                    tmp = device.createRfcommSocketToServiceRecord(mUuid);
                 } else {
-                    tmp = device.createInsecureRfcommSocketToServiceRecord(
-                            MY_UUID_INSECURE);
+                    tmp = device.createInsecureRfcommSocketToServiceRecord(mUuid);
                 }
             } catch (IOException e) {
                 Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessClientActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessClientActivity.java
new file mode 100644
index 0000000..5befdaf
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessClientActivity.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.bluetooth;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class ConnectionAccessClientActivity extends PassFailButtons.Activity {
+
+    private static final int ENABLE_BLUETOOTH_REQUEST = 1;
+    private static final int PICK_SERVER_DEVICE_REQUEST = 2;
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private BluetoothChatService mChatService;
+    private String mDeviceAddress;
+    private Button mPickServerButton;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.bt_connection_access);
+        setInfoResources(R.string.bt_connection_access_client,
+                R.string.bt_connection_access_client_info, 0);
+        setPassFailButtonClickListeners();
+
+        View settings = findViewById(R.id.bt_settings);
+        settings.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+            }
+        });
+
+        mPickServerButton = (Button) findViewById(R.id.bt_pick_server_button);
+        mPickServerButton.setVisibility(View.VISIBLE);
+        mPickServerButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                startDevicePickerActivity();
+            }
+        });
+
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (!mBluetoothAdapter.isEnabled()) {
+            mPickServerButton.setEnabled(false);
+            startEnableBluetoothActivity();
+        }
+    }
+
+    private void startDevicePickerActivity() {
+        Intent intent = new Intent(this, DevicePickerActivity.class);
+        startActivityForResult(intent, PICK_SERVER_DEVICE_REQUEST);
+    }
+
+    private void startEnableBluetoothActivity() {
+        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+        startActivityForResult(intent, ENABLE_BLUETOOTH_REQUEST);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+            case ENABLE_BLUETOOTH_REQUEST:
+                if (resultCode == RESULT_OK) {
+                    mPickServerButton.setEnabled(true);
+                } else {
+                    setResult(RESULT_CANCELED);
+                    finish();
+                }
+                break;
+
+            case PICK_SERVER_DEVICE_REQUEST:
+                if (resultCode == RESULT_OK) {
+                    mDeviceAddress = data.getStringExtra(DevicePickerActivity.EXTRA_DEVICE_ADDRESS);
+                    startChartService();
+                }
+                break;
+        }
+    }
+
+    private void startChartService() {
+        mChatService = new BluetoothChatService(this, new ChatHandler(),
+                BluetoothChatService.HANDSFREE_INSECURE_UUID);
+        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mDeviceAddress);
+        mChatService.connect(device, false);
+    }
+
+    private class ChatHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what) {
+                case BluetoothChatService.MESSAGE_STATE_CHANGE:
+                    handleStateChange(msg);
+                    break;
+
+                case BluetoothChatService.MESSAGE_DEVICE_NAME:
+                    handleDeviceName(msg);
+                    break;
+
+                case BluetoothChatService.MESSAGE_TOAST:
+                    handleToast(msg);
+                    break;
+            }
+        }
+    }
+
+    private void handleStateChange(Message msg) {
+        int state = msg.arg1;
+        switch (state) {
+            case BluetoothChatService.STATE_CONNECTING:
+                setProgressBarIndeterminateVisibility(true);
+                Toast.makeText(this, R.string.bt_connecting, Toast.LENGTH_SHORT).show();
+                break;
+
+            case BluetoothChatService.STATE_CONNECTED:
+                setProgressBarIndeterminateVisibility(false);
+                Toast.makeText(this, R.string.bt_connected, Toast.LENGTH_SHORT).show();
+                break;
+
+            case BluetoothChatService.STATE_NONE:
+                setProgressBarIndeterminateVisibility(false);
+                break;
+        }
+    }
+
+    private void handleDeviceName(Message msg) {
+        mDeviceAddress = msg.getData().getString(BluetoothChatService.DEVICE_NAME);
+    }
+
+    private void handleToast(Message msg) {
+        String toast = msg.getData().getString(BluetoothChatService.TOAST);
+        Toast.makeText(this, toast, Toast.LENGTH_SHORT).show();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessServerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessServerActivity.java
new file mode 100644
index 0000000..19c46af
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/ConnectionAccessServerActivity.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.cts.verifier.bluetooth;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.TextView;
+import android.widget.Toast;
+
+public class ConnectionAccessServerActivity extends PassFailButtons.Activity {
+
+    private static final String ACTION_CONNECTION_ACCESS_REQUEST =
+            "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
+
+    private static final int ENABLE_BLUETOOTH_REQUEST = 1;
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private ConnectionAccessRequestReceiver mConnectionAccessRequestReceiver;
+    private BluetoothChatService mChatService;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+        setContentView(R.layout.bt_connection_access);
+        setInfoResources(R.string.bt_connection_access_server,
+                R.string.bt_connection_access_server_info, 0);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        View settings = findViewById(R.id.bt_settings);
+        settings.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+            }
+        });
+
+        Button makeDiscoverableButton = (Button) findViewById(R.id.bt_make_discoverable_button);
+        makeDiscoverableButton.setVisibility(View.VISIBLE);
+        makeDiscoverableButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                makeDiscoverable();
+            }
+        });
+
+        mConnectionAccessRequestReceiver = new ConnectionAccessRequestReceiver();
+        IntentFilter intentFilter = new IntentFilter(ACTION_CONNECTION_ACCESS_REQUEST);
+        registerReceiver(mConnectionAccessRequestReceiver, intentFilter);
+
+        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mBluetoothAdapter.isEnabled()) {
+            startChatService();
+        } else {
+            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
+            startActivityForResult(intent, ENABLE_BLUETOOTH_REQUEST);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+            case ENABLE_BLUETOOTH_REQUEST:
+                if (resultCode == RESULT_OK) {
+                    startChatService();
+                } else {
+                    setResult(RESULT_CANCELED);
+                    finish();
+                }
+                break;
+        }
+    }
+
+    private void startChatService() {
+        mChatService = new BluetoothChatService(this, new ChatHandler(),
+                BluetoothChatService.HANDSFREE_INSECURE_UUID);
+        boolean secure = false;
+        mChatService.start(secure);
+    }
+
+    private void makeDiscoverable() {
+        if (mBluetoothAdapter.getScanMode() !=
+                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+            intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 30);
+            startActivity(intent);
+        }
+    }
+
+    private class ChatHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch (msg.what) {
+                case BluetoothChatService.MESSAGE_STATE_CHANGE:
+                    handleStateChange(msg);
+                    break;
+
+                case BluetoothChatService.MESSAGE_TOAST:
+                    handleToast(msg);
+                    break;
+            }
+        }
+    }
+
+    private void handleStateChange(Message msg) {
+        int state = msg.arg1;
+        switch (state) {
+            case BluetoothChatService.STATE_LISTEN:
+                setProgressBarIndeterminateVisibility(true);
+                Toast.makeText(this, R.string.bt_listening, Toast.LENGTH_SHORT).show();
+                break;
+        }
+    }
+
+    private void handleToast(Message msg) {
+        String toast = msg.getData().getString(BluetoothChatService.TOAST);
+        Toast.makeText(this, toast, Toast.LENGTH_LONG).show();
+    }
+
+    class ConnectionAccessRequestReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            new AlertDialog.Builder(ConnectionAccessServerActivity.this)
+                    .setMessage(R.string.bt_ca_dialog)
+                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            getPassButton().setEnabled(true);
+                        }
+                    })
+                    .setNegativeButton(android.R.string.cancel,
+                            new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            getPassButton().setEnabled(false);
+                        }
+                    })
+                    .show();
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mChatService != null) {
+            mChatService.stop();
+        }
+        unregisterReceiver(mConnectionAccessRequestReceiver);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureClientActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureClientActivity.java
index 6dfbbea..da1f369 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureClientActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureClientActivity.java
@@ -18,6 +18,6 @@
 
 public class InsecureClientActivity extends MessageTestActivity {
     public InsecureClientActivity() {
-        super(false, false);
+        super(false, false, BluetoothChatService.INSECURE_UUID);
     }
-}
\ No newline at end of file
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureServerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureServerActivity.java
index 3526e04..31ae7d8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureServerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/InsecureServerActivity.java
@@ -18,6 +18,6 @@
 
 public class InsecureServerActivity extends MessageTestActivity {
     public InsecureServerActivity() {
-        super(false, true);
+        super(false, true, BluetoothChatService.INSECURE_UUID);
     }
 }
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
index 28a711a..c730aed 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/MessageTestActivity.java
@@ -40,6 +40,7 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -71,15 +72,18 @@
     private AlertDialog mInstructionsDialog;
 
     private String mDeviceAddress;
-    private boolean mSecure;
-    private boolean mServer;
+
+    private final boolean mSecure;
+    private final boolean mServer;
+    private final UUID mUuid;
 
     private String mRemoteDeviceName = "";
     private StringBuilder mMessageBuffer = new StringBuilder();
 
-    MessageTestActivity(boolean secure, boolean server) {
+    MessageTestActivity(boolean secure, boolean server, UUID uuid) {
         mSecure = secure;
         mServer = server;
+        mUuid = uuid;
     }
 
     @Override
@@ -166,7 +170,7 @@
     }
 
     private void startChatService() {
-        mChatService = new BluetoothChatService(this, new ChatHandler());
+        mChatService = new BluetoothChatService(this, new ChatHandler(), mUuid);
         if (mServer) {
             mChatService.start(mSecure);
         } else {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureClientActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureClientActivity.java
index 799f0b8..ad908b5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureClientActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureClientActivity.java
@@ -18,6 +18,6 @@
 
 public class SecureClientActivity extends MessageTestActivity {
     public SecureClientActivity() {
-        super(true, false);
+        super(true, false, BluetoothChatService.SECURE_UUID);
     }
 }
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureServerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureServerActivity.java
index 25e26e6..df50026 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureServerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/SecureServerActivity.java
@@ -18,6 +18,6 @@
 
 public class SecureServerActivity extends MessageTestActivity {
     public SecureServerActivity() {
-        super(true, true);
+        super(true, true, BluetoothChatService.SECURE_UUID);
     }
 }
\ No newline at end of file