From 0ea027a71cc97ca07576fa4bdaff608eec326f78 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Wed, 3 Apr 2024 10:45:43 +0800 Subject: [PATCH 1/7] [RESTRICT AUTOMERGE] Restrict WifiDppConfiguratorActivity - Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG - Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG Fix: 299931076 Flag: None Test: manual test with TestDPC atest -c SettingsUnitTests:AddNetworkFragmentTest \ SettingsUnitTests:WifiDppConfiguratorActivityTest Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a Merged-In: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a --- .../settings/wifi/AddNetworkFragment.java | 20 +++++ .../wifi/dpp/WifiDppConfiguratorActivity.java | 20 +++++ .../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++ .../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java index 9fd8626f3bf..f5bf5eec9df 100644 --- a/src/com/android/settings/wifi/AddNetworkFragment.java +++ b/src/com/android/settings/wifi/AddNetworkFragment.java @@ -16,12 +16,17 @@ package com.android.settings.wifi; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.Activity; import android.app.settings.SettingsEnums; +import android.content.Context; import android.content.Intent; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; +import android.os.UserManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -43,6 +48,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils; */ public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2, View.OnClickListener { + private static final String TAG = "AddNetworkFragment"; public static final String WIFI_CONFIG_KEY = "wifi_config_key"; @VisibleForTesting @@ -62,6 +68,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getContext())) { + getActivity().finish(); + return; + } } @Override @@ -237,4 +247,14 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf activity.setResult(Activity.RESULT_CANCELED); activity.finish(); } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java index e6f0b31f384..a7527d7332f 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java +++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java @@ -16,6 +16,8 @@ package com.android.settings.wifi.dpp; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; @@ -99,6 +101,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } if (savedInstanceState != null) { String qrCode = savedInstanceState.getString(KEY_QR_CODE); @@ -119,6 +125,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void handleIntent(Intent intent) { + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } if (isGuestUser(getApplicationContext())) { Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!"); EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest"); @@ -402,4 +412,14 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements if (userManager == null) return false; return userManager.isGuestUser(); } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java new file mode 100644 index 00000000000..22d43c9bb4e --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi; + +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class AddNetworkFragmentTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private AddNetworkFragment mFragment; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mFragment = new AddNetworkFragment(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java new file mode 100644 index 00000000000..4d723dc1846 --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.dpp; + +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class WifiDppConfiguratorActivityTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private WifiDppConfiguratorActivity mActivity; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mActivity = new WifiDppConfiguratorActivity(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} From 254ba087c29503e8bcf01cc10082c3f393e7701f Mon Sep 17 00:00:00 2001 From: Weng Su Date: Wed, 3 Apr 2024 10:45:43 +0800 Subject: [PATCH 2/7] [RESTRICT AUTOMERGE] Restrict WifiDppConfiguratorActivity - Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG - Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG Fix: 299931076 Flag: None Test: manual test with TestDPC atest -c SettingsUnitTests:AddNetworkFragmentTest \ SettingsUnitTests:WifiDppConfiguratorActivityTest Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a Merged-In: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a --- .../settings/wifi/AddNetworkFragment.java | 20 +++++ .../wifi/dpp/WifiDppConfiguratorActivity.java | 23 ++++++ .../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++ .../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java index 47a027d8bed..eb48d7d9aa2 100644 --- a/src/com/android/settings/wifi/AddNetworkFragment.java +++ b/src/com/android/settings/wifi/AddNetworkFragment.java @@ -16,11 +16,16 @@ package com.android.settings.wifi; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.Activity; import android.app.settings.SettingsEnums; +import android.content.Context; import android.content.Intent; import android.net.wifi.WifiConfiguration; import android.os.Bundle; +import android.os.UserManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -41,6 +46,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils; */ public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2, View.OnClickListener { + private static final String TAG = "AddNetworkFragment"; public static final String WIFI_CONFIG_KEY = "wifi_config_key"; @VisibleForTesting @@ -58,6 +64,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getContext())) { + getActivity().finish(); + return; + } } @Override @@ -209,4 +219,14 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf activity.setResult(Activity.RESULT_CANCELED); activity.finish(); } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java index ecaf9ee8fc4..338c1bd771f 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java +++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java @@ -16,13 +16,17 @@ package com.android.settings.wifi.dpp; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.settings.SettingsEnums; +import android.content.Context; import android.content.Intent; import android.net.Uri; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; +import android.os.UserManager; import android.provider.Settings; import android.util.Log; @@ -96,6 +100,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } if (savedInstanceState != null) { String qrCode = savedInstanceState.getString(KEY_QR_CODE); @@ -116,6 +124,11 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void handleIntent(Intent intent) { + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } + String action = intent != null ? intent.getAction() : null; if (action == null) { finish(); @@ -384,4 +397,14 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements return null; } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java new file mode 100644 index 00000000000..22d43c9bb4e --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi; + +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class AddNetworkFragmentTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private AddNetworkFragment mFragment; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mFragment = new AddNetworkFragment(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java new file mode 100644 index 00000000000..4d723dc1846 --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi.dpp; + +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class WifiDppConfiguratorActivityTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private WifiDppConfiguratorActivity mActivity; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mActivity = new WifiDppConfiguratorActivity(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} From f42207e1d9b4601280a454ee95c5a46128517cfa Mon Sep 17 00:00:00 2001 From: Manish Singh Date: Wed, 27 Mar 2024 17:23:33 +0000 Subject: [PATCH 3/7] Remove all Settings tasks from Recents when PS is locked Bug: 330865434 Test: manual Test: atest PrivateSpaceMaintainerTest Change-Id: I56b12a6ea5bfedd243fd138ef898f8496301199e --- .../privatespace/PrivateSpaceMaintainer.java | 107 +++++++++++++++++- .../PrivateSpaceMaintainerTest.java | 25 ++++ 2 files changed, 126 insertions(+), 6 deletions(-) diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java index a0c4cbecaed..e27a1c671e7 100644 --- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java +++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java @@ -23,20 +23,21 @@ import static android.provider.Settings.Secure.PRIVATE_SPACE_AUTO_LOCK_AFTER_DEV import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; import android.app.ActivityManager; -import android.app.IActivityManager; import android.app.KeyguardManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.UserInfo; import android.os.Flags; -import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; import android.util.ArraySet; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -54,9 +55,12 @@ public class PrivateSpaceMaintainer { private final Context mContext; private final UserManager mUserManager; + private final ActivityManager mActivityManager; @GuardedBy("this") private UserHandle mUserHandle; private final KeyguardManager mKeyguardManager; + /** This variable should be accessed via {@link #getBroadcastReceiver()} only. */ + @Nullable private ProfileAvailabilityBroadcastReceiver mProfileAvailabilityBroadcastReceiver; /** This is the default value for the hide private space entry point settings. */ public static final int HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL = 0; @@ -104,12 +108,13 @@ public class PrivateSpaceMaintainer { return false; } - IActivityManager am = ActivityManager.getService(); + registerBroadcastReceiver(); + try { //TODO(b/313926659): To check and handle failure of startProfile - am.startProfile(mUserHandle.getIdentifier()); - } catch (RemoteException e) { - Log.e(TAG, "Failed to start private profile"); + mActivityManager.startProfile(mUserHandle); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Unexpected that " + mUserHandle.getIdentifier() + " is not a profile"); return false; } @@ -134,6 +139,7 @@ public class PrivateSpaceMaintainer { Log.i(TAG, "Deleting Private space with id: " + mUserHandle.getIdentifier()); if (mUserManager.removeUser(mUserHandle)) { Log.i(TAG, "Private space deleted"); + unregisterBroadcastReceiver(); mUserHandle = null; return ErrorDeletingPrivateSpace.DELETE_PS_ERROR_NONE; @@ -160,6 +166,7 @@ public class PrivateSpaceMaintainer { for (UserInfo user : users) { if (user.isPrivateProfile()) { mUserHandle = user.getUserHandle(); + registerBroadcastReceiver(); return true; } } @@ -213,6 +220,7 @@ public class PrivateSpaceMaintainer { mContext = context.getApplicationContext(); mUserManager = mContext.getSystemService(UserManager.class); mKeyguardManager = mContext.getSystemService(KeyguardManager.class); + mActivityManager = mContext.getSystemService(ActivityManager.class); } @@ -328,4 +336,91 @@ public class PrivateSpaceMaintainer { && android.multiuser.Flags.supportAutolockForPrivateSpace() && android.multiuser.Flags.enablePrivateSpaceFeatures(); } + + /** {@link BroadcastReceiver} which handles the private profile's availability related + * broadcasts. + */ + private final class ProfileAvailabilityBroadcastReceiver extends BroadcastReceiver { + void register() { + Log.d(TAG, "Registering the receiver"); + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE); + mContext.registerReceiver(/* receiver= */ this, filter, Context.RECEIVER_NOT_EXPORTED); + } + + void unregister() { + Log.d(TAG, "Unregistering the receiver"); + mContext.unregisterReceiver(/* receiver= */ this); + } + + @Override + public void onReceive(@NonNull Context context, @NonNull Intent intent) { + UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class); + if (!userHandle.equals(getPrivateProfileHandle())) { + Log.d(TAG, "Ignoring intent for non-private profile with user id " + + userHandle.getIdentifier()); + return; + } + + Log.i(TAG, "Removing all Settings tasks."); + removeSettingsAllTasks(); + } + } + + private synchronized void registerBroadcastReceiver() { + if (!android.os.Flags.allowPrivateProfile() + || !android.multiuser.Flags.enablePrivateSpaceFeatures()) { + return; + } + var broadcastReceiver = getBroadcastReceiver(); + if (broadcastReceiver == null) { + return; + } + broadcastReceiver.register(); + } + + private synchronized void unregisterBroadcastReceiver() { + if (!android.os.Flags.allowPrivateProfile() + || !android.multiuser.Flags.enablePrivateSpaceFeatures()) { + return; + } + if (mProfileAvailabilityBroadcastReceiver == null) { + Log.w(TAG, "Requested to unregister when there is no receiver."); + return; + } + mProfileAvailabilityBroadcastReceiver.unregister(); + mProfileAvailabilityBroadcastReceiver = null; + } + + /** Always use this getter to access {@link #mProfileAvailabilityBroadcastReceiver}. */ + @VisibleForTesting + @Nullable synchronized ProfileAvailabilityBroadcastReceiver getBroadcastReceiver() { + if (!android.os.Flags.allowPrivateProfile() + || !android.multiuser.Flags.enablePrivateSpaceFeatures()) { + return null; + } + if (!doesPrivateSpaceExist()) { + Log.e(TAG, "Cannot return a broadcast receiver when private space doesn't exist"); + return null; + } + if (mProfileAvailabilityBroadcastReceiver == null) { + mProfileAvailabilityBroadcastReceiver = new ProfileAvailabilityBroadcastReceiver(); + } + return mProfileAvailabilityBroadcastReceiver; + } + + /** This is purely for testing purpose only, and should not be used elsewhere. */ + @VisibleForTesting + synchronized void resetBroadcastReceiver() { + mProfileAvailabilityBroadcastReceiver = null; + } + + private void removeSettingsAllTasks() { + List appTasks = mActivityManager.getAppTasks(); + for (var appTask : appTasks) { + if (!appTask.getTaskInfo().isVisible()) { + appTask.finishAndRemoveTask(); + } + } + } } diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java index 50f67d3c55b..83a80bafa64 100644 --- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java +++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java @@ -90,6 +90,7 @@ public class PrivateSpaceMaintainerTest { public void deletePrivateSpace_psDoesNotExist_returnsNoPSError() { PrivateSpaceMaintainer privateSpaceMaintainer = PrivateSpaceMaintainer.getInstance(mContext); + privateSpaceMaintainer.deletePrivateSpace(); ErrorDeletingPrivateSpace errorDeletingPrivateSpace = privateSpaceMaintainer.deletePrivateSpace(); assertThat(errorDeletingPrivateSpace) @@ -178,6 +179,30 @@ public class PrivateSpaceMaintainerTest { .isEqualTo(HIDE_PRIVATE_SPACE_ENTRY_POINT_ENABLED_VAL); } + @Test + public void createPrivateSpace_psDoesNotExist_registersTheBroadcastReceiver() { + mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE, + android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES); + PrivateSpaceMaintainer privateSpaceMaintainer = + PrivateSpaceMaintainer.getInstance(mContext); + privateSpaceMaintainer.deletePrivateSpace(); + privateSpaceMaintainer.createPrivateSpace(); + // test that no exception is thrown, which would indicate that the receiver was registered. + mContext.unregisterReceiver(privateSpaceMaintainer.getBroadcastReceiver()); + privateSpaceMaintainer.resetBroadcastReceiver(); + } + + @Test + public void deletePrivateSpace_psExists_unregistersTheBroadcastReceiver() { + mSetFlagsRule.enableFlags(Flags.FLAG_ALLOW_PRIVATE_PROFILE, + android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES); + PrivateSpaceMaintainer privateSpaceMaintainer = + PrivateSpaceMaintainer.getInstance(mContext); + privateSpaceMaintainer.createPrivateSpace(); + privateSpaceMaintainer.deletePrivateSpace(); + assertThat(privateSpaceMaintainer.getBroadcastReceiver()).isNull(); + } + /** * Tests that {@link PrivateSpaceMaintainer#lockPrivateSpace()} when PS exists and is running * locks the private profile. From 6cef7bac2dea60fb8df9db3a2a36e5db6b86ed47 Mon Sep 17 00:00:00 2001 From: Hao Dong Date: Wed, 3 Apr 2024 20:44:16 +0000 Subject: [PATCH 4/7] Show "no thanks" button when scroll is not needed. Test: atest FingerprintEnrollIntroductionTest Bug: 328019857 Change-Id: Ia9e9be3a5a4c89e1d01e597730da5bfc2a5483ad --- .../BiometricEnrollIntroduction.java | 14 ++-- .../face/FaceEnrollIntroductionTest.java | 36 +++++++++- .../FingerprintEnrollIntroductionTest.java | 72 ++++++++++++++----- 3 files changed, 99 insertions(+), 23 deletions(-) diff --git a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java index 1b9a70f5d46..5ebe9c7e515 100644 --- a/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java +++ b/src/com/android/settings/biometrics/BiometricEnrollIntroduction.java @@ -229,13 +229,15 @@ public abstract class BiometricEnrollIntroduction extends BiometricEnrollBase } // Show secondary button once scroll is completed. - if (!scrollNeeded) { - if (!enrollmentCompleted) { - getSecondaryFooterButton().setVisibility(View.VISIBLE); - } - mHasScrolledToBottom = true; - } + getSecondaryFooterButton().setVisibility( + !scrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE); + mHasScrolledToBottom = !scrollNeeded; }); + + final boolean isScrollNeeded = requireScrollMixin.isScrollingRequired(); + final boolean enrollmentCompleted = checkMaxEnrolled() != 0; + getSecondaryFooterButton().setVisibility( + !isScrollNeeded && !enrollmentCompleted ? View.VISIBLE : View.INVISIBLE); } @Override diff --git a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java index a56c34cacdf..81a72694592 100644 --- a/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/face/FaceEnrollIntroductionTest.java @@ -78,6 +78,7 @@ import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; import com.google.android.setupcompat.util.WizardManagerHelper; import com.google.android.setupdesign.GlifLayout; +import com.google.android.setupdesign.template.RequireScrollMixin; import com.google.android.setupdesign.view.BottomScrollView; import org.junit.After; @@ -137,6 +138,11 @@ public class FaceEnrollIntroductionTest { return mRecreateCount; } + @Override + protected void onResume() { + super.onResume(); + } + @Override public void recreate() { mRecreateCount++; @@ -424,11 +430,39 @@ public class FaceEnrollIntroductionTest { } @Test - public void testFaceEnrollIntroduction_notShowFooterSecondaryButton() { + public void testFaceEnrollIntroduction_footerSecondaryButtonWhenCanEnroll() { setupActivity(); FooterBarMixin footer = getGlifLayout(mActivity).getMixin(FooterBarMixin.class); FooterButton footerButton = footer.getSecondaryButton(); + final RequireScrollMixin requireScrollMixin = getGlifLayout(mActivity).getMixin( + RequireScrollMixin.class); + assertThat(footerButton.getVisibility()).isEqualTo( + requireScrollMixin.isScrollingRequired() ? View.INVISIBLE : View.VISIBLE); + + requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( + false); + assertThat(footerButton.getVisibility()).isEqualTo(View.VISIBLE); + } + + @Test + public void testFaceEnrollIntroduction_footerSecondaryButtonWhenMaxEnroll() { + setFaceManagerToHave(1 /* numEnrollments */); + final Intent intent = new Intent(); + intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]); + mController = Robolectric.buildActivity(TestFaceEnrollIntroduction.class, intent); + mActivity = (TestFaceEnrollIntroduction) mController.get(); + + mController.create(); + + FooterBarMixin footer = getGlifLayout(mActivity).getMixin(FooterBarMixin.class); + FooterButton footerButton = footer.getSecondaryButton(); + final RequireScrollMixin requireScrollMixin = getGlifLayout(mActivity).getMixin( + RequireScrollMixin.class); + assertThat(footerButton.getVisibility()).isEqualTo(View.INVISIBLE); + + requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( + false); assertThat(footerButton.getVisibility()).isEqualTo(View.INVISIBLE); } diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java index 6df8b8ef4b9..edd50a6e6f6 100644 --- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java +++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollIntroductionTest.java @@ -183,14 +183,6 @@ public class FingerprintEnrollIntroductionTest { int result = mFingerprintEnrollIntroduction.checkMaxEnrolled(); assertThat(result).isEqualTo(0); - - final RequireScrollMixin requireScrollMixin = - ((GlifLayout) mFingerprintEnrollIntroduction.findViewById( - R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class); - requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( - false); - Assert.assertEquals(View.VISIBLE, - mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); } @Test @@ -206,14 +198,6 @@ public class FingerprintEnrollIntroductionTest { int result = mFingerprintEnrollIntroduction.checkMaxEnrolled(); assertThat(result).isEqualTo(R.string.fingerprint_intro_error_max); - - final RequireScrollMixin requireScrollMixin = - ((GlifLayout) mFingerprintEnrollIntroduction.findViewById( - R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class); - requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( - false); - Assert.assertEquals(View.INVISIBLE, - mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); } @Test @@ -321,6 +305,57 @@ public class FingerprintEnrollIntroductionTest { .isEqualTo(FingerprintEnrollOptions.ENROLL_REASON_SETTINGS); } + @Test + public void intro_CheckNoThanksButtonWhenCanEnroll() { + // This code path should depend on suw_max_fingerprints_enrollable versus + // FingerprintManager.getSensorProperties...maxEnrollmentsPerUser() + Resources resources = mock(Resources.class); + when(resources.getInteger(anyInt())).thenReturn(5); + when(mContext.getResources()).thenReturn(resources); + + setupFingerprintEnrollIntroWith(newFirstSuwIntent()); + setFingerprintManagerToHave(0 /* numEnrollments */); + + final RequireScrollMixin requireScrollMixin = + ((GlifLayout) mFingerprintEnrollIntroduction.findViewById( + R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class); + + Assert.assertEquals( + requireScrollMixin.isScrollingRequired() ? View.INVISIBLE : View.VISIBLE, + mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); + + requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( + false); + Assert.assertEquals(View.VISIBLE, + mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); + } + + @Test + public void intro_CheckNoThanksButtonWhenMaxEnroll() { + // This code path should depend on suw_max_fingerprints_enrollable versus + // FingerprintManager.getSensorProperties...maxEnrollmentsPerUser() + Resources resources = mock(Resources.class); + when(mContext.getResources()).thenReturn(resources); + when(resources.getInteger(anyInt())).thenReturn(1); + + setupFingerprintEnrollIntroWith(newFirstSuwIntent()); + setFingerprintManagerToHave(1 /* numEnrollments */); + + final RequireScrollMixin requireScrollMixin = + ((GlifLayout) mFingerprintEnrollIntroduction.findViewById( + R.id.setup_wizard_layout)).getMixin(RequireScrollMixin.class); + + mFingerprintEnrollIntroduction.onResume(); + Assert.assertEquals(View.INVISIBLE, + mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); + + requireScrollMixin.getOnRequireScrollStateChangedListener().onRequireScrollStateChanged( + false); + Assert.assertEquals(View.INVISIBLE, + mFingerprintEnrollIntroduction.getSecondaryFooterButton().getVisibility()); + + } + private Intent newTokenOnlyIntent() { return new Intent() .putExtra(EXTRA_KEY_CHALLENGE_TOKEN, new byte[] { 1 }); @@ -365,6 +400,11 @@ public class FingerprintEnrollIntroductionTest { public int mNewSensorId; public long mNewChallenge; + @Override + protected void onResume() { + super.onResume(); + } + @Nullable public byte[] getTokenField() { return mToken; From 33f505052667142b309bdf731bbea044d1e87272 Mon Sep 17 00:00:00 2001 From: Rafael Higuera Silva Date: Tue, 2 Apr 2024 02:33:13 +0000 Subject: [PATCH 5/7] Add logic to log interaction of RAC warning dialog. Bug: 326618987 Test: make, atest EuiccRacConnectivityDialogActivityTest Change-Id: If4e3285b3715e9630d4932d4bf1bcb71e4167cff --- .../EuiccRacConnectivityDialogActivity.java | 34 +++++-- ...uiccRacConnectivityDialogActivityTest.java | 96 +++++++++++++++++++ 2 files changed, 122 insertions(+), 8 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java diff --git a/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java index d439d4f6c27..aaf98f1e99d 100644 --- a/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java +++ b/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivity.java @@ -16,6 +16,7 @@ package com.android.settings.network.telephony; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -28,20 +29,21 @@ import androidx.fragment.app.FragmentActivity; import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; +import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; /** This dialog activity advise the user to have connectivity if the eSIM uses a RAC. */ public class EuiccRacConnectivityDialogActivity extends FragmentActivity implements WarningDialogFragment.OnConfirmListener { private static final String TAG = "EuiccRacConnectivityDialogActivity"; - // Dialog tags - private static final int DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION = 1; private static final String ARG_SUB_ID = "sub_id"; private static final String ARG_RESET_MOBILE_NETWORK_ID = "reset_mobile_netword_id"; private int mSubId; @Nullable private Intent mResetMobileNetworkIntent; + private MetricsFeatureProvider mMetricsFeatureProvider; /** * Returns an intent of EuiccRacConnectivityDialogActivity for Settings: erase eSIM. @@ -80,6 +82,7 @@ public class EuiccRacConnectivityDialogActivity extends FragmentActivity mSubId = intent.getIntExtra(ARG_SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); mResetMobileNetworkIntent = intent.getParcelableExtra(ARG_RESET_MOBILE_NETWORK_ID, Intent.class); + mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); if (savedInstanceState == null) { showConnectivityWarningDialog(); @@ -88,20 +91,26 @@ public class EuiccRacConnectivityDialogActivity extends FragmentActivity @Override public void onConfirm(int tag, boolean confirmed) { + if (tag == SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING + || tag == SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING) { + mMetricsFeatureProvider.action(this, tag, confirmed ? 1 : 0); + } + if (!confirmed) { finish(); return; } + finish(); switch (tag) { - case DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION: - finish(); + case SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING: + Log.i(TAG, "Show dialogue activity that handles deleting eSIM profile"); + startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId)); + break; + case SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING: if (mResetMobileNetworkIntent != null) { Log.i(TAG, "Show fragment activity that handles mobile network settings reset"); new SubSettingLauncher(this).launchWithIntent(mResetMobileNetworkIntent); - } else { - Log.i(TAG, "Show dialogue activity that handles deleting eSIM profiles"); - startActivity(DeleteEuiccSubscriptionDialogActivity.getIntent(this, mSubId)); } break; default: @@ -115,10 +124,19 @@ public class EuiccRacConnectivityDialogActivity extends FragmentActivity WarningDialogFragment.show( this, WarningDialogFragment.OnConfirmListener.class, - DIALOG_TAG_ERASE_ANYWAY_CONFIRMATION, + getMetricsTag(), getString(R.string.wifi_warning_dialog_title), getString(R.string.wifi_warning_dialog_text), getString(R.string.wifi_warning_continue_button), getString(R.string.wifi_warning_return_button)); } + + /* Get the metrics tag depending on the intent. */ + private int getMetricsTag() { + if (mResetMobileNetworkIntent != null) { + return SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING; + } else { + return SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING; + } + } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java b/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java new file mode 100644 index 00000000000..29d8f796feb --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/telephony/EuiccRacConnectivityDialogActivityTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.network.telephony; + +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import android.app.settings.SettingsEnums; + +import com.android.settings.testutils.FakeFeatureFactory; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class EuiccRacConnectivityDialogActivityTest { + private static final boolean CONFIRMED = true; + + private FakeFeatureFactory mFeatureFactory; + private EuiccRacConnectivityDialogActivity mActivity; + + @Before + public void setUp() { + mFeatureFactory = FakeFeatureFactory.setupForTest(); + mActivity = spy(Robolectric.buildActivity(EuiccRacConnectivityDialogActivity.class).get()); + mActivity.onCreate(null); + } + + @Test + public void dialogAction_continue_intentResetMobileNetwork_metricsLogged() { + mActivity.onConfirm( + SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, CONFIRMED); + + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mActivity, + SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, + getMetricsValue(CONFIRMED)); + } + + @Test + public void dialogAction_back_intentResetMobileNetwork_metricsLogged() { + mActivity.onConfirm( + SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, !CONFIRMED); + + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mActivity, + SettingsEnums.ACTION_RESET_MOBILE_NETWORK_RAC_CONNECTIVITY_WARNING, + getMetricsValue(!CONFIRMED)); + } + + @Test + public void dialogAction_continue_intentSettingsEsimDelete_metricsLogged() { + mActivity.onConfirm(SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, CONFIRMED); + + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mActivity, + SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, + getMetricsValue(CONFIRMED)); + } + + @Test + public void dialogAction_back_intentSettingsEsimDelete_metricsLogged() { + mActivity.onConfirm( + SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, !CONFIRMED); + + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mActivity, + SettingsEnums.ACTION_SETTINGS_ESIM_RAC_CONNECTIVITY_WARNING, + getMetricsValue(!CONFIRMED)); + } + + private int getMetricsValue(boolean confirmed) { + return confirmed ? 1 : 0; + } +} From d0b08818102cf040f32fb8cce97e28f8f5bef029 Mon Sep 17 00:00:00 2001 From: Faye Yan Date: Thu, 4 Apr 2024 02:29:19 +0000 Subject: [PATCH 6/7] Revert "Add Voice activation apps into Settings->Apps->Special a..." Revert submission 25108596-va-special-access Reason for revert: voice activation is not going in V Reverted changes: /q/submissionid:25108596-va-special-access Bug: 306447565 Bug: 393727896 Test: presubmit Change-Id: I4977e7d543cb800fc9fb6962bba3afebb9480dcc --- res/values/strings.xml | 7 -- res/xml/special_access.xml | 5 -- .../android/settings/SettingsActivityUtil.kt | 3 - .../settings/spa/SettingsSpaEnvironment.kt | 2 - .../spa/app/specialaccess/SpecialAppAccess.kt | 1 - .../app/specialaccess/VoiceActivationApps.kt | 67 ------------------- ...VoiceActivationAppsPreferenceController.kt | 38 ----------- ...eActivationAppsPreferenceControllerTest.kt | 65 ------------------ .../specialaccess/VoiceActivationAppsTest.kt | 30 --------- 9 files changed, 218 deletions(-) delete mode 100644 src/com/android/settings/spa/app/specialaccess/VoiceActivationApps.kt delete mode 100644 src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt delete mode 100644 tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt delete mode 100644 tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt diff --git a/res/values/strings.xml b/res/values/strings.xml index 9fbce465110..b54b82222bf 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9834,13 +9834,6 @@ Can access all files - - Voice activation apps - - Allow voice activation - - Voice activation turns-on approved apps, hands-free, using voice command. Built-in adaptive sensing ensures data stays private only to you.\n\nMore about protected adaptive sensing - Full screen notifications diff --git a/res/xml/special_access.xml b/res/xml/special_access.xml index 572345c404e..4caf7ac6d18 100644 --- a/res/xml/special_access.xml +++ b/res/xml/special_access.xml @@ -116,11 +116,6 @@ android:title="@string/full_screen_intent_title" settings:controller="com.android.settings.spa.app.specialaccess.UseFullScreenIntentPreferenceController" /> - - SettingsEnums.APP_SPECIAL_PERMISSION_RECEIVE_SANDBOX_TRIGGER_AUDIO_ALLOW - else -> SettingsEnums.APP_SPECIAL_PERMISSION_RECEIVE_SANDBOX_TRIGGER_AUDIO_DENY - } - /** - * Leave the package string empty as we should not log the package names for the collected - * metrics. - */ - FeatureFactory.featureFactory.metricsFeatureProvider.action(context, category, "") - } -} \ No newline at end of file diff --git a/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt b/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt deleted file mode 100644 index 27d4b4b9035..00000000000 --- a/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceController.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.spa.app.specialaccess - -import android.content.Context -import androidx.preference.Preference -import com.android.settings.core.BasePreferenceController -import com.android.settings.flags.Flags -import com.android.settings.spa.SpaActivity.Companion.startSpaActivity - -class VoiceActivationAppsPreferenceController(context: Context, preferenceKey: String) : - BasePreferenceController(context, preferenceKey) { - override fun getAvailabilityStatus() = - if (Flags.enableVoiceActivationAppsInSettings()) AVAILABLE - else CONDITIONALLY_UNAVAILABLE - - override fun handlePreferenceTreeClick(preference: Preference): Boolean { - if (preference.key == mPreferenceKey) { - mContext.startSpaActivity(VoiceActivationAppsListProvider.getAppListRoute()) - return true - } - return false - } -} \ No newline at end of file diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt deleted file mode 100644 index 2127497ded8..00000000000 --- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsPreferenceControllerTest.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.android.settings.spa.app.specialaccess - -import android.content.Context -import android.platform.test.annotations.RequiresFlagsDisabled -import android.platform.test.annotations.RequiresFlagsEnabled -import android.platform.test.flag.junit.CheckFlagsRule -import android.platform.test.flag.junit.DeviceFlagsValueProvider -import androidx.preference.Preference -import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import com.android.settings.flags.Flags -import com.google.common.truth.Truth.assertThat - -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.kotlin.any -import org.mockito.kotlin.doNothing -import org.mockito.kotlin.spy -import org.mockito.kotlin.whenever - -@RunWith(AndroidJUnit4::class) -class VoiceActivationAppsPreferenceControllerTest { - - @get:Rule - val checkFlagsRule: CheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() - - private val context: Context = spy(ApplicationProvider.getApplicationContext()) { - doNothing().whenever(mock).startActivity(any()) - } - - private val matchedPreference = Preference(context).apply { key = preferenceKey } - - private val misMatchedPreference = Preference(context).apply { key = testPreferenceKey } - - private val controller = VoiceActivationAppsPreferenceController(context, preferenceKey) - - @Test - @RequiresFlagsEnabled(Flags.FLAG_ENABLE_VOICE_ACTIVATION_APPS_IN_SETTINGS) - fun getAvailabilityStatus_enableVoiceActivationApps_returnAvailable() { - assertThat(controller.isAvailable).isTrue() - } - - @Test - @RequiresFlagsDisabled(Flags.FLAG_ENABLE_VOICE_ACTIVATION_APPS_IN_SETTINGS) - fun getAvailableStatus_disableVoiceActivationApps_returnConditionallyUnavailable() { - assertThat(controller.isAvailable).isFalse() - } - - @Test - fun handlePreferenceTreeClick_keyMatched_returnTrue() { - assertThat(controller.handlePreferenceTreeClick(matchedPreference)).isTrue() - } - - @Test - fun handlePreferenceTreeClick_keyMisMatched_returnFalse() { - assertThat(controller.handlePreferenceTreeClick(misMatchedPreference)).isFalse() - } - - companion object { - private const val preferenceKey: String = "voice_activation_apps" - private const val testPreferenceKey: String = "test_key" - } -} \ No newline at end of file diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt deleted file mode 100644 index a2aa293731a..00000000000 --- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/VoiceActivationAppsTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.android.settings.spa.app.specialaccess - -import android.Manifest -import android.app.AppOpsManager -import android.content.Context -import androidx.test.core.app.ApplicationProvider -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.android.settings.R -import com.google.common.truth.Truth.assertThat -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class VoiceActivationAppsTest { - private val context: Context = ApplicationProvider.getApplicationContext() - - private val listModel = VoiceActivationAppsListModel(context) - - @Test - fun modelResourceIdAndProperties() { - assertThat(listModel.pageTitleResId).isEqualTo(R.string.voice_activation_apps_title) - assertThat(listModel.switchTitleResId).isEqualTo(R.string.permit_voice_activation_apps) - assertThat(listModel.footerResId).isEqualTo(R.string.allow_voice_activation_apps_description) - assertThat(listModel.appOp).isEqualTo(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO) - assertThat(listModel.permission).isEqualTo( - Manifest.permission.RECEIVE_SANDBOX_TRIGGER_AUDIO - ) - assertThat(listModel.setModeByUid).isTrue() - } -} \ No newline at end of file From b5aab7716220bac3a71ea9ef05040c83c281d89c Mon Sep 17 00:00:00 2001 From: Faye Yan Date: Thu, 4 Apr 2024 03:40:46 +0000 Subject: [PATCH 7/7] Revert "Add Voice activation apps into Settings->Apps->Specific app->AppInfo->Voice activation apps" This reverts commit 7f2fbc2e4cdc08a6b23939ec4de1ef4989706041. Reason for revert: voice activation is not going in V Change-Id: Idfabfd48f45d2ace7de9f8498181f281ad0358a1 --- src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt index c12915c6a0d..2fd8fc59edf 100644 --- a/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt +++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettings.kt @@ -43,7 +43,6 @@ import com.android.settings.spa.app.specialaccess.DisplayOverOtherAppsAppListPro import com.android.settings.spa.app.specialaccess.InstallUnknownAppsListProvider import com.android.settings.spa.app.specialaccess.ModifySystemSettingsAppListProvider import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider -import com.android.settings.spa.app.specialaccess.VoiceActivationAppsListProvider import com.android.settingslib.spa.framework.common.SettingsPageProvider import com.android.settingslib.spa.framework.compose.navigator import com.android.settingslib.spa.widget.scaffold.RegularScaffold @@ -167,9 +166,6 @@ private fun AppInfoSettings(packageInfoPresenter: PackageInfoPresenter) { InstallUnknownAppsListProvider.InfoPageEntryItem(app) InteractAcrossProfilesDetailsPreference(app) AlarmsAndRemindersAppListProvider.InfoPageEntryItem(app) - if (Flags.enableVoiceActivationAppsInSettings()) { - VoiceActivationAppsListProvider.InfoPageEntryItem(app) - } if (Flags.enablePerformBackupTasksInSettings()) { BackupTasksAppsListProvider.InfoPageEntryItem(app) }