diff --git a/src/com/android/settings/SetupRedactionInterstitial.java b/src/com/android/settings/SetupRedactionInterstitial.java index 90f6c21dab7..4747d84cf82 100644 --- a/src/com/android/settings/SetupRedactionInterstitial.java +++ b/src/com/android/settings/SetupRedactionInterstitial.java @@ -20,9 +20,12 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; +import android.os.Bundle; import com.android.settings.notification.RedactionInterstitial; +import com.google.android.setupcompat.util.WizardManagerHelper; + /** * Setup Wizard's version of RedactionInterstitial screen. It inherits the logic and basic structure * from RedactionInterstitial class, and should remain similar to that behaviorally. This class @@ -46,6 +49,15 @@ public class SetupRedactionInterstitial extends RedactionInterstitial { PackageManager.DONT_KILL_APP); } + @Override + protected void onCreate(Bundle savedInstance) { + // Only allow to start the activity from Setup Wizard. + if (!WizardManagerHelper.isAnySetupWizard(getIntent())) { + finish(); + } + super.onCreate(savedInstance); + } + @Override public Intent getIntent() { Intent modIntent = new Intent(super.getIntent()); diff --git a/src/com/android/settings/biometrics/face/FaceSettings.java b/src/com/android/settings/biometrics/face/FaceSettings.java index a493ae01dc9..04df11a17b1 100644 --- a/src/com/android/settings/biometrics/face/FaceSettings.java +++ b/src/com/android/settings/biometrics/face/FaceSettings.java @@ -95,9 +95,20 @@ public class FaceSettings extends DashboardFragment { private final FaceSettingsEnrollButtonPreferenceController.Listener mEnrollListener = intent -> startActivityForResult(intent, ENROLL_REQUEST); - public static boolean isAvailable(Context context) { + /** + * @param context + * @return true if the Face hardware is detected. + */ + public static boolean isFaceHardwareDetected(Context context) { FaceManager manager = Utils.getFaceManagerOrNull(context); - return manager != null && manager.isHardwareDetected(); + boolean isHardwareDetected = false; + if (manager == null) { + Log.d(TAG, "FaceManager is null"); + } else { + isHardwareDetected = manager.isHardwareDetected(); + Log.d(TAG, "FaceManager is not null. Hardware detected: " + isHardwareDetected); + } + return manager != null && isHardwareDetected; } @Override @@ -126,7 +137,7 @@ public class FaceSettings extends DashboardFragment { super.onCreate(savedInstanceState); final Context context = getPrefContext(); - if (!isAvailable(context)) { + if (!isFaceHardwareDetected(context)) { Log.w(TAG, "no faceManager, finish this"); finish(); return; @@ -273,7 +284,7 @@ public class FaceSettings extends DashboardFragment { @Override protected List createPreferenceControllers(Context context) { - if (!isAvailable(context)) { + if (!isFaceHardwareDetected(context)) { return null; } mControllers = buildPreferenceControllers(context, getSettingsLifecycle()); @@ -314,7 +325,7 @@ public class FaceSettings extends DashboardFragment { @Override public List createPreferenceControllers( Context context) { - if (isAvailable(context)) { + if (isFaceHardwareDetected(context)) { return buildPreferenceControllers(context, null /* lifecycle */); } else { return null; @@ -323,7 +334,7 @@ public class FaceSettings extends DashboardFragment { @Override protected boolean isPageSearchEnabled(Context context) { - if (isAvailable(context)) { + if (isFaceHardwareDetected(context)) { return hasEnrolledBiometrics(context); } @@ -333,7 +344,10 @@ public class FaceSettings extends DashboardFragment { @Override public List getNonIndexableKeys(Context context) { final List keys = super.getNonIndexableKeys(context); - if (isAvailable(context)) { + final boolean isFaceHardwareDetected = isFaceHardwareDetected(context); + Log.d(TAG, "Get non indexable keys. isFaceHardwareDetected: " + + isFaceHardwareDetected + ", size:" + keys.size()); + if (isFaceHardwareDetected) { final boolean hasEnrolled = hasEnrolledBiometrics(context); keys.add(hasEnrolled ? PREF_KEY_ENROLL_FACE_UNLOCK : PREF_KEY_DELETE_FACE_DATA); diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java index a54171e8c42..bde146b19cd 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsAppPreferenceController.java @@ -22,10 +22,10 @@ import android.content.Context; import android.hardware.face.FaceManager; import android.provider.Settings; -import com.android.settings.Utils; - import androidx.preference.Preference; +import com.android.settings.Utils; + /** * Preference controller for Face settings page controlling the ability to use * Face authentication in apps (through BiometricPrompt). @@ -51,7 +51,7 @@ public class FaceSettingsAppPreferenceController extends FaceSettingsPreferenceC @Override public boolean isChecked() { - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { return false; } return Settings.Secure.getIntForUser( @@ -67,7 +67,7 @@ public class FaceSettingsAppPreferenceController extends FaceSettingsPreferenceC @Override public void updateState(Preference preference) { super.updateState(preference); - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { preference.setEnabled(false); } else if (!mFaceManager.hasEnrolledTemplates(getUserId())) { preference.setEnabled(false); diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java index e5fee758be5..200c0b949ec 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java @@ -93,7 +93,7 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe @Override public boolean isChecked() { - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { return true; } // Set to disabled until we know the true value. diff --git a/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java index c65cd23342e..c5157421132 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsConfirmPreferenceController.java @@ -25,7 +25,6 @@ import android.provider.Settings; import androidx.preference.Preference; import com.android.settings.Utils; -import com.android.settings.core.TogglePreferenceController; /** * Preference controller giving the user an option to always require confirmation. @@ -65,7 +64,7 @@ public class FaceSettingsConfirmPreferenceController extends FaceSettingsPrefere @Override public void updateState(Preference preference) { super.updateState(preference); - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { preference.setEnabled(false); } else if (!mFaceManager.hasEnrolledTemplates(getUserId())) { preference.setEnabled(false); diff --git a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java index 7e7a748faec..8ee7ffd57ce 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsKeyguardPreferenceController.java @@ -53,7 +53,7 @@ public class FaceSettingsKeyguardPreferenceController extends FaceSettingsPrefer @Override public boolean isChecked() { - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { return false; } else if (getRestrictingAdmin() != null) { return false; @@ -77,7 +77,7 @@ public class FaceSettingsKeyguardPreferenceController extends FaceSettingsPrefer public void updateState(Preference preference) { EnforcedAdmin admin; super.updateState(preference); - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { preference.setEnabled(false); } else if ((admin = getRestrictingAdmin()) != null) { ((RestrictedSwitchPreference) preference).setDisabledByAdmin(admin); diff --git a/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java index 5c46a3d9cc9..0a2757b5cbd 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsLockscreenBypassPreferenceController.java @@ -47,7 +47,7 @@ public class FaceSettingsLockscreenBypassPreferenceController @Override public boolean isChecked() { - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { return false; } else if (getRestrictingAdmin() != null) { return false; @@ -69,7 +69,7 @@ public class FaceSettingsLockscreenBypassPreferenceController public void updateState(Preference preference) { EnforcedAdmin admin; super.updateState(preference); - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { preference.setEnabled(false); } else if ((admin = getRestrictingAdmin()) != null) { ((RestrictedSwitchPreference) preference).setDisabledByAdmin(admin); diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java index a4da7597929..6c9806043d4 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java @@ -165,7 +165,7 @@ public class FaceSettingsRemoveButtonPreferenceController extends BasePreference .findViewById(R.id.security_settings_face_settings_remove_button); mButton.setOnClickListener(this); - if (!FaceSettings.isAvailable(mContext)) { + if (!FaceSettings.isFaceHardwareDetected(mContext)) { mButton.setEnabled(false); } else { mButton.setEnabled(!mRemoving); diff --git a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java index cb82b5e8563..648da9b6ef7 100644 --- a/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceStatusPreferenceController.java @@ -41,7 +41,7 @@ public class FaceStatusPreferenceController extends BiometricStatusPreferenceCon @Override protected boolean isDeviceSupported() { - return mFaceManager != null && mFaceManager.isHardwareDetected(); + return FaceSettings.isFaceHardwareDetected(mContext); } @Override diff --git a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java index 8e7031d9cee..49a9de62827 100644 --- a/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java +++ b/src/com/android/settings/gestures/AssistGestureSettingsPreferenceController.java @@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENA import android.content.Context; import android.provider.Settings; +import android.util.Log; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -31,6 +32,7 @@ import com.android.settings.overlay.FeatureFactory; public class AssistGestureSettingsPreferenceController extends GesturePreferenceController { + private static final String TAG = "AssistGesture"; private static final String PREF_KEY_VIDEO = "gesture_assist_video"; private static final String SECURE_KEY_ASSIST = ASSIST_GESTURE_ENABLED; @@ -55,8 +57,11 @@ public class AssistGestureSettingsPreferenceController extends GesturePreference @Override public int getAvailabilityStatus() { - final boolean isAvailable = mAssistOnly ? mFeatureProvider.isSupported(mContext) - : mFeatureProvider.isSensorAvailable(mContext); + final boolean isSupported = mFeatureProvider.isSupported(mContext); + final boolean isSensorAvailable = mFeatureProvider.isSensorAvailable(mContext); + final boolean isAvailable = mAssistOnly ? isSupported : isSensorAvailable; + Log.d(TAG, "mAssistOnly:" + mAssistOnly + ", isSupported:" + isSupported + + ", isSensorAvailable:" + isSensorAvailable); return isAvailable ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java index 4d1a1d476bf..d30fe59a51d 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardLoader.java @@ -38,14 +38,14 @@ import com.android.settings.homepage.contextualcards.logging.ContextualCardLogUt import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.utils.AsyncLoaderCompat; -import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; public class ContextualCardLoader extends AsyncLoaderCompat> { @@ -56,7 +56,7 @@ public class ContextualCardLoader extends AsyncLoaderCompat static final int CARD_CONTENT_LOADER_ID = 1; private static final String TAG = "ContextualCardLoader"; - private static final long ELIGIBILITY_CHECKER_TIMEOUT_MS = 300; + private static final long ELIGIBILITY_CHECKER_TIMEOUT_MS = 400; private final ContentObserver mObserver = new ContentObserver( new Handler(Looper.getMainLooper())) { @@ -184,23 +184,37 @@ public class ContextualCardLoader extends AsyncLoaderCompat @VisibleForTesting List filterEligibleCards(List candidates) { + final ExecutorService executor = Executors.newFixedThreadPool(candidates.size()); final List cards = new ArrayList<>(); - final List> eligibleCards = new ArrayList<>(); + List> eligibleCards = new ArrayList<>(); - for (ContextualCard card : candidates) { - final EligibleCardChecker checker = new EligibleCardChecker(mContext, card); - eligibleCards.add(ThreadUtils.postOnBackgroundThread(checker)); + final List checkers = candidates.stream() + .map(card -> new EligibleCardChecker(mContext, card)) + .collect(Collectors.toList()); + try { + eligibleCards = executor.invokeAll(checkers, ELIGIBILITY_CHECKER_TIMEOUT_MS, + TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Log.w(TAG, "Failed to get eligible states for all cards", e); } + executor.shutdown(); + // Collect future and eligible cards - for (Future cardFuture : eligibleCards) { + for (int i = 0; i < eligibleCards.size(); i++) { + final Future cardFuture = eligibleCards.get(i); + if (cardFuture.isCancelled()) { + Log.w(TAG, "Timeout getting eligible state for card: " + + candidates.get(i).getSliceUri()); + continue; + } + try { - final ContextualCard card = cardFuture.get(ELIGIBILITY_CHECKER_TIMEOUT_MS, - TimeUnit.MILLISECONDS); + final ContextualCard card = cardFuture.get(); if (card != null) { cards.add(card); } - } catch (ExecutionException | InterruptedException | TimeoutException e) { - Log.w(TAG, "Failed to get eligible state for card: " + e.toString()); + } catch (Exception e) { + Log.w(TAG, "Failed to get eligible state for card", e); } } return cards; diff --git a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java index ebfaca9544e..9f0023aa15c 100644 --- a/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java +++ b/src/com/android/settings/homepage/contextualcards/ContextualCardsFragment.java @@ -109,6 +109,7 @@ public class ContextualCardsFragment extends InstrumentedFragment implements mCardsContainer.setLayoutManager(mLayoutManager); mContextualCardsAdapter = new ContextualCardsAdapter(context, this /* lifecycleOwner */, mContextualCardManager); + mCardsContainer.setItemAnimator(null); mCardsContainer.setAdapter(mContextualCardsAdapter); mContextualCardManager.setListener(mContextualCardsAdapter); mCardsContainer.setListener(this); diff --git a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java index 43403306cb3..46b4c869ecb 100644 --- a/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java +++ b/src/com/android/settings/homepage/contextualcards/EligibleCardChecker.java @@ -22,6 +22,7 @@ import android.app.settings.SettingsEnums; import android.content.ContentResolver; import android.content.Context; import android.net.Uri; +import android.os.AsyncTask; import android.util.Log; import androidx.annotation.VisibleForTesting; @@ -32,6 +33,7 @@ import androidx.slice.core.SliceAction; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.utils.ThreadUtils; import java.util.List; import java.util.concurrent.Callable; @@ -115,7 +117,12 @@ public class EligibleCardChecker implements Callable { // Register a trivial callback to pin the slice manager.registerSliceCallback(uri, callback); final Slice slice = manager.bindSlice(uri); - manager.unregisterSliceCallback(uri, callback); + + // Workaround of unpinning slice in the same SerialExecutor of AsyncTask as SliceCallback's + // observer. + ThreadUtils.postOnMainThread(() -> + AsyncTask.execute(() -> manager.unregisterSliceCallback(uri, callback)) + ); return slice; } diff --git a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java index 84aa0cb065a..c9ce9b04b76 100644 --- a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java +++ b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java @@ -59,6 +59,11 @@ public abstract class TelephonyTogglePreferenceController extends TogglePreferen mSetSessionCount.getAndDecrement(); } + @Override + public boolean isSliceable() { + return false; + } + /** * Get carrier config based on specific subscription id. * diff --git a/src/com/android/settings/notification/RedactionInterstitial.java b/src/com/android/settings/notification/RedactionInterstitial.java index 14f99f38b3d..ac648a51e62 100644 --- a/src/com/android/settings/notification/RedactionInterstitial.java +++ b/src/com/android/settings/notification/RedactionInterstitial.java @@ -48,6 +48,7 @@ import com.android.settingslib.RestrictedLockUtilsInternal; 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; public class RedactionInterstitial extends SettingsActivity { @@ -144,7 +145,11 @@ public class RedactionInterstitial extends SettingsActivity { } private void onDoneButtonClicked(View view) { - SetupRedactionInterstitial.setEnabled(getContext(), false); + // If the activity starts by Setup Wizard, then skip disable component which avoids the + // framework force closing all activities on the same task when the system is busy. + if (!WizardManagerHelper.isAnySetupWizard(getIntent())) { + SetupRedactionInterstitial.setEnabled(getContext(), false); + } final RedactionInterstitial activity = (RedactionInterstitial) getActivity(); if (activity != null) { activity.setResult(RESULT_OK, null); diff --git a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java index 6067b77e59f..19e25fc5882 100644 --- a/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java +++ b/src/com/android/settings/security/trustagent/TrustAgentListPreferenceController.java @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.UserHandle; -import android.text.TextUtils; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -46,6 +45,7 @@ import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState; import com.android.settingslib.search.SearchIndexableRaw; +import java.util.ArrayList; import java.util.List; public class TrustAgentListPreferenceController extends AbstractPreferenceController @@ -66,6 +66,9 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro private Intent mTrustAgentClickIntent; private PreferenceCategory mSecurityCategory; + @VisibleForTesting + final List mTrustAgentsKeyList; + public TrustAgentListPreferenceController(Context context, SecuritySettings host, Lifecycle lifecycle) { super(context); @@ -74,6 +77,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro mHost = host; mLockPatternUtils = provider.getLockPatternUtils(context); mTrustAgentManager = provider.getTrustAgentManager(); + mTrustAgentsKeyList = new ArrayList(); if (lifecycle != null) { lifecycle.addObserver(this); } @@ -113,7 +117,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro @Override public boolean handlePreferenceTreeClick(Preference preference) { - if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { + if (!mTrustAgentsKeyList.contains(preference.getKey())) { return super.handlePreferenceTreeClick(preference); } final ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper( @@ -189,6 +193,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro mSecurityCategory.removePreference(oldAgent); } } + mTrustAgentsKeyList.clear(); // Then add new ones. final boolean hasSecurity = mLockPatternUtils.isSecure(MY_USER_ID); @@ -196,6 +201,7 @@ public class TrustAgentListPreferenceController extends AbstractPreferenceContro final RestrictedPreference trustAgentPreference = new RestrictedPreference(mSecurityCategory.getContext()); TrustAgentManager.TrustAgentComponentInfo agent = agents.get(i); + mTrustAgentsKeyList.add(PREF_KEY_TRUST_AGENT + i); trustAgentPreference.setKey(PREF_KEY_TRUST_AGENT + i); trustAgentPreference.setTitle(agent.title); trustAgentPreference.setSummary(agent.summary); diff --git a/src/com/android/settings/slices/SettingsSliceProvider.java b/src/com/android/settings/slices/SettingsSliceProvider.java index 75061a5dac5..c22d001a2d8 100644 --- a/src/com/android/settings/slices/SettingsSliceProvider.java +++ b/src/com/android/settings/slices/SettingsSliceProvider.java @@ -143,7 +143,7 @@ public class SettingsSliceProvider extends SliceProvider { @VisibleForTesting final Map mPinnedWorkers = new ArrayMap<>(); - private boolean mNightMode; + private Boolean mNightMode; public SettingsSliceProvider() { super(READ_SEARCH_INDEXABLES); @@ -153,8 +153,6 @@ public class SettingsSliceProvider extends SliceProvider { public boolean onCreateSliceProvider() { mSlicesDatabaseAccessor = new SlicesDatabaseAccessor(getContext()); mSliceWeakDataCache = new WeakHashMap<>(); - mNightMode = Utils.isNightMode(getContext()); - getContext().setTheme(R.style.Theme_SettingsBase); return true; } @@ -207,7 +205,10 @@ public class SettingsSliceProvider extends SliceProvider { } final boolean nightMode = Utils.isNightMode(getContext()); - if (mNightMode != nightMode) { + if (mNightMode == null) { + mNightMode = nightMode; + getContext().setTheme(R.style.Theme_SettingsBase); + } else if (mNightMode != nightMode) { Log.d(TAG, "Night mode changed, reload theme"); mNightMode = nightMode; getContext().getTheme().rebase(); diff --git a/tests/robotests/src/com/android/settings/network/telephony/TelephonyTogglePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/TelephonyTogglePreferenceControllerTest.java new file mode 100644 index 00000000000..75425123c4b --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/telephony/TelephonyTogglePreferenceControllerTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2020 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 com.google.common.truth.Truth.assertThat; + +import android.content.Context; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class TelephonyTogglePreferenceControllerTest { + + private Context mContext; + private FakeTelephonyToggle mFakeTelephonyToggle; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mFakeTelephonyToggle = new FakeTelephonyToggle(mContext, "key"); + } + + @Test + public void isSliceable_byDefault_shouldReturnFalse() { + assertThat(mFakeTelephonyToggle.isSliceable()).isFalse(); + } + + private static class FakeTelephonyToggle extends TelephonyTogglePreferenceController { + + private FakeTelephonyToggle(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public boolean isChecked() { + return false; + } + + @Override + public boolean setChecked(boolean isChecked) { + return false; + } + + @Override + public int getAvailabilityStatus(int subId) { + return 0; + } + } +} diff --git a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java index c0fbff79358..0463e003ae2 100644 --- a/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/security/trustagent/TrustAgentListPreferenceControllerTest.java @@ -16,10 +16,8 @@ package com.android.settings.security.trustagent; -import static com.android.settings.security.trustagent.TrustAgentListPreferenceController - .PREF_KEY_SECURITY_CATEGORY; -import static com.android.settings.security.trustagent.TrustAgentListPreferenceController - .PREF_KEY_TRUST_AGENT; +import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_SECURITY_CATEGORY; +import static com.android.settings.security.trustagent.TrustAgentListPreferenceController.PREF_KEY_TRUST_AGENT; import static com.google.common.truth.Truth.assertThat; @@ -172,6 +170,26 @@ public class TrustAgentListPreferenceControllerTest { verify(mCategory, never()).addPreference(any(Preference.class)); } + @Test + public void onResume_controllerShouldHasKey() { + final List agents = new ArrayList<>(); + final TrustAgentManager.TrustAgentComponentInfo agent = + mock(TrustAgentManager.TrustAgentComponentInfo.class); + agent.title = "Test_title"; + agent.summary = "test summary"; + agent.componentName = new ComponentName("pkg", "agent"); + agent.admin = null; + agents.add(agent); + when(mTrustAgentManager.getActiveTrustAgents(mActivity, mLockPatternUtils)) + .thenReturn(agents); + final String key = PREF_KEY_TRUST_AGENT + 0; + + mController.displayPreference(mScreen); + mController.onResume(); + + assertThat(mController.mTrustAgentsKeyList).containsExactly(key); + } + @Test public void updateDynamicRawDataToIndex_shouldIndexAgents() { final List agents = new ArrayList<>(); @@ -190,5 +208,4 @@ public class TrustAgentListPreferenceControllerTest { assertThat(indexRaws).hasSize(1); } - }