From 58d81fbbb4903284182a3e83dbb880664db0d516 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Thu, 28 Oct 2021 06:21:37 +0000 Subject: [PATCH 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 48c3533cd0e89c2bc8d203c4c53446b60b417637 Mon Sep 17 00:00:00 2001 From: ykhung Date: Tue, 9 Nov 2021 19:10:59 +0800 Subject: [PATCH 8/8] Fix incorrect usage for the logging method to cause no data in WW Fix incorrect usage for the logging method to cause the schedule type and percentage data is not logged into the WW, since MetricsFeatureProvider doesn't support log Pair.of() data into the WestWorld or Clearcut directly, it is used for EventLogWriter only Bug: 202906853 Test: make SettingsRoboTests Change-Id: I0ca87ca96647f025adbd23f9f93a3cbd5f7d8579 --- .../BatterySaverScheduleSettings.java | 32 ++++--------------- .../BatterySaverScheduleSettingsTest.java | 29 ++++++++--------- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java index ead6fc68c11..05a1e8f7f1d 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java @@ -29,7 +29,6 @@ import android.os.Handler; import android.provider.Settings; import android.text.TextUtils; import android.view.View; -import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -184,35 +183,18 @@ public class BatterySaverScheduleSettings extends RadioButtonPickerFragment { } private void logPowerSaver() { - int currentSaverPercentage = getSaverPercentage(); - String currentSaverScheduleKey = mRadioButtonController.getDefaultKey(); + final int currentSaverPercentage = getSaverPercentage(); + final String currentSaverScheduleKey = mRadioButtonController.getDefaultKey(); if (mSaverScheduleKey.equals(currentSaverScheduleKey) && mSaverPercentage == currentSaverPercentage) { return; } - int scheduleType = -1; - int schedulePercentage = -1; - switch (currentSaverScheduleKey) { - case BatterySaverScheduleRadioButtonsController.KEY_NO_SCHEDULE: - scheduleType = SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_NO_SCHEDULE; - break; - case BatterySaverScheduleRadioButtonsController.KEY_ROUTINE: - scheduleType = SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_ROUTINE; - break; - case BatterySaverScheduleRadioButtonsController.KEY_PERCENTAGE: - scheduleType = SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_PERCENTAGE; - schedulePercentage = currentSaverPercentage; - break; - // Unknown schedule type. - default: - return; - } FeatureFactory.getFactory(mContext).getMetricsFeatureProvider() - .action(mContext, SettingsEnums.FUELGAUGE_BATTERY_SAVER, - Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE, - scheduleType), - Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE, - schedulePercentage)); + .action(SettingsEnums.FUELGAUGE_BATTERY_SAVER, + SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE, + SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE, + currentSaverScheduleKey, + currentSaverPercentage); } private int getSaverPercentage() { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettingsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettingsTest.java index afd7f66d56b..5c24da9aedb 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettingsTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettingsTest.java @@ -43,22 +43,22 @@ public final class BatterySaverScheduleSettingsTest { @Test public void onPause_withNoScheduleType_logExpectedData() { - setSchedule(PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE, 0); + int expectedPercentage = 0; + setSchedule(PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE, expectedPercentage); mBatterySaverScheduleSettings.onPause(); - verifySchedule(SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_NO_SCHEDULE, - /* schedulePercentage= */ -1); + verifySchedule("key_battery_saver_no_schedule", expectedPercentage); } @Test public void onPause_withRoutineScheduleType_logExpectedData() { - setSchedule(PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC, 0); + int expectedPercentage = 0; + setSchedule(PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC, expectedPercentage); mBatterySaverScheduleSettings.onPause(); - verifySchedule(SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_ROUTINE, - /* schedulePercentage= */ -1); + verifySchedule("key_battery_saver_routine", expectedPercentage); } @Test @@ -68,8 +68,7 @@ public final class BatterySaverScheduleSettingsTest { mBatterySaverScheduleSettings.onPause(); - verifySchedule(SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_PERCENTAGE, - expectedPercentage); + verifySchedule("key_battery_saver_percentage", expectedPercentage); } @Test @@ -90,8 +89,7 @@ public final class BatterySaverScheduleSettingsTest { mBatterySaverScheduleSettings.onPause(); - verifySchedule(SettingsEnums.BATTERY_SAVER_SCHEDULE_TYPE_BASED_ON_PERCENTAGE, - expectedPercentage); + verifySchedule("key_battery_saver_percentage", expectedPercentage); } private void setSchedule(int scheduleType, int schedulePercentage) { @@ -101,13 +99,12 @@ public final class BatterySaverScheduleSettingsTest { Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, schedulePercentage); } - private void verifySchedule(int scheduleType, int schedulePercentage) { + private void verifySchedule(String scheduleTypeKey, int schedulePercentage) { waitAWhile(); - verify(mMetricsFeatureProvider).action(mContext, SettingsEnums.FUELGAUGE_BATTERY_SAVER, - Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE, - scheduleType), - Pair.create(SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE, - schedulePercentage)); + verify(mMetricsFeatureProvider).action(SettingsEnums.FUELGAUGE_BATTERY_SAVER, + SettingsEnums.FIELD_BATTERY_SAVER_SCHEDULE_TYPE, + SettingsEnums.FIELD_BATTERY_SAVER_PERCENTAGE_VALUE, + scheduleTypeKey, schedulePercentage); } private void waitAWhile() {