From 20d88eb2a8e83ea1b95f31d970a6817523bde1b5 Mon Sep 17 00:00:00 2001 From: zoey chen Date: Fri, 17 Apr 2020 20:44:37 +0800 Subject: [PATCH] Improve the performance of displaying preference. - Set a variable to record the status then replace getAvailabilityStatus() with it. Test: manual test, use command to run MobileNetworkSettings and record it. Bug: 154061428 Merged-In: Ia13a75a3821bb6c17d0dfeffb5043f47b60adf61 Change-Id: Ia13a75a3821bb6c17d0dfeffb5043f47b60adf61 --- .../telephony/MobileNetworkSettings.java | 49 ++++++++++++++++++- .../TelephonyAvailabilityHandler.java | 38 ++++++++++++++ .../TelephonyBasePreferenceController.java | 23 ++++++++- .../TelephonyTogglePreferenceController.java | 24 ++++++++- 4 files changed, 129 insertions(+), 5 deletions(-) create mode 100644 src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java index c30a89efd84..d5e6f5e39e5 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java +++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java @@ -38,6 +38,7 @@ import androidx.preference.PreferenceScreen; import com.android.internal.telephony.TelephonyIntents; import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; import com.android.settings.core.FeatureFlags; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.datausage.BillingCyclePreferenceController; @@ -52,11 +53,14 @@ import com.android.settings.search.Indexable; import com.android.settings.widget.PreferenceCategoryController; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.utils.ThreadUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -192,16 +196,59 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment { @Override public void onCreate(Bundle icicle) { Log.i(LOG_TAG, "onCreate:+"); + + final Collection> controllerLists = + getPreferenceControllers(); + final Future result = ThreadUtils.postOnBackgroundThread(() -> + setupAvailabilityStatus(controllerLists) + ); + super.onCreate(icicle); final Context context = getContext(); - mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mTelephonyManager = context.getSystemService(TelephonyManager.class) .createForSubscriptionId(mSubId); + // Check the background thread is finished then unset the status of availability. + try { + result.get(); + } catch (ExecutionException | InterruptedException exception) { + Log.e(LOG_TAG, "onCreate, setup availability status failed!", exception); + } + unsetAvailabilityStatus(controllerLists); + onRestoreInstance(icicle); } + private Boolean setupAvailabilityStatus( + Collection> controllerLists) { + try { + controllerLists.stream().flatMap(Collection::stream) + .filter(controller -> controller instanceof TelephonyAvailabilityHandler) + .map(TelephonyAvailabilityHandler.class::cast) + .forEach(controller -> { + int status = ((BasePreferenceController) controller) + .getAvailabilityStatus(); + controller.unsetAvailabilityStatus(true); + controller.setAvailabilityStatus(status); + }); + return true; + } catch (Exception exception) { + Log.e(LOG_TAG, "Setup availability status failed!", exception); + return false; + } + } + + private void unsetAvailabilityStatus( + Collection> controllerLists) { + controllerLists.stream().flatMap(Collection::stream) + .filter(controller -> controller instanceof TelephonyAvailabilityHandler) + .map(TelephonyAvailabilityHandler.class::cast) + .forEach(controller -> { + controller.unsetAvailabilityStatus(false); + }); + } + @Override public void onExpandButtonClick() { final PreferenceScreen screen = getPreferenceScreen(); diff --git a/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java new file mode 100644 index 00000000000..50dd26bc1b5 --- /dev/null +++ b/src/com/android/settings/network/telephony/TelephonyAvailabilityHandler.java @@ -0,0 +1,38 @@ +/* + * 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. + */ + +/** + * Interface letting {@link TelephonyTogglePreferenceController and + * @link TelephonyBasePreferenceController} can handle availability status. + */ +package com.android.settings.network.telephony; + +import android.content.Context; + +public interface TelephonyAvailabilityHandler { + + /** + * Set availability to preference controller. + */ + public void setAvailabilityStatus(int status); + + /** + * Do not set availability, use + * {@link MobileNetworkUtils#getAvailability(Context, int, TelephonyAvailabilityCallback)} + * to get the availability. + */ + public void unsetAvailabilityStatus(boolean enable); +} diff --git a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java index 241dc5dac65..678209d9358 100644 --- a/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java +++ b/src/com/android/settings/network/telephony/TelephonyBasePreferenceController.java @@ -23,12 +23,17 @@ import android.telephony.SubscriptionManager; import com.android.settings.core.BasePreferenceController; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + /** * {@link BasePreferenceController} that used by all preferences that requires subscription id. */ public abstract class TelephonyBasePreferenceController extends BasePreferenceController - implements TelephonyAvailabilityCallback { + implements TelephonyAvailabilityCallback, TelephonyAvailabilityHandler { protected int mSubId; + private AtomicInteger mAvailabilityStatus = new AtomicInteger(0); + private AtomicBoolean mUnsetAvailabilityStatus = new AtomicBoolean(false); public TelephonyBasePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); @@ -37,7 +42,21 @@ public abstract class TelephonyBasePreferenceController extends BasePreferenceCo @Override public int getAvailabilityStatus() { - return MobileNetworkUtils.getAvailability(mContext, mSubId, this::getAvailabilityStatus); + if (!mUnsetAvailabilityStatus.get()) { + mAvailabilityStatus.set(MobileNetworkUtils + .getAvailability(mContext, mSubId, this::getAvailabilityStatus)); + } + return mAvailabilityStatus.get(); + } + + @Override + public void setAvailabilityStatus(int status) { + mAvailabilityStatus.set(status); + } + + @Override + public void unsetAvailabilityStatus(boolean enable) { + mUnsetAvailabilityStatus.set(enable); } /** diff --git a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java index fc3003041b8..56d51eb3809 100644 --- a/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java +++ b/src/com/android/settings/network/telephony/TelephonyTogglePreferenceController.java @@ -23,12 +23,18 @@ import android.telephony.SubscriptionManager; import com.android.settings.core.TogglePreferenceController; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + /** * {@link TogglePreferenceController} that used by all preferences that requires subscription id. */ public abstract class TelephonyTogglePreferenceController extends TogglePreferenceController - implements TelephonyAvailabilityCallback { + implements TelephonyAvailabilityCallback, TelephonyAvailabilityHandler { protected int mSubId; + private AtomicInteger mAvailabilityStatus = new AtomicInteger(0); + private AtomicBoolean mUnsetAvailabilityStatus = new AtomicBoolean(false); + public TelephonyTogglePreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); @@ -37,7 +43,21 @@ public abstract class TelephonyTogglePreferenceController extends TogglePreferen @Override public int getAvailabilityStatus() { - return MobileNetworkUtils.getAvailability(mContext, mSubId, this::getAvailabilityStatus); + if (!mUnsetAvailabilityStatus.get()) { + mAvailabilityStatus.set(MobileNetworkUtils + .getAvailability(mContext, mSubId, this::getAvailabilityStatus)); + } + return mAvailabilityStatus.get(); + } + + @Override + public void setAvailabilityStatus(int status) { + mAvailabilityStatus.set(status); + } + + @Override + public void unsetAvailabilityStatus(boolean enable) { + mUnsetAvailabilityStatus.set(enable); } /**