/* * Copyright (C) 2018 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.car.settings.profiles; import android.car.drivingstate.CarUxRestrictions; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.UserInfo; import androidx.annotation.CallSuper; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceGroup; import com.android.car.settings.common.FragmentController; import com.android.car.settings.common.PreferenceController; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** Shared business logic between {@link ProfilesListFragment} and * {@link ChooseNewAdminFragment}. */ public abstract class ProfilesBasePreferenceController extends PreferenceController<PreferenceGroup> { private ProfilesPreferenceProvider mPreferenceProvider; private List<Preference> mProfilesToDisplay = new ArrayList<>(); @VisibleForTesting final BroadcastReceiver mProfileUpdateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { /** Update screen when profiles list is updated. */ refreshUi(); } }; public ProfilesBasePreferenceController(Context context, String preferenceKey, FragmentController fragmentController, CarUxRestrictions uxRestrictions) { super(context, preferenceKey, fragmentController, uxRestrictions); ProfilesPreferenceProvider.ProfileClickListener profileClickListener = this::profileClicked; mPreferenceProvider = new ProfilesPreferenceProvider(context, profileClickListener); } @Override protected Class<PreferenceGroup> getPreferenceType() { return PreferenceGroup.class; } /** * Ensure that helper is set by the time onCreate is called. Register a listener to refresh * screen on updates. */ @Override @CallSuper protected void onCreateInternal() { registerForProfileEvents(); } /** Unregister listener to refresh screen on updates. */ @Override @CallSuper protected void onDestroyInternal() { unregisterForProfileEvents(); } @Override protected void updateState(PreferenceGroup preferenceGroup) { List<Preference> newProfiles = mPreferenceProvider.createProfileList(); if (profileListsAreDifferent(mProfilesToDisplay, newProfiles)) { mProfilesToDisplay = newProfiles; preferenceGroup.removeAll(); for (Preference preference : mProfilesToDisplay) { preferenceGroup.addPreference(preference); } } } /** Handles the profile click on a preference for a certain profile. */ protected abstract void profileClicked(UserInfo userInfo); /** Gets the preference provider to set additional arguments if necessary. */ protected ProfilesPreferenceProvider getPreferenceProvider() { return mPreferenceProvider; } protected List<Preference> getProfilesToDisplay() { return mProfilesToDisplay; } private boolean profileListsAreDifferent(List<Preference> currentList, List<Preference> newList) { if (currentList.size() != newList.size()) { return true; } for (int i = 0; i < currentList.size(); i++) { // Cannot use "compareTo" on preference, since it uses the order attribute to compare. if (preferencesAreDifferent(currentList.get(i), newList.get(i))) { return true; } } return false; } private boolean preferencesAreDifferent(Preference lhs, Preference rhs) { return !Objects.equals(lhs.getTitle(), rhs.getTitle()) || !Objects.equals(lhs.getSummary(), rhs.getSummary()); } private void registerForProfileEvents() { IntentFilter filter = new IntentFilter(Intent.ACTION_USER_INFO_CHANGED); getContext().registerReceiver(mProfileUpdateReceiver, filter); } private void unregisterForProfileEvents() { getContext().unregisterReceiver(mProfileUpdateReceiver); } }