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

Commit 86125487 authored by SongFerng Wang's avatar SongFerng Wang Committed by Android (Google) Code Review
Browse files

Merge "[LE boradcast] save the data into ContentProvider" into tm-qpr-dev

parents a753bdb1 e7477028
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -6659,6 +6659,26 @@ public final class Settings {
        @SuppressLint("NoSettingsProvider")
        public static final String BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid";
        /**
         * This is used by LocalBluetoothLeBroadcast to store the broadcast program info.
         * @hide
         */
        public static final String BLUETOOTH_LE_BROADCAST_PROGRAM_INFO =
                "bluetooth_le_broadcast_program_info";
        /**
         * This is used by LocalBluetoothLeBroadcast to store the broadcast code.
         * @hide
         */
        public static final String BLUETOOTH_LE_BROADCAST_CODE = "bluetooth_le_broadcast_code";
        /**
         * This is used by LocalBluetoothLeBroadcast to store the app source name.
         * @hide
         */
        public static final String BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME =
                "bluetooth_le_broadcast_app_source_name";
        /**
         * Setting to indicate that on device captions are enabled.
         *
+157 −62
Original line number Diff line number Diff line
@@ -26,11 +26,17 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastSubgroup;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

@@ -40,6 +46,7 @@ import com.android.settingslib.R;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
@@ -54,19 +61,20 @@ import java.util.concurrent.ThreadLocalRandom;
 */
public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
    private static final String TAG = "LocalBluetoothLeBroadcast";
    private static final int UNKNOWN_VALUE_PLACEHOLDER = -1;
    private static final boolean DEBUG = BluetoothUtils.D;

    static final String NAME = "LE_AUDIO_BROADCAST";
    // Order of this profile in device profiles list
    private static final int ORDINAL = 1;
    private static final String PREF_NAME = "LocalBluetoothLeBroadcast";
    private static final String PREF_PROGRAM_INFO = "PrefProgramInfo";
    private static final String PREF_BROADCAST_CODE = "PrefBroadcastCode";
    private static final String PREF_APP_SOURCE_NAME = "PrefAppSourceName";
    private static final String UNDERLINE = "_";
    private static final int DEFAULT_CODE_MIN = 1000;
    private static final int DEFAULT_CODE_MAX = 9999;
    private static final int DEFAULT_CODE_MIN = 1000;
    // Order of this profile in device profiles list
    private static final int ORDINAL = 1;
    private static final int UNKNOWN_VALUE_PLACEHOLDER = -1;
    private static final Uri[] SETTINGS_URIS = new Uri[]{
            Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO),
            Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE),
            Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME),
    };

    private BluetoothLeBroadcast mService;
    private BluetoothLeAudioContentMetadata mBluetoothLeAudioContentMetadata;
@@ -78,8 +86,9 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
    private boolean mIsProfileReady;
    private String mProgramInfo;
    private byte[] mBroadcastCode;
    private SharedPreferences mSharedPref;
    private Executor mExecutor;
    private ContentResolver mContentResolver;
    private ContentObserver mSettingsObserver;

    private final ServiceListener mServiceListener = new ServiceListener() {
        @Override
@@ -91,6 +100,11 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
                mService = (BluetoothLeBroadcast) proxy;
                mIsProfileReady = true;
                registerServiceCallBack(mExecutor, mBroadcastCallback);
                List<BluetoothLeBroadcastMetadata> metadata = getAllBroadcastMetadata();
                if (!metadata.isEmpty()) {
                    updateBroadcastInfoFromBroadcastMetadata(metadata.get(0));
                }
                registerContentObserver();
            }
        }

@@ -102,6 +116,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
            if(mIsProfileReady) {
                mIsProfileReady = false;
                unregisterServiceCallBack(mBroadcastCallback);
                unregisterContentObserver();
            }
        }
    };
@@ -116,7 +131,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
                                        + broadcastId);
                    }
                    setLatestBroadcastId(broadcastId);
                    setAppSourceName(mNewAppSourceName);
                    setAppSourceName(mNewAppSourceName, /*updateContentResolver=*/ true);
                }

                @Override
@@ -160,7 +175,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
                                        + broadcastId);
                    }
                    setLatestBroadcastId(broadcastId);
                    setAppSourceName(mNewAppSourceName);
                    setAppSourceName(mNewAppSourceName, /*updateContentResolver=*/ true);
                }

                @Override
@@ -181,30 +196,27 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
                }
            };

    private class BroadcastSettingsObserver extends ContentObserver {
        BroadcastSettingsObserver(Handler h) {
            super(h);
        }

        @Override
        public void onChange(boolean selfChange) {
            Log.d(TAG, "BroadcastSettingsObserver: onChange");
            updateBroadcastInfoFromContentProvider();
        }
    }

    LocalBluetoothLeBroadcast(Context context) {
        mExecutor = Executors.newSingleThreadExecutor();
        BluetoothAdapter.getDefaultAdapter().
                getProfileProxy(context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST);
        mBuilder = new BluetoothLeAudioContentMetadata.Builder();
        mSharedPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        if (mSharedPref != null) {
            String programInfo = mSharedPref.getString(PREF_PROGRAM_INFO, "");
            if (programInfo.isEmpty()) {
                programInfo = getDefaultValueOfProgramInfo();
            }
            setProgramInfo(programInfo);

            String prefBroadcastCode = mSharedPref.getString(PREF_BROADCAST_CODE, "");
            byte[] broadcastCode;
            if (prefBroadcastCode.isEmpty()) {
                broadcastCode = getDefaultValueOfBroadcastCode();
            } else {
                broadcastCode = prefBroadcastCode.getBytes(StandardCharsets.UTF_8);
            }
            setBroadcastCode(broadcastCode);

            mAppSourceName = mSharedPref.getString(PREF_APP_SOURCE_NAME, "");
        }
        mContentResolver = context.getContentResolver();
        Handler handler = new Handler(Looper.getMainLooper());
        mSettingsObserver = new BroadcastSettingsObserver(handler);
        updateBroadcastInfoFromContentProvider();
    }

    /**
@@ -217,11 +229,12 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
            Log.d(TAG, "The BluetoothLeBroadcast is null when starting the broadcast.");
            return;
        }
        String programInfo = getProgramInfo();
        if (DEBUG) {
            Log.d(TAG,
                    "startBroadcast: language = " + language + " ,programInfo = " + mProgramInfo);
                    "startBroadcast: language = " + language + " ,programInfo = " + programInfo);
        }
        buildContentMetadata(language, mProgramInfo);
        buildContentMetadata(language, programInfo);
        mService.startBroadcast(mBluetoothLeAudioContentMetadata, mBroadcastCode);
    }

@@ -230,21 +243,28 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
    }

    public void setProgramInfo(String programInfo) {
        if (programInfo == null || programInfo.isEmpty()) {
        setProgramInfo(programInfo, /*updateContentResolver=*/ true);
    }

    private void setProgramInfo(String programInfo, boolean updateContentResolver) {
        if (TextUtils.isEmpty(programInfo)) {
            Log.d(TAG, "setProgramInfo: programInfo is null or empty");
            return;
        }
        if (mProgramInfo != null && TextUtils.equals(mProgramInfo, programInfo)) {
            Log.d(TAG, "setProgramInfo: programInfo is not changed");
            return;
        }
        Log.d(TAG, "setProgramInfo: " + programInfo);
        mProgramInfo = programInfo;

        if (mSharedPref == null) {
            Log.d(TAG, "setProgramInfo: sharedPref is null");
        if (updateContentResolver) {
            if (mContentResolver == null) {
                Log.d(TAG, "mContentResolver is null");
                return;
            }
        SharedPreferences.Editor editor = mSharedPref.edit();
        editor.putString(PREF_PROGRAM_INFO, mProgramInfo);
        editor.apply();

            Settings.Secure.putString(mContentResolver,
                    Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, programInfo);
        }
    }

    public byte[] getBroadcastCode() {
@@ -252,22 +272,31 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
    }

    public void setBroadcastCode(byte[] broadcastCode) {
        if (broadcastCode == null || broadcastCode.length == 0) {
            Log.d(TAG, "setBroadcastCode: broadcastCode is null or empty");
        setBroadcastCode(broadcastCode, /*updateContentResolver=*/ true);
    }

    private void setBroadcastCode(byte[] broadcastCode, boolean updateContentResolver) {
        if (broadcastCode == null) {
            Log.d(TAG, "setBroadcastCode: broadcastCode is null");
            return;
        }
        if (mBroadcastCode != null && Arrays.equals(broadcastCode, mBroadcastCode)) {
            Log.d(TAG, "setBroadcastCode: broadcastCode is not changed");
            return;
        }
        mBroadcastCode = broadcastCode;

        if (mSharedPref == null) {
            Log.d(TAG, "setBroadcastCode: sharedPref is null");
        if (updateContentResolver) {
            if (mContentResolver == null) {
                Log.d(TAG, "mContentResolver is null");
                return;
            }
        SharedPreferences.Editor editor = mSharedPref.edit();
        editor.putString(PREF_BROADCAST_CODE, new String(broadcastCode, StandardCharsets.UTF_8));
        editor.apply();
            Settings.Secure.putString(mContentResolver, Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE,
                    new String(broadcastCode, StandardCharsets.UTF_8));
        }
    }

    private void setLatestBroadcastId(int broadcastId) {
        Log.d(TAG, "setLatestBroadcastId: mBroadcastId is " + broadcastId);
        mBroadcastId = broadcastId;
    }

@@ -275,19 +304,24 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        return mBroadcastId;
    }

    private void setAppSourceName(String appSourceName) {
    private void setAppSourceName(String appSourceName, boolean updateContentResolver) {
        if (TextUtils.isEmpty(appSourceName)) {
            appSourceName = "";
        }
        if (mAppSourceName != null && TextUtils.equals(mAppSourceName, appSourceName)) {
            Log.d(TAG, "setAppSourceName: appSourceName is not changed");
            return;
        }
        mAppSourceName = appSourceName;
        mNewAppSourceName = "";
        if (mSharedPref == null) {
            Log.d(TAG, "setBroadcastCode: sharedPref is null");
        if (updateContentResolver) {
            if (mContentResolver == null) {
                Log.d(TAG, "mContentResolver is null");
                return;
            }
        SharedPreferences.Editor editor = mSharedPref.edit();
        editor.putString(PREF_APP_SOURCE_NAME, appSourceName);
        editor.apply();
            Settings.Secure.putString(mContentResolver,
                    Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, mAppSourceName);
        }
    }

    public String getAppSourceName() {
@@ -299,6 +333,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        if (bluetoothLeBroadcastMetadata != null
                && bluetoothLeBroadcastMetadata.getBroadcastId() == mBroadcastId) {
            mBluetoothLeBroadcastMetadata = bluetoothLeBroadcastMetadata;
            updateBroadcastInfoFromBroadcastMetadata(bluetoothLeBroadcastMetadata);
        }
    }

@@ -318,6 +353,48 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        return mBluetoothLeBroadcastMetadata;
    }

    private void updateBroadcastInfoFromContentProvider() {
        if (mContentResolver == null) {
            Log.d(TAG, "updateBroadcastInfoFromContentProvider: mContentResolver is null");
            return;
        }
        String programInfo = Settings.Secure.getString(mContentResolver,
                Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO);
        if (programInfo == null) {
            programInfo = getDefaultValueOfProgramInfo();
        }
        setProgramInfo(programInfo, /*updateContentResolver=*/ false);

        String prefBroadcastCode = Settings.Secure.getString(mContentResolver,
                Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE);
        byte[] broadcastCode = (prefBroadcastCode == null) ? getDefaultValueOfBroadcastCode()
                : prefBroadcastCode.getBytes(StandardCharsets.UTF_8);
        setBroadcastCode(broadcastCode, /*updateContentResolver=*/ false);

        String appSourceName = Settings.Secure.getString(mContentResolver,
                Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME);
        setAppSourceName(appSourceName, /*updateContentResolver=*/ false);
    }

    private void updateBroadcastInfoFromBroadcastMetadata(
            BluetoothLeBroadcastMetadata bluetoothLeBroadcastMetadata) {
        if (bluetoothLeBroadcastMetadata == null) {
            Log.d(TAG, "The bluetoothLeBroadcastMetadata is null");
            return;
        }
        setBroadcastCode(bluetoothLeBroadcastMetadata.getBroadcastCode());
        setLatestBroadcastId(bluetoothLeBroadcastMetadata.getBroadcastId());

        List<BluetoothLeBroadcastSubgroup> subgroup = bluetoothLeBroadcastMetadata.getSubgroups();
        if (subgroup == null || subgroup.size() < 1) {
            Log.d(TAG, "The subgroup is not valid value");
            return;
        }
        BluetoothLeAudioContentMetadata contentMetadata = subgroup.get(0).getContentMetadata();
        setProgramInfo(contentMetadata.getProgramInfo());
        setAppSourceName(getAppSourceName(), /*updateContentResolver=*/ true);
    }

    /**
     * Stop the latest LE Broadcast. If the system stopped the LE Broadcast, then the system
     * calls the corresponding callback {@link BluetoothLeBroadcast.Callback}.
@@ -350,12 +427,13 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
            Log.d(TAG, "The BluetoothLeBroadcast is null when updating the broadcast.");
            return;
        }
        String programInfo = getProgramInfo();
        if (DEBUG) {
            Log.d(TAG,
                    "updateBroadcast: language = " + language + " ,programInfo = " + mProgramInfo);
                    "updateBroadcast: language = " + language + " ,programInfo = " + programInfo);
        }
        mNewAppSourceName = appSourceName;
        mBluetoothLeAudioContentMetadata = mBuilder.setProgramInfo(mProgramInfo).build();
        mBluetoothLeAudioContentMetadata = mBuilder.setProgramInfo(programInfo).build();
        mService.updateBroadcast(mBroadcastId, mBluetoothLeAudioContentMetadata);
    }

@@ -517,8 +595,7 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        if (DEBUG) {
            Log.d(TAG, "resetCacheInfo:");
        }
        mNewAppSourceName = "";
        mAppSourceName = "";
        setAppSourceName("", /*updateContentResolver=*/ true);
        mBluetoothLeBroadcastMetadata = null;
        mBroadcastId = UNKNOWN_VALUE_PLACEHOLDER;
    }
@@ -528,4 +605,22 @@ public class LocalBluetoothLeBroadcast implements LocalBluetoothProfile {
        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
        return randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
    }

    private void registerContentObserver() {
        if (mContentResolver == null) {
            Log.d(TAG, "mContentResolver is null");
            return;
        }
        for (Uri uri : SETTINGS_URIS) {
            mContentResolver.registerContentObserver(uri, false, mSettingsObserver);
        }
    }

    private void unregisterContentObserver() {
        if (mContentResolver == null) {
            Log.d(TAG, "mContentResolver is null");
            return;
        }
        mContentResolver.unregisterContentObserver(mSettingsObserver);
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -212,6 +212,9 @@ public class SecureSettings {
        Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
        Settings.Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
        Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED,
        Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED
        Settings.Secure.ASSIST_LONG_PRESS_HOME_ENABLED,
        Settings.Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO,
        Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE,
        Settings.Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME
    };
}
+3 −0
Original line number Diff line number Diff line
@@ -344,5 +344,8 @@ public class SecureSettingsValidators {
            return true;
        });
        VALIDATORS.put(Secure.ODI_CAPTIONS_VOLUME_UI_ENABLED, BOOLEAN_VALIDATOR);
        VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_PROGRAM_INFO, ANY_STRING_VALIDATOR);
        VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_CODE, ANY_STRING_VALIDATOR);
        VALIDATORS.put(Secure.BLUETOOTH_LE_BROADCAST_APP_SOURCE_NAME, ANY_STRING_VALIDATOR);
    }
}