From 58d81fbbb4903284182a3e83dbb880664db0d516 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 01/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 ++++++++++++-- ...verableFooterPreferenceControllerTest.java | 26 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index ce980e0bda2..c8eb488df09 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -19,12 +19,15 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -33,6 +36,9 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -64,12 +70,20 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 91368bf2a81..5df31bc63a4 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -52,6 +52,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; private FooterPreference mPreference; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context, String key) { super(context, key); @@ -84,7 +85,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -94,7 +97,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle(int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 065b924138c..6510f198de1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -104,7 +105,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStart_shouldRegisterBluetoothChanged() { + public void onStart_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); @@ -112,7 +114,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStop_shouldUnregisterBluetoothChanged() { + public void onStop_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); mDiscoverableFooterPreferenceController.onStop(); @@ -120,6 +123,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onStart_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onStop_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + mDiscoverableFooterPreferenceController.onStop(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From b1adf980a58479affaae3476ea80d7f1b0d27138 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 02/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 ++++++++++++-- ...verableFooterPreferenceControllerTest.java | 26 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index ce980e0bda2..c8eb488df09 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -19,12 +19,15 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -33,6 +36,9 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -64,12 +70,20 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 91368bf2a81..5df31bc63a4 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -52,6 +52,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; private FooterPreference mPreference; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context, String key) { super(context, key); @@ -84,7 +85,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -94,7 +97,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle(int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 065b924138c..6510f198de1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -104,7 +105,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStart_shouldRegisterBluetoothChanged() { + public void onStart_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); @@ -112,7 +114,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStop_shouldUnregisterBluetoothChanged() { + public void onStop_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); mDiscoverableFooterPreferenceController.onStop(); @@ -120,6 +123,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onStart_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onStop_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + mDiscoverableFooterPreferenceController.onStop(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From d7c50f795201fa8dc125a82a711fd7be15b6d3e4 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 03/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 ++++++++++++-- ...verableFooterPreferenceControllerTest.java | 26 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index ce980e0bda2..c8eb488df09 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -19,12 +19,15 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -33,6 +36,9 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -64,12 +70,20 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 91368bf2a81..5df31bc63a4 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -52,6 +52,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; private FooterPreference mPreference; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context, String key) { super(context, key); @@ -84,7 +85,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -94,7 +97,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle(int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 065b924138c..6510f198de1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -104,7 +105,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStart_shouldRegisterBluetoothChanged() { + public void onStart_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); @@ -112,7 +114,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStop_shouldUnregisterBluetoothChanged() { + public void onStop_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); mDiscoverableFooterPreferenceController.onStop(); @@ -120,6 +123,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onStart_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onStop_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + mDiscoverableFooterPreferenceController.onStop(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From 249f9e269640d712431ac5eba75412872800a89b Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 04/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 ++++++++++++-- ...verableFooterPreferenceControllerTest.java | 26 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index 5dd769db130..3274a85dea8 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -19,12 +19,15 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -33,6 +36,9 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -69,12 +75,20 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 91368bf2a81..5df31bc63a4 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -52,6 +52,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; private FooterPreference mPreference; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context, String key) { super(context, key); @@ -84,7 +85,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -94,7 +97,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle(int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 065b924138c..6510f198de1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -104,7 +105,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStart_shouldRegisterBluetoothChanged() { + public void onStart_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); @@ -112,7 +114,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStop_shouldUnregisterBluetoothChanged() { + public void onStop_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); mDiscoverableFooterPreferenceController.onStop(); @@ -120,6 +123,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onStart_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onStop_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + mDiscoverableFooterPreferenceController.onStop(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From 528d40e4d12bc82bfc48b4c886c177c7b02561a4 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 05/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 ++++++++++++-- ...verableFooterPreferenceControllerTest.java | 26 +++++++++++++++++-- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index 5dd769db130..3274a85dea8 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -19,12 +19,15 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -33,6 +36,9 @@ import com.android.settingslib.search.SearchIndexable; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -69,12 +75,20 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 91368bf2a81..5df31bc63a4 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -52,6 +52,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; private FooterPreference mPreference; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context, String key) { super(context, key); @@ -84,7 +85,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -94,7 +97,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle(int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 065b924138c..6510f198de1 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -104,7 +105,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStart_shouldRegisterBluetoothChanged() { + public void onStart_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); @@ -112,7 +114,8 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onStop_shouldUnregisterBluetoothChanged() { + public void onStop_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onStart(); mDiscoverableFooterPreferenceController.onStop(); @@ -120,6 +123,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onStart_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onStop_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onStart(); + mDiscoverableFooterPreferenceController.onStop(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From d4e0ed22844c1fbb2afdd2ab9ad8b428e18eb909 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 06/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 14 ++++++++++ ...iscoverableFooterPreferenceController.java | 19 +++++++++++-- ...verableFooterPreferenceControllerTest.java | 27 +++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index cbabb06eb61..68c6d3c1aed 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -20,12 +20,15 @@ import android.content.Context; import android.net.Uri; import android.provider.DeviceConfig; import android.provider.SearchIndexableResource; +import android.text.TextUtils; +import android.util.Log; 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.password.PasswordUtils; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.slices.SlicePreferenceController; import com.android.settingslib.core.AbstractPreferenceController; @@ -40,6 +43,9 @@ import java.util.List; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -90,6 +96,11 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { super.onAttach(context); final boolean nearbyEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_NEAR_BY_SUGGESTION_ENABLED, true); + String callingAppPackageName = PasswordUtils.getCallingAppPackageName( + getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); @@ -97,6 +108,9 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { use(SlicePreferenceController.class).setSliceUri(nearbyEnabled ? Uri.parse(getString(R.string.config_nearby_devices_slice_uri)) : null); + use(DiscoverableFooterPreferenceController.class).setAlwaysDiscoverable( + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); } /** diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index ead33070ee0..bb0417e580f 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -55,6 +55,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private FooterPreference mPreference; private BluetoothAdapter mBluetoothAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context) { super(context, KEY); @@ -119,7 +120,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro } mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mBluetoothAdapter.getState()); } @@ -129,7 +132,19 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro return; } mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } + } + + /** + * Set whether the device can be discovered. By default the value will be {@code false}. + * + * @param isAlwaysDiscoverable {@code true} if the device can be discovered, + * otherwise {@code false} + */ + public void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } private void updateFooterPreferenceTitle (int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 3cc125b4d25..a64b2935638 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -116,14 +117,17 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onResume() { + public void onResume_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onResume(); + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); verify(mAlwaysDiscoverable).start(); } @Test - public void onPause() { + public void onPause_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onResume(); mDiscoverableFooterPreferenceController.onPause(); @@ -131,6 +135,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onResume_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onResume(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onPause_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onResume(); + mDiscoverableFooterPreferenceController.onPause(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { BluetoothAdapter.getDefaultAdapter().setName(DEVICE_NAME); From f8cd68c6e2440f541c77c1e7e299aaca432c05c5 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 07/11] RESTRICT AUTOMERGE Fix make Bluetooth discoverable without additional permission - Only enable device can be discoverable when the user launch "Connected Devices settings" through settings and systemui Bug: 194695497 Test: make -j42 RunSettingsRoboTests and use test apk to manually test to verify the device is not discoversable when open "Connected settings" through test apk. Change-Id: Ia04ab759b737acf30b782f5c5831dd59f25fb257 (cherry picked from commit d3abbb9821dca627c49b15185109150c79597549) --- .../ConnectedDeviceDashboardFragment.java | 27 ++++++++++++++++++- ...iscoverableFooterPreferenceController.java | 17 +++++++++--- ...verableFooterPreferenceControllerTest.java | 27 +++++++++++++++++-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java index 482c45faa43..241648c3a09 100644 --- a/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java +++ b/src/com/android/settings/connecteddevice/ConnectedDeviceDashboardFragment.java @@ -16,9 +16,14 @@ package com.android.settings.connecteddevice; import android.app.Activity; +import android.app.ActivityManager; import android.content.Context; +import android.os.IBinder; +import android.os.RemoteException; import android.provider.SearchIndexableResource; import android.support.annotation.VisibleForTesting; +import android.text.TextUtils; +import android.util.Log; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -36,6 +41,9 @@ import java.util.List; public class ConnectedDeviceDashboardFragment extends DashboardFragment { private static final String TAG = "ConnectedDeviceFrag"; + private static final String SETTINGS_PACKAGE_NAME = "com.android.settings"; + private static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String KEY_CONNECTED_DEVICES = "connected_device_list"; @@ -84,10 +92,27 @@ public class ConnectedDeviceDashboardFragment extends DashboardFragment { @Override public void onAttach(Context context) { super.onAttach(context); + + String callingAppPackageName = getCallingAppPackageName(getActivity().getActivityToken()); + if (DEBUG) { + Log.d(TAG, "onAttach() calling package name is : " + callingAppPackageName); + } use(AvailableMediaDeviceGroupController.class).init(this); use(ConnectedDeviceGroupController.class).init(this); use(PreviouslyConnectedDevicePreferenceController.class).init(this); - use(DiscoverableFooterPreferenceController.class).init(this); + use(DiscoverableFooterPreferenceController.class).init(this, + TextUtils.equals(SETTINGS_PACKAGE_NAME, callingAppPackageName) + || TextUtils.equals(SYSTEMUI_PACKAGE_NAME, callingAppPackageName)); + } + + private String getCallingAppPackageName(IBinder activityToken) { + String pkg = null; + try { + pkg = ActivityManager.getService().getLaunchedFromPackage(activityToken); + } catch (RemoteException e) { + Log.v(TAG, "Could not talk to activity manager.", e); + } + return pkg; } @VisibleForTesting diff --git a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java index 6d2b7154b4c..eb8a9be5705 100644 --- a/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java +++ b/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceController.java @@ -54,6 +54,7 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro private LocalBluetoothManager mLocalManager; private LocalBluetoothAdapter mLocalAdapter; private AlwaysDiscoverable mAlwaysDiscoverable; + private boolean mIsAlwaysDiscoverable; public DiscoverableFooterPreferenceController(Context context) { super(context, KEY); @@ -79,8 +80,9 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro }; } - public void init(DashboardFragment fragment) { + public void init(DashboardFragment fragment, boolean isAlwaysDiscoverable) { mFooterPreferenceMixin = new FooterPreferenceMixin(fragment, fragment.getLifecycle()); + mIsAlwaysDiscoverable = isAlwaysDiscoverable; } @VisibleForTesting @@ -91,6 +93,11 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro mAlwaysDiscoverable = alwaysDiscoverable; } + @VisibleForTesting + void setAlwaysDiscoverable(boolean isAlwaysDiscoverable) { + mIsAlwaysDiscoverable = isAlwaysDiscoverable; + } + @Override public void displayPreference(PreferenceScreen screen) { super.displayPreference(screen); @@ -114,14 +121,18 @@ public class DiscoverableFooterPreferenceController extends BasePreferenceContro public void onResume() { mContext.registerReceiver(mBluetoothChangedReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED)); - mAlwaysDiscoverable.start(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.start(); + } updateFooterPreferenceTitle(mLocalAdapter.getState()); } @Override public void onPause() { mContext.unregisterReceiver(mBluetoothChangedReceiver); - mAlwaysDiscoverable.stop(); + if (mIsAlwaysDiscoverable) { + mAlwaysDiscoverable.stop(); + } } private void updateFooterPreferenceTitle (int bluetoothState) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java index 8cad0bfe70d..4b517b672d6 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/DiscoverableFooterPreferenceControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -117,14 +118,17 @@ public class DiscoverableFooterPreferenceControllerTest { } @Test - public void onResume() { + public void onResume_setAlwaysDiscoverableAsTrue_shouldRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onResume(); + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); verify(mAlwaysDiscoverable).start(); } @Test - public void onPause() { + public void onPause_setAlwaysDiscoverableAsTrue_shouldUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(true); mDiscoverableFooterPreferenceController.onResume(); mDiscoverableFooterPreferenceController.onPause(); @@ -132,6 +136,25 @@ public class DiscoverableFooterPreferenceControllerTest { verify(mAlwaysDiscoverable).stop(); } + @Test + public void onResume_setAlwaysDiscoverableAsFalse_shouldNotRegisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onResume(); + + assertThat(getRegisteredBroadcastReceivers()).contains(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).start(); + } + + @Test + public void onPause_setAlwaysDiscoverableAsFalse_shouldNotUnregisterBluetoothChanged() { + mDiscoverableFooterPreferenceController.setAlwaysDiscoverable(false); + mDiscoverableFooterPreferenceController.onResume(); + mDiscoverableFooterPreferenceController.onPause(); + + assertThat(getRegisteredBroadcastReceivers()).doesNotContain(mBluetoothChangedReceiver); + verify(mAlwaysDiscoverable, never()).stop(); + } + @Test public void onBluetoothStateChanged_bluetoothOn_updateTitle() { ShadowLocalBluetoothAdapter.setName(DEVICE_NAME); From 89c2c5e9c08d68666fd56137f47834d8e320f90d Mon Sep 17 00:00:00 2001 From: Jun Ono Date: Thu, 30 May 2019 12:56:43 +0900 Subject: [PATCH 08/11] Add entry point for adaptive brightness settings Test: adb shell am start -a android.settings.ADAPTIVE_BRIGHTNESS_SETTINGS Bug: 187332145 Change-Id: Ifd81bfb3b0abc3ea10a062cb49fab20f6ef3fdfc --- AndroidManifest.xml | 11 +++++++++++ src/com/android/settings/Settings.java | 2 ++ .../settings/core/gateway/SettingsGateway.java | 6 +++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f367b6fca7f..e10b17ddbf8 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -325,6 +325,17 @@ android:value="true" /> + + + + + + + + Display + Settings.AdaptiveBrightnessActivity.class.getName(), // Home page > Security & screen lock Settings.LocationSettingsActivity.class.getName(), // Home page > System From b10637715581112c2f0efa371fb82e0bdb66edc6 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Fri, 5 Nov 2021 17:12:00 -0400 Subject: [PATCH 09/11] Add ability to force rebuild list So that you can change between filters that have the same sort order. Test: robotests, manually switch between notifications (off) to notifications (all) Fixes: 169943424 Change-Id: I62bbe90f30abada2ec342487a1fa420e451b3caf --- .../manageapplications/ManageApplications.java | 16 ++++++++-------- .../ManageApplicationsTest.java | 7 +++++-- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index edd4088a27f..c1f45746599 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -768,7 +768,7 @@ public class ManageApplications extends InstrumentedFragment int i = item.getItemId(); if (i == R.id.sort_order_alpha || i == R.id.sort_order_size) { if (mApplications != null) { - mApplications.rebuild(menuId); + mApplications.rebuild(menuId, false); } } else if (i == R.id.show_system || i == R.id.hide_system) { mShowSystem = !mShowSystem; @@ -1097,13 +1097,13 @@ public class ManageApplications extends InstrumentedFragment // Notification filters require resorting the list if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) { if (FILTER_APPS_FREQUENT == appFilter.getFilterType()) { - rebuild(R.id.sort_order_frequent_notification); + rebuild(R.id.sort_order_frequent_notification, false); } else if (FILTER_APPS_RECENT == appFilter.getFilterType()) { - rebuild(R.id.sort_order_recent_notification); + rebuild(R.id.sort_order_recent_notification, false); } else if (FILTER_APPS_BLOCKED == appFilter.getFilterType()) { - rebuild(R.id.sort_order_alpha); + rebuild(R.id.sort_order_alpha, true); } else { - rebuild(R.id.sort_order_alpha); + rebuild(R.id.sort_order_alpha, true); } } else { rebuild(); @@ -1121,7 +1121,7 @@ public class ManageApplications extends InstrumentedFragment } rebuild(); } else { - rebuild(sort); + rebuild(sort, false); } } @@ -1149,8 +1149,8 @@ public class ManageApplications extends InstrumentedFragment } } - public void rebuild(int sort) { - if (sort == mLastSortMode) { + public void rebuild(int sort, boolean force) { + if (sort == mLastSortMode && !force) { return; } mManageApplications.mSortOrder = sort; diff --git a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java index 25eca7adb22..da17f1143bb 100644 --- a/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java +++ b/tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java @@ -455,10 +455,13 @@ public class ManageApplicationsTest { ManageApplications.ApplicationsAdapter adapter = new ManageApplications.ApplicationsAdapter( mState, mFragment, mock(AppFilterItem.class), mock(Bundle.class)); - adapter.rebuild(mSortRecent.getItemId()); + adapter.rebuild(mSortRecent.getItemId(), false); assertThat(mFragment.mSortOrder).isEqualTo(mSortRecent.getItemId()); - adapter.rebuild(mSortFrequent.getItemId()); + adapter.rebuild(mSortFrequent.getItemId(), false); + assertThat(mFragment.mSortOrder).isEqualTo(mSortFrequent.getItemId()); + + adapter.rebuild(mSortFrequent.getItemId(), true); assertThat(mFragment.mSortOrder).isEqualTo(mSortFrequent.getItemId()); } From 358fe8e508123978dbc91ee6208865abcd3af670 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Mon, 8 Nov 2021 12:02:10 -0500 Subject: [PATCH 10/11] Update styling of NLS dialog To make the content easier to parse Test: manual Fixes: 191331361 Change-Id: I1a86b761a09fd29a9581abfd9c4b313feb19394a --- res/layout/enable_nls_dialog_content.xml | 167 ++++++++++++++++++ res/values/strings.xml | 9 +- .../ScaryWarningDialogFragment.java | 67 +++++-- 3 files changed, 224 insertions(+), 19 deletions(-) create mode 100644 res/layout/enable_nls_dialog_content.xml diff --git a/res/layout/enable_nls_dialog_content.xml b/res/layout/enable_nls_dialog_content.xml new file mode 100644 index 00000000000..5e1dec98e59 --- /dev/null +++ b/res/layout/enable_nls_dialog_content.xml @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +