Add SettingsPolicy to control BT feature
Fixes: 130302238 Test: RunSettingsRoboTests Change-Id: I7e1bf55c476f8e4d3dec7a7dfc0e8d44e5bd53ae
This commit is contained in:
@@ -26,6 +26,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -38,6 +39,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.fuelgauge.BatteryMeterView;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
@@ -64,7 +66,6 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
@VisibleForTesting
|
||||
final Map<String, Bitmap> mIconCache;
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private BluetoothDevice mBluetoothDevice;
|
||||
@VisibleForTesting
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
@VisibleForTesting
|
||||
@@ -88,9 +89,11 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
final boolean advancedEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, true);
|
||||
final boolean untetheredHeadset = BluetoothUtils.getBooleanMetaData(
|
||||
mCachedDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET);
|
||||
return untetheredHeadset ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
return advancedEnabled && untetheredHeadset ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,7 +141,6 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
|
||||
public void init(CachedBluetoothDevice cachedBluetoothDevice) {
|
||||
mCachedDevice = cachedBluetoothDevice;
|
||||
mBluetoothDevice = mCachedDevice.getDevice();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
@@ -19,12 +19,14 @@ package com.android.settings.bluetooth;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.bluetooth.BluetoothUtils;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
@@ -53,7 +55,10 @@ public class BluetoothDetailsHeaderController extends BluetoothDetailsController
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return !BluetoothUtils.getBooleanMetaData(mCachedDevice.getDevice(),
|
||||
final boolean advancedEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, true);
|
||||
return !advancedEnabled
|
||||
|| !BluetoothUtils.getBooleanMetaData(mCachedDevice.getDevice(),
|
||||
BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET);
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,7 @@ import android.app.settings.SettingsEnums;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
@@ -30,7 +30,7 @@ import android.view.MenuItem;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.slices.BlockingSlicePrefController;
|
||||
@@ -117,10 +117,10 @@ public class BluetoothDeviceDetailsFragment extends RestrictedDashboardFragment
|
||||
|
||||
final BluetoothFeatureProvider featureProvider = FeatureFactory.getFactory(
|
||||
context).getBluetoothFeatureProvider(context);
|
||||
final boolean injectionEnabled = FeatureFlagUtils.isEnabled(context,
|
||||
FeatureFlags.SLICE_INJECTION);
|
||||
final boolean sliceEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_SLICE_SETTINGS_ENABLED, true);
|
||||
|
||||
use(BlockingSlicePrefController.class).setSliceUri(injectionEnabled
|
||||
use(BlockingSlicePrefController.class).setSliceUri(sliceEnabled
|
||||
? featureProvider.getBluetoothDeviceSettingsUri(mCachedDevice.getDevice())
|
||||
: null);
|
||||
}
|
||||
|
@@ -18,11 +18,13 @@ package com.android.settings.connecteddevice;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.slices.SlicePreferenceController;
|
||||
@@ -86,12 +88,15 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment {
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true);
|
||||
use(AvailableMediaDeviceGroupController.class).init(this);
|
||||
use(ConnectedDeviceGroupController.class).init(this);
|
||||
use(PreviouslyConnectedDevicePreferenceController.class).init(this);
|
||||
use(DiscoverableFooterPreferenceController.class).init(this);
|
||||
use(SlicePreferenceController.class).setSliceUri(
|
||||
Uri.parse(getString(R.string.config_nearby_devices_slice_uri)));
|
||||
use(SlicePreferenceController.class).setSliceUri(nearbyEnabled
|
||||
? Uri.parse(getString(R.string.config_nearby_devices_slice_uri))
|
||||
: null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
36
src/com/android/settings/core/SettingsUIDeviceConfig.java
Normal file
36
src/com/android/settings/core/SettingsUIDeviceConfig.java
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.settings.core;
|
||||
|
||||
/**
|
||||
* Class to store keys for settings related features, which comes from
|
||||
* {@link android.provider.DeviceConfig}
|
||||
*/
|
||||
public class SettingsUIDeviceConfig {
|
||||
/**
|
||||
* {@code true} if slice settings is enabled in BT device detail page
|
||||
*/
|
||||
public static final String BT_SLICE_SETTINGS_ENABLED = "bt_slice_settings_enabled";
|
||||
/**
|
||||
* {@code true} if advanced header is enabled in BT device detail page
|
||||
*/
|
||||
public static final String BT_ADVANCED_HEADER_ENABLED = "bt_advanced_header_enabled";
|
||||
/**
|
||||
* {@code true} if near by device suggestion is enabled in connected device page
|
||||
*/
|
||||
public static final String BT_NEAR_BY_SUGGESTION_ENABLED = "bt_near_by_suggestion_enabled";
|
||||
}
|
@@ -27,6 +27,7 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
@@ -35,7 +36,9 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.fuelgauge.BatteryMeterView;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
|
||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.widget.LayoutPreference;
|
||||
@@ -50,8 +53,8 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowEntityHeaderController.class)
|
||||
public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
@Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class})
|
||||
public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
private static final int BATTERY_LEVEL_MAIN = 30;
|
||||
private static final int BATTERY_LEVEL_LEFT = 25;
|
||||
private static final int BATTERY_LEVEL_RIGHT = 45;
|
||||
@@ -141,7 +144,9 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_untetheredHeadset_returnAvailable() {
|
||||
public void getAvailabilityStatus_untetheredHeadsetWithConfigOn_returnAvailable() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
@@ -150,7 +155,31 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_notUntetheredHeadset_returnUnavailable() {
|
||||
public void getAvailabilityStatus_untetheredHeadsetWithConfigOff_returnUnavailable() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_notUntetheredHeadsetWithConfigOn_returnUnavailable() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("false".getBytes());
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(
|
||||
BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_notUntetheredHeadsetWithConfigOff_returnUnavailable() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("false".getBytes());
|
||||
|
||||
@@ -169,17 +198,21 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
|
||||
@Test
|
||||
public void onStart_isAvailable_registerCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mBluetoothAdapter).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor() ,mController.mMetadataListener);
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_isAvailable_unregisterCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
|
||||
@@ -197,7 +230,7 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
mController.onStart();
|
||||
|
||||
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor() ,mController.mMetadataListener);
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -213,6 +246,8 @@ public class AdvancedBluetoothDetailsHeaderControllerTest{
|
||||
|
||||
@Test
|
||||
public void onDestroy_isAvailable_recycleBitmap() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
mController.mIconCache.put(ICON_URI, mBitmap);
|
||||
|
@@ -27,7 +27,9 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.SettingsUIDeviceConfig;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowDeviceConfig;
|
||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
|
||||
@@ -44,7 +46,7 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = ShadowEntityHeaderController.class)
|
||||
@Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class})
|
||||
public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsControllerTestBase {
|
||||
|
||||
private BluetoothDetailsHeaderController mController;
|
||||
@@ -123,10 +125,24 @@ public class BluetoothDetailsHeaderControllerTest extends BluetoothDetailsContro
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_untetheredHeadset_returnFalse() {
|
||||
public void isAvailable_untetheredHeadsetWithConfigOn_returnFalse() {
|
||||
android.provider.DeviceConfig.setProperty(
|
||||
android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(
|
||||
BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn("true".getBytes());
|
||||
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAvailable_untetheredHeadsetWithConfigOff_returnTrue() {
|
||||
android.provider.DeviceConfig.setProperty(
|
||||
android.provider.DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "false", true);
|
||||
when(mBluetoothDevice.getMetadata(
|
||||
BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)).thenReturn("true".getBytes());
|
||||
|
||||
assertThat(mController.isAvailable()).isTrue();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user