1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.dashboard;
18 
19 import android.app.settings.SettingsEnums;
20 import android.os.SystemClock;
21 import android.text.TextUtils;
22 import android.util.Log;
23 
24 import androidx.preference.Preference;
25 import androidx.preference.PreferenceScreen;
26 
27 import com.android.settingslib.core.AbstractPreferenceController;
28 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
29 import com.android.settingslib.utils.ThreadUtils;
30 
31 /**
32  * A {@link Runnable} controller task. This task handle the visibility of the controller in the
33  * background. Also handle the state updating in the main thread.
34  */
35 public class ControllerTask implements Runnable {
36     private static final String TAG = "ControllerTask";
37     private static final int CONTROLLER_UPDATESTATE_TIME_THRESHOLD = 50;
38 
39     private final AbstractPreferenceController mController;
40     private final PreferenceScreen mScreen;
41     private final int mMetricsCategory;
42     private final MetricsFeatureProvider mMetricsFeature;
43 
ControllerTask(AbstractPreferenceController controller, PreferenceScreen screen, MetricsFeatureProvider metricsFeature, int metricsCategory)44     public ControllerTask(AbstractPreferenceController controller, PreferenceScreen screen,
45             MetricsFeatureProvider metricsFeature, int metricsCategory) {
46         mController = controller;
47         mScreen = screen;
48         mMetricsFeature = metricsFeature;
49         mMetricsCategory = metricsCategory;
50     }
51 
52     @Override
run()53     public void run() {
54         if (!mController.isAvailable()) {
55             return;
56         }
57 
58         final String key = mController.getPreferenceKey();
59         if (TextUtils.isEmpty(key)) {
60             Log.d(TAG, String.format("Preference key is %s in Controller %s",
61                     key, mController.getClass().getSimpleName()));
62             return;
63         }
64 
65         final Preference preference = mScreen.findPreference(key);
66         if (preference == null) {
67             Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
68                     key, mController.getClass().getSimpleName()));
69             return;
70         }
71         ThreadUtils.postOnMainThread(() -> {
72             final long t = SystemClock.elapsedRealtime();
73             mController.updateState(preference);
74             final int elapsedTime = (int) (SystemClock.elapsedRealtime() - t);
75             if (elapsedTime > CONTROLLER_UPDATESTATE_TIME_THRESHOLD) {
76                 Log.w(TAG, "The updateState took " + elapsedTime + " ms in Controller "
77                         + mController.getClass().getSimpleName());
78                 if (mMetricsFeature != null) {
79                     mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN,
80                             SettingsEnums.ACTION_CONTROLLER_UPDATE_STATE, mMetricsCategory,
81                             mController.getClass().getSimpleName(), elapsedTime);
82                 }
83             }
84         });
85     }
86 
getController()87     AbstractPreferenceController getController() {
88         return mController;
89     }
90 }
91