Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bfe03e4 authored by Srinu Jella's avatar Srinu Jella Committed by Linux Build Service Account
Browse files

Bluetooth: SAP: Add SAP profile support in Settings APP

- Handles 16 digit Authentication
- Added Handles SAP profile connection status changes
- Added SAP Disconnect from server related changes

Change-Id: I655a8c8bcdcc275c5d95c8ddd3d7bac2691fa818
(cherry picked from commit d17f03934b2582637f9d059fccccaabbc4203994)
(cherry picked from commit 26fd639eaeacb7dc5d82c9ef9cf5b5eb5fc70b4f)
(cherry picked from commit c63c73ebf900091b67a951e004573c03ea53e01a)
parent 97c0e1dd
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1059,6 +1059,9 @@
    <!-- Message when bluetooth dialog for pin entry is showing. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_enter_pin_msg">To pair with:<xliff:g id="bold">&lt;br>&lt;b></xliff:g><xliff:g id="device_name">%1$s</xliff:g><xliff:g id="end_bold">&lt;/b>&lt;br>&lt;br></xliff:g>Type the device\'s required PIN:</string>

    <!-- Message when bluetooth dialog for pin entry is showing  when HIGH security enabled-->
    <string name="bluetooth_enter_pin_msg_hs">\nType PIN to pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022. [High Security Enabled: Needs 16 character key] </string>

    <!-- Message when bluetooth dialog for passkey entry is showing. [CHAR LIMIT=NONE] -->
    <string name="bluetooth_enter_passkey_msg">To pair with:<xliff:g id="bold">&lt;br>&lt;b></xliff:g><xliff:g id="device_name">%1$s</xliff:g><xliff:g id="end_bold">&lt;/b>&lt;br>&lt;br></xliff:g>Type the device\'s required passkey:</string>

@@ -1152,6 +1155,8 @@
    <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the map profile. -->
    <string name="bluetooth_profile_map">Message Access</string>

    <!-- Bluetooth settings.  The user-visible string that is used whenever referring to the SAP profile. -->
    <string name="bluetooth_profile_sap">SIM Access</string>
    <!-- Bluetooth settings.  Message for disconnecting from the A2DP profile. [CHAR LIMIT=80] -->
    <string name="bluetooth_disconnect_a2dp_profile"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected from media audio.</string>
    <!-- Bluetooth settings.  Message for disconnecting from the headset profile. [CHAR LIMIT=80] -->
@@ -1185,6 +1190,8 @@
    <string name="bluetooth_opp_profile_summary_connected">Connected to file transfer server</string>
    <!-- Bluetooth settings.  Connection options screen.  The summary for the map checkbox preference when map is connected. -->
    <string name="bluetooth_map_profile_summary_connected">Connected to map</string>
    <!-- Bluetooth settings.  Connection options screen.  The summary for the SAP checkbox preference when SAP is connected. -->
    <string name="bluetooth_sap_profile_summary_connected">Connected to SIM Access Server</string>
    <!-- Bluetooth settings.  Connection options screen.  The summary for the OPP checkbox preference when OPP is not connected. -->
    <string name="bluetooth_opp_profile_summary_not_connected">Not connected to file transfer server</string>
    <!-- Bluetooth settings. Connection options screen. The summary for the HID checkbox preference when HID is connected. -->
@@ -1200,6 +1207,8 @@
    <string name="bluetooth_headset_profile_summary_use_for">Use for phone audio</string>
    <!-- Bluetooth settings.  Connection options screen.  The summary for the OPP checkbox preference that describes how checking it will set the OPP profile as preferred. -->
    <string name="bluetooth_opp_profile_summary_use_for">Use for file transfer</string>
    <!-- Bluetooth settings.  Connection options screen.  The summary for the SAP checkbox preference that describes how checking it will set the SAP profile as preferred. -->
    <string name="bluetooth_sap_profile_summary_use_for">Use for SIM Access</string>
    <!-- Bluetooth settings. Connection options screen. The summary
         for the HID checkbox preference that describes how checking it
         will set the HID profile as preferred. -->
+17 −4
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ public final class BluetoothPairingDialog extends AlertActivity implements
    private String mPairingKey;
    private EditText mPairingView;
    private Button mOkButton;
    private boolean mIsSecurityHigh;

    /**
     * Dismiss the dialog if the bond state changes to bonded or none,
@@ -72,8 +73,8 @@ public final class BluetoothPairingDialog extends AlertActivity implements
            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
                                                   BluetoothDevice.ERROR);
                if (bondState == BluetoothDevice.BOND_BONDED ||
                        bondState == BluetoothDevice.BOND_NONE) {
                if (((bondState == BluetoothDevice.BOND_BONDED) && (!mIsSecurityHigh) ) ||
                    (bondState == BluetoothDevice.BOND_NONE)) {
                    dismiss();
                }
            } else if (BluetoothDevice.ACTION_PAIRING_CANCEL.equals(action)) {
@@ -108,6 +109,8 @@ public final class BluetoothPairingDialog extends AlertActivity implements

        mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        mType = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
        mIsSecurityHigh = intent.getBooleanExtra(BluetoothDevice.EXTRA_SECURE_PAIRING, false);
        Log.i(TAG, "Secure is " + mIsSecurityHigh);

        switch (mType) {
            case BluetoothDevice.PAIRING_VARIANT_PIN:
@@ -188,7 +191,11 @@ public final class BluetoothPairingDialog extends AlertActivity implements
        int maxLength;
        switch (mType) {
            case BluetoothDevice.PAIRING_VARIANT_PIN:
                if (mIsSecurityHigh)
                    messageId1 = R.string.bluetooth_enter_pin_msg_hs;
                else
                    messageId1 = R.string.bluetooth_enter_pin_msg;

                messageId2 = R.string.bluetooth_enter_pin_other_device;
                // Maximum of 16 characters in a PIN
                maxLength = BLUETOOTH_PIN_MAX_LENGTH;
@@ -301,7 +308,13 @@ public final class BluetoothPairingDialog extends AlertActivity implements

    public void afterTextChanged(Editable s) {
        if (mOkButton != null) {
            mOkButton.setEnabled(s.length() > 0);
            if (s.length() > 0 && !mIsSecurityHigh) {
                mOkButton.setEnabled(true);
            } else if (mIsSecurityHigh && s.length() == BLUETOOTH_PIN_MAX_LENGTH) {
                mOkButton.setEnabled(true);
            } else {
                mOkButton.setEnabled(false);
            }
        }
    }

+2 −0
Original line number Diff line number Diff line
@@ -48,10 +48,12 @@ public final class BluetoothPairingRequest extends BroadcastReceiver {
                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                    BluetoothDevice.ERROR);
            boolean secure = intent.getBooleanExtra(BluetoothDevice.EXTRA_SECURE_PAIRING, false);
            Intent pairingIntent = new Intent();
            pairingIntent.setClass(context, BluetoothPairingDialog.class);
            pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
            pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, type);
            pairingIntent.putExtra(BluetoothDevice.EXTRA_SECURE_PAIRING, secure);
            if (type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION ||
                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY ||
                    type == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
+10 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothMap;
import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothPbap;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
@@ -38,6 +39,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.List;
import android.os.SystemProperties;

/**
 * LocalBluetoothProfileManager provides access to the LocalBluetoothProfile
@@ -84,6 +86,7 @@ final class LocalBluetoothProfileManager {
    private final HidProfile mHidProfile;
    private OppProfile mOppProfile;
    private final PanProfile mPanProfile;
    private SapServerProfile mSapProfile;
    private final PbapServerProfile mPbapProfile;

    /**
@@ -126,6 +129,13 @@ final class LocalBluetoothProfileManager {
                mDeviceManager, this);
        addProfile(mMapProfile, MapProfile.NAME,
                BluetoothMap.ACTION_CONNECTION_STATE_CHANGED);
        // enable SAP only if the property is set
        if(SystemProperties.getBoolean("ro.bluetooth.sap", false) == true) {
            mSapProfile = new SapServerProfile(context);
            addProfile(mSapProfile, SapServerProfile.NAME,
                    BluetoothSap.ACTION_CONNECTION_STATE_CHANGED);
        }


       //Create PBAP server profile, but do not add it to list of profiles
       // as we do not need to monitor the profile as part of profile list
+161 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *        * Redistributions of source code must retain the above copyright
 *            notice, this list of conditions and the following disclaimer.
 *        * Redistributions in binary form must reproduce the above copyright
 *            notice, this list of conditions and the following disclaimer in the
 *            documentation and/or other materials provided with the distribution.
 *        * Neither the name of The Linux Foundation nor
 *            the names of its contributors may be used to endorse or promote
 *            products derived from this software without specific prior written
 *            permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.android.settings.bluetooth;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSap;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.util.Log;

import com.android.settings.R;

import java.util.HashMap;
import java.util.List;

/**
 * SapServerProfile handles Bluetooth SAP server profile.
 */
final class SapServerProfile implements LocalBluetoothProfile {
    private static final String TAG = "SapServerProfile";
    private static boolean V = true;

    private BluetoothSap mService;
    private boolean mIsProfileReady;

    static final String NAME = "SAP Server";

    // Order of this profile in device profiles list
    private static final int ORDINAL = 10;

    // These callbacks run on the main thread.
    private final class SapServiceListener
            implements BluetoothProfile.ServiceListener {

        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (V) Log.d(TAG,"Bluetooth service connected");
            mService = (BluetoothSap) proxy;
            mIsProfileReady=true;
        }

        public void onServiceDisconnected(int profile) {
            if (V) Log.d(TAG,"Bluetooth service disconnected");
            mIsProfileReady=false;
        }
    }

    public boolean isProfileReady() {
        return mIsProfileReady;
    }

    SapServerProfile(Context context) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        adapter.getProfileProxy(context, new SapServiceListener(),
                BluetoothProfile.SAP);
    }

    public boolean isConnectable() {
        return true;
    }

    public boolean isAutoConnectable() {
        return false;
    }

    public boolean connect(BluetoothDevice device) {
        return false;
    }

    public boolean disconnect(BluetoothDevice device) {
        if (mService == null) return false;
        return mService.disconnect(device);
    }

    public int getConnectionStatus(BluetoothDevice device) {
        if (mService == null) {
            return BluetoothProfile.STATE_DISCONNECTED;
        }
        return mService.getConnectionState(device);
    }

    public boolean isPreferred(BluetoothDevice device) {
        return true;
    }

    public int getPreferred(BluetoothDevice device) {
        return -1;
    }

    public void setPreferred(BluetoothDevice device, boolean preferred) {
        // ignore: isPreferred is always true for SAP
    }

    public String toString() {
        return NAME;
    }

    public int getOrdinal() {
        return ORDINAL;
    }

    public int getNameResource(BluetoothDevice device) {
        return R.string.bluetooth_profile_sap;
    }

    public int getSummaryResourceForDevice(BluetoothDevice device) {
        int state = getConnectionStatus(device);
        switch (state) {
            case BluetoothProfile.STATE_DISCONNECTED:
                return R.string.bluetooth_sap_profile_summary_use_for;

            case BluetoothProfile.STATE_CONNECTED:
                return R.string.bluetooth_sap_profile_summary_connected;
            default:
                return Utils.getConnectionStateSummary(state);
        }
    }

    public int getDrawableResource(BluetoothClass btClass) {
        return R.drawable.ic_bt_network_pan;
    }

    protected void finalize() {
        if (V) Log.d(TAG, "finalize()");
        if (mService != null) {
            try {
                BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.SAP, mService);
                mService = null;
            }catch (Throwable t) {
                Log.w(TAG, "Error cleaning up SAP proxy", t);
            }
        }
    }
}