From 45711dccb4524889f50abb2fcb89f03d44484137 Mon Sep 17 00:00:00 2001 From: Varun Somani Date: Fri, 11 Aug 2023 19:08:47 +0000 Subject: [PATCH 1/6] ARC: Show location services setting in ARC-T Add a new flag that controls location services setting. The current flag controls location services as well as wifi and bluetooth scanning. Seperating these flag will help show GLA setting to the user. UI: go/screen-recording-location-setting-arc-t Bug: 295397004 Test: atest SettingsRoboTests and manual (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:37a14be139542f0d6dbc4b75863368279e8053ba) Merged-In: I3fc377fb118fea031b0ca7dca84f645998486304 Change-Id: I3fc377fb118fea031b0ca7dca84f645998486304 --- res/values/config.xml | 3 +++ .../location/LocationServicesPreferenceController.java | 2 +- tests/robotests/res/values-mcc999/config.xml | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/res/values/config.xml b/res/values/config.xml index d0cd96b8e1b..00e5c99fde6 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -784,4 +784,7 @@ com.android.vending + + + true diff --git a/src/com/android/settings/location/LocationServicesPreferenceController.java b/src/com/android/settings/location/LocationServicesPreferenceController.java index 53150a827b3..bab8bc8d62d 100644 --- a/src/com/android/settings/location/LocationServicesPreferenceController.java +++ b/src/com/android/settings/location/LocationServicesPreferenceController.java @@ -32,7 +32,7 @@ public class LocationServicesPreferenceController extends BasePreferenceControll @AvailabilityStatus public int getAvailabilityStatus() { - return mContext.getResources().getBoolean(R.bool.config_show_location_scanning) + return mContext.getResources().getBoolean(R.bool.config_show_location_services) ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml index a5767e40907..2183b47a37a 100644 --- a/tests/robotests/res/values-mcc999/config.xml +++ b/tests/robotests/res/values-mcc999/config.xml @@ -38,6 +38,7 @@ false false false + false false false false From a36612c003683dd137287ad9f2b2c6c0f0c142bf Mon Sep 17 00:00:00 2001 From: Varun Somani Date: Wed, 20 Dec 2023 23:00:10 +0000 Subject: [PATCH 2/6] ARC: Follow-up fix AndroidLint error Add missing default resource value to fix AndroidLint failure. Bug: 295397004 Test: Presubmit Change-Id: If7ff54c527f48b5260a9f8f8bdddcbf410ac8931 --- tests/robotests/res/values/config.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/robotests/res/values/config.xml b/tests/robotests/res/values/config.xml index 323e742a481..312d31d1c5c 100644 --- a/tests/robotests/res/values/config.xml +++ b/tests/robotests/res/values/config.xml @@ -20,4 +20,5 @@ true true true + true From ba2a86ad9ff9858dc3e64c8c1ff6dd70299a2691 Mon Sep 17 00:00:00 2001 From: SongFerng Wang Date: Wed, 20 Dec 2023 11:38:47 +0000 Subject: [PATCH 3/6] Using ACTION_SIM_CARD_STATE_CHANGED to detect simSlotMapping is complete Sometime modem can't return the GET_SIM_STATUS immediately, so that the settings send the sim switching too early after simSlotMapping. Bug: 291733084 Change-Id: If547c8b02020bc86c83915334e29945176a4ee9f Test: tester will test it manually. --- .../settings/network/UiccSlotUtil.java | 21 ++++++++++++------- .../settings/network/UiccSlotUtilTest.java | 9 +++++--- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java index e329c74a3ef..f7737aa15f4 100644 --- a/src/com/android/settings/network/UiccSlotUtil.java +++ b/src/com/android/settings/network/UiccSlotUtil.java @@ -58,22 +58,29 @@ public class UiccSlotUtil { public static final int INVALID_PORT_ID = -1; @VisibleForTesting - static class SimSlotChangeReceiver extends BroadcastReceiver{ + static class SimCardStateChangeReceiver extends BroadcastReceiver{ private final CountDownLatch mLatch; - SimSlotChangeReceiver(CountDownLatch latch) { + SimCardStateChangeReceiver(CountDownLatch latch) { mLatch = latch; } public void registerOn(Context context) { context.registerReceiver(this, - new IntentFilter(TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED), - Context.RECEIVER_EXPORTED/*UNAUDITED*/); + new IntentFilter(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED), + Context.RECEIVER_NOT_EXPORTED); } @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "Action: " + intent.getAction()); - if (TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED.equals(intent.getAction())) { + if (!TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED.equals(intent.getAction())) { + return; + } + final int simState = intent.getIntExtra( + TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_UNKNOWN); + Log.i(TAG, "simState: " + simState); + if (simState != TelephonyManager.SIM_STATE_UNKNOWN + && simState != TelephonyManager.SIM_STATE_ABSENT) { mLatch.countDown(); } } @@ -269,8 +276,8 @@ public class UiccSlotUtil { try { CountDownLatch latch = new CountDownLatch(1); if (isMultipleEnabledProfilesSupported(telMgr)) { - receiver = new SimSlotChangeReceiver(latch); - ((SimSlotChangeReceiver) receiver).registerOn(context); + receiver = new SimCardStateChangeReceiver(latch); + ((SimCardStateChangeReceiver) receiver).registerOn(context); } else { receiver = new CarrierConfigChangedReceiver(latch); ((CarrierConfigChangedReceiver) receiver).registerOn(context); diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java index 2e17fb271cd..5261b3ec445 100644 --- a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java +++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java @@ -752,11 +752,14 @@ public class UiccSlotUtilTest { } @Test - public void onReceiveSimSlotChangeReceiver_receiveAction_timerCountDown() { + public void onReceiveSimCardStateChangeReceiver_receiveAction_timerCountDown() { CountDownLatch latch = spy(new CountDownLatch(1)); - UiccSlotUtil.SimSlotChangeReceiver receive = new UiccSlotUtil.SimSlotChangeReceiver(latch); + UiccSlotUtil.SimCardStateChangeReceiver receive = + new UiccSlotUtil.SimCardStateChangeReceiver(latch); + Intent intent = new Intent(TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED); + intent.putExtra(TelephonyManager.EXTRA_SIM_STATE, TelephonyManager.SIM_STATE_PRESENT); - receive.onReceive(mContext, new Intent(TelephonyManager.ACTION_SIM_SLOT_STATUS_CHANGED)); + receive.onReceive(mContext, intent); verify(latch).countDown(); } From eff0d103c09b329f5599c6396d7f91071ae4509c Mon Sep 17 00:00:00 2001 From: ykhung Date: Tue, 26 Dec 2023 02:07:27 +0800 Subject: [PATCH 4/6] Add more log for DynamicDenylistManager Bug: 306329984 Test: presubmit Change-Id: I977e80f1a7fc502d1e505856cfa5c4bd80b538c8 --- .../fuelgauge/datasaver/DynamicDenylistManager.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java b/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java index 15f209463e7..e0b6543c09b 100644 --- a/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java +++ b/src/com/android/settings/fuelgauge/datasaver/DynamicDenylistManager.java @@ -31,6 +31,7 @@ import android.util.Log; import androidx.annotation.VisibleForTesting; import java.io.PrintWriter; +import java.util.Arrays; import java.util.Set; /** A class to dynamically manage per apps {@link NetworkPolicyManager} POLICY_ flags. */ @@ -87,6 +88,7 @@ public final class DynamicDenylistManager { /** Set policy flags for specific UID. */ public void setUidPolicyLocked(int uid, int policy) { + Log.i(TAG, "setUidPolicyLocked: uid=" + uid + " policy=" + policy); synchronized (mLock) { mNetworkPolicyManager.setUidPolicy(uid, policy); } @@ -152,17 +154,21 @@ public final class DynamicDenylistManager { /** Reset the UIDs in the denylist if needed. */ public void resetDenylistIfNeeded(String packageName, boolean force) { if (!force && !SETTINGS_PACKAGE_NAME.equals(packageName)) { + Log.w(TAG, "resetDenylistIfNeeded: invalid conditions"); return; } synchronized (mLock) { final int[] uids = mNetworkPolicyManager .getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND); if (uids != null && uids.length != 0) { + Log.i(TAG, "resetDenylistIfNeeded: " + Arrays.toString(uids)); for (int uid : uids) { if (!getDenylistAllUids(getManualDenylistPref()).contains(uid)) { mNetworkPolicyManager.setUidPolicy(uid, POLICY_NONE); } } + } else { + Log.w(TAG, "resetDenylistIfNeeded: there is no valid UIDs"); } } clearSharedPreferences(); @@ -209,6 +215,7 @@ public final class DynamicDenylistManager { } void clearSharedPreferences() { + Log.i(TAG, "clearSharedPreferences()"); getManualDenylistPref().edit().clear().apply(); getDynamicDenylistPref().edit().clear().apply(); } From 706907b7b2541a6cf5b6850dbd0df527c5e41639 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Mon, 18 Dec 2023 17:05:24 +0800 Subject: [PATCH 5/6] Finish HomepageActivity when it's not the root of a task and not singleTask. HomepageActivity should be the first activity in a task, or be launched in singleTask mode. Finishing it will bring up the previous activity in the task. Fix: 297857732 Fix: 309045575 Test: robotest Change-Id: Iddcba1652060d755693dd20d0e350e3d6c1ae138 Merged-In: Iddcba1652060d755693dd20d0e350e3d6c1ae138 --- .../homepage/SettingsHomepageActivity.java | 12 ++++++++++ .../SettingsHomepageActivityTest.java | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index 829a89c6f03..bf8c9a3c9f5 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -175,6 +175,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isTaskRoot() && !isSingleTask()) { + Log.i(TAG, "Not task root nor single task, finish"); + finish(); + return; + } + mIsEmbeddingActivityEnabled = ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this); if (mIsEmbeddingActivityEnabled) { final UserManager um = getSystemService(UserManager.class); @@ -291,6 +297,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements updateSplitLayout(); } + private boolean isSingleTask() { + ActivityInfo info = getIntent().resolveActivityInfo(getPackageManager(), + PackageManager.MATCH_DEFAULT_ONLY); + return info.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK; + } + private void updateSplitLayout() { if (!mIsEmbeddingActivityEnabled) { return; diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java index 2c16db5bb4d..c2c6bdf871d 100644 --- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java +++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java @@ -29,6 +29,7 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -209,6 +210,28 @@ public class SettingsHomepageActivityTest { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } + @Test + public void onCreate_notTaskRoot_shouldFinishActivity() { + SettingsHomepageActivity activity = + spy(Robolectric.buildActivity(SettingsHomepageActivity.class).get()); + doReturn(false).when(activity).isTaskRoot(); + + activity.onCreate(/* savedInstanceState */ null); + + verify(activity).finish(); + } + + @Test + public void onCreate_singleTaskActivity_shouldNotFinishActivity() { + SettingsHomepageActivity activity = + spy(Robolectric.buildActivity(DeepLinkHomepageActivity.class).get()); + doReturn(false).when(activity).isTaskRoot(); + + activity.onCreate(/* savedInstanceState */ null); + + verify(activity, never()).finish(); + } + /** This test is for large screen devices Activity embedding. */ @Test @Config(shadows = ShadowActivityEmbeddingUtils.class) From debcc284135a4cf0f01ea6511ae1dbddcf08b294 Mon Sep 17 00:00:00 2001 From: Haijie Hong Date: Tue, 26 Dec 2023 13:19:24 +0800 Subject: [PATCH 6/6] Move hasHeadTracker to background thread in device details page BUG: 316490612 Test: atest BluetoothDetailsSpatialAudioControllerTest Change-Id: Ic9ca426190bd6389c05272416c87fbf9da392abd --- ...luetoothDetailsSpatialAudioController.java | 29 +++++++++++++++---- ...oothDetailsSpatialAudioControllerTest.java | 8 +++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java index c0869b23bc2..e5fb365e199 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java @@ -37,6 +37,9 @@ import com.android.settings.R; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.core.lifecycle.Lifecycle; +import com.android.settingslib.utils.ThreadUtils; + +import java.util.concurrent.atomic.AtomicBoolean; /** * The controller of the Spatial audio setting in the bluetooth detail settings. @@ -56,6 +59,8 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont @VisibleForTesting AudioDeviceAttributes mAudioDevice = null; + AtomicBoolean mHasHeadTracker = new AtomicBoolean(false); + public BluetoothDetailsSpatialAudioController( Context context, PreferenceFragmentCompat fragment, @@ -77,7 +82,13 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont String key = switchPreference.getKey(); if (TextUtils.equals(key, KEY_SPATIAL_AUDIO)) { updateSpatializerEnabled(switchPreference.isChecked()); - refreshSpatialAudioEnabled(switchPreference); + ThreadUtils.postOnBackgroundThread( + () -> { + mHasHeadTracker.set( + mAudioDevice != null && mSpatializer.hasHeadTracker(mAudioDevice)); + mContext.getMainExecutor() + .execute(() -> refreshSpatialAudioEnabled(switchPreference)); + }); return true; } else if (TextUtils.equals(key, KEY_HEAD_TRACKING)) { updateSpatializerHeadTracking(switchPreference.isChecked()); @@ -124,7 +135,15 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont if (mAudioDevice == null) { getAvailableDevice(); } + ThreadUtils.postOnBackgroundThread( + () -> { + mHasHeadTracker.set( + mAudioDevice != null && mSpatializer.hasHeadTracker(mAudioDevice)); + mContext.getMainExecutor().execute(this::refreshUi); + }); + } + private void refreshUi() { TwoStatePreference spatialAudioPref = mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO); if (spatialAudioPref == null && mAudioDevice != null) { spatialAudioPref = createSpatialAudioPreference(mProfilesContainer.getContext()); @@ -145,7 +164,8 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont refreshSpatialAudioEnabled(spatialAudioPref); } - private void refreshSpatialAudioEnabled(TwoStatePreference spatialAudioPref) { + private void refreshSpatialAudioEnabled( + TwoStatePreference spatialAudioPref) { boolean isSpatialAudioOn = mSpatializer.getCompatibleAudioDevices().contains(mAudioDevice); Log.d(TAG, "refresh() isSpatialAudioOn : " + isSpatialAudioOn); spatialAudioPref.setChecked(isSpatialAudioOn); @@ -160,9 +180,8 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont private void refreshHeadTracking(TwoStatePreference spatialAudioPref, TwoStatePreference headTrackingPref) { - boolean isHeadTrackingAvailable = - spatialAudioPref.isChecked() && mSpatializer.hasHeadTracker(mAudioDevice); - Log.d(TAG, "refresh() has head tracker : " + mSpatializer.hasHeadTracker(mAudioDevice)); + boolean isHeadTrackingAvailable = spatialAudioPref.isChecked() && mHasHeadTracker.get(); + Log.d(TAG, "refresh() has head tracker : " + mHasHeadTracker.get()); headTrackingPref.setVisible(isHeadTrackingAvailable); if (isHeadTrackingAvailable) { headTrackingPref.setChecked(mSpatializer.isHeadTrackerEnabled(mAudioDevice)); diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java index de70330b732..2cc55a70098 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java @@ -43,6 +43,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.shadows.ShadowLooper; import java.util.ArrayList; import java.util.List; @@ -120,6 +121,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices); mController.refresh(); + ShadowLooper.idleMainLooper(); assertThat(mSpatialAudioPref.isChecked()).isTrue(); } @@ -130,6 +132,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices); mController.refresh(); + ShadowLooper.idleMainLooper(); assertThat(mSpatialAudioPref.isChecked()).isFalse(); } @@ -142,6 +145,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(true); mController.refresh(); + ShadowLooper.idleMainLooper(); assertThat(mHeadTrackingPref.isVisible()).isTrue(); } @@ -156,6 +160,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(false); mController.refresh(); + ShadowLooper.idleMainLooper(); verify(mProfilesContainer).removePreference(mHeadTrackingPref); } @@ -166,6 +171,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices); mController.refresh(); + ShadowLooper.idleMainLooper(); verify(mProfilesContainer).removePreference(mHeadTrackingPref); } @@ -181,6 +187,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(true); mController.refresh(); + ShadowLooper.idleMainLooper(); assertThat(mHeadTrackingPref.isChecked()).isTrue(); } @@ -196,6 +203,7 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(false); mController.refresh(); + ShadowLooper.idleMainLooper(); assertThat(mHeadTrackingPref.isChecked()).isFalse(); }