Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73b858db authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove no reference code" into tm-dev

parents ccf275d5 6af43b14
Loading
Loading
Loading
Loading
+0 −36
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.dashboard;

import com.android.settingslib.core.AbstractPreferenceController;

import java.util.concurrent.FutureTask;

/**
 *  {@link FutureTask} of the Controller.
 */
public class ControllerFutureTask extends FutureTask<Void> {
    private final AbstractPreferenceController mController;

    public ControllerFutureTask(ControllerTask task, Void result) {
        super(task, result);
        mController = task.getController();
    }

    AbstractPreferenceController getController() {
        return mController;
    }
}
+0 −90
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.dashboard;

import android.app.settings.SettingsEnums;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;

import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;

import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.utils.ThreadUtils;

/**
 * A {@link Runnable} controller task. This task handle the visibility of the controller in the
 * background. Also handle the state updating in the main thread.
 */
public class ControllerTask implements Runnable {
    private static final String TAG = "ControllerTask";
    private static final int CONTROLLER_UPDATESTATE_TIME_THRESHOLD = 50;

    private final AbstractPreferenceController mController;
    private final PreferenceScreen mScreen;
    private final int mMetricsCategory;
    private final MetricsFeatureProvider mMetricsFeature;

    public ControllerTask(AbstractPreferenceController controller, PreferenceScreen screen,
            MetricsFeatureProvider metricsFeature, int metricsCategory) {
        mController = controller;
        mScreen = screen;
        mMetricsFeature = metricsFeature;
        mMetricsCategory = metricsCategory;
    }

    @Override
    public void run() {
        if (!mController.isAvailable()) {
            return;
        }

        final String key = mController.getPreferenceKey();
        if (TextUtils.isEmpty(key)) {
            Log.d(TAG, String.format("Preference key is %s in Controller %s",
                    key, mController.getClass().getSimpleName()));
            return;
        }

        final Preference preference = mScreen.findPreference(key);
        if (preference == null) {
            Log.d(TAG, String.format("Cannot find preference with key %s in Controller %s",
                    key, mController.getClass().getSimpleName()));
            return;
        }
        ThreadUtils.postOnMainThread(() -> {
            final long t = SystemClock.elapsedRealtime();
            mController.updateState(preference);
            final int elapsedTime = (int) (SystemClock.elapsedRealtime() - t);
            if (elapsedTime > CONTROLLER_UPDATESTATE_TIME_THRESHOLD) {
                Log.w(TAG, "The updateState took " + elapsedTime + " ms in Controller "
                        + mController.getClass().getSimpleName());
                if (mMetricsFeature != null) {
                    mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN,
                            SettingsEnums.ACTION_CONTROLLER_UPDATE_STATE, mMetricsCategory,
                            mController.getClass().getSimpleName(), elapsedTime);
                }
            }
        });
    }

    AbstractPreferenceController getController() {
        return mController;
    }
}
+1 −41
Original line number Diff line number Diff line
@@ -48,7 +48,6 @@ import com.android.settingslib.drawer.DashboardCategory;
import com.android.settingslib.drawer.ProviderTile;
import com.android.settingslib.drawer.Tile;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.utils.ThreadUtils;

import java.util.ArrayList;
import java.util.Arrays;
@@ -58,7 +57,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ExecutionException;

/**
 * Base fragment for dashboard style UI containing a list of static and dynamic setting items.
@@ -222,7 +220,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
        super.onResume();
        updatePreferenceStates();
        writeElapsedTimeMetric(SettingsEnums.ACTION_DASHBOARD_VISIBLE_TIME,
                "isParalleledControllers:" + isParalleledControllers());
                "isParalleledControllers:false");
    }

    @Override
@@ -348,14 +346,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
                controller -> controller.displayPreference(screen));
    }

    /**
     * @return {@code true} if the underlying controllers should be executed in parallel.
     * Override this function to enable/disable the behavior.
     */
    protected boolean isParalleledControllers() {
        return false;
    }

    /**
     * Get current PreferenceController(s)
     */
@@ -394,36 +384,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
        }
    }

    /**
     * Use parallel method to update state of each preference managed by PreferenceController.
     */
    @VisibleForTesting
    // To use this parallel approach will cause the side effect of the UI flicker. Such as
    // the thumb sliding of the toggle button.
    void updatePreferenceStatesInParallel() {
        final PreferenceScreen screen = getPreferenceScreen();
        final Collection<List<AbstractPreferenceController>> controllerLists =
                mPreferenceControllers.values();
        final List<ControllerFutureTask> taskList = new ArrayList<>();
        for (List<AbstractPreferenceController> controllerList : controllerLists) {
            for (AbstractPreferenceController controller : controllerList) {
                final ControllerFutureTask task = new ControllerFutureTask(
                        new ControllerTask(controller, screen, mMetricsFeatureProvider,
                                getMetricsCategory()), null /* result */);
                taskList.add(task);
                ThreadUtils.postOnBackgroundThread(task);
            }
        }

        for (ControllerFutureTask task : taskList) {
            try {
                task.get();
            } catch (InterruptedException | ExecutionException e) {
                Log.w(TAG, task.getController().getPreferenceKey() + " " + e.getMessage());
            }
        }
    }

    /**
     * Refresh all preference items, including both static prefs from xml, and dynamic items from
     * DashboardCategory.
+0 −71
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.dashboard;

import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;

import static com.google.common.truth.Truth.assertThat;

import android.content.Context;

import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;

import com.android.settings.core.BasePreferenceController;

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 ControllerFutureTaskTest {
    private static final String KEY = "my_key";

    private Context mContext;
    private TestPreferenceController mTestController;
    private PreferenceScreen mScreen;

    @Before
    public void setUp() {
        mContext = RuntimeEnvironment.application;
        mTestController = new TestPreferenceController(mContext, KEY);
        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
        mScreen = preferenceManager.createPreferenceScreen(mContext);
    }

    @Test
    public void getController_addTask_checkControllerKey() {
        final ControllerFutureTask futureTask = new ControllerFutureTask(
                new ControllerTask(mTestController, mScreen, null /* metricsFeature */,
                        METRICS_CATEGORY_UNKNOWN), null /* result */);

        assertThat(futureTask.getController().getPreferenceKey()).isEqualTo(KEY);
    }


    static class TestPreferenceController extends BasePreferenceController {
        TestPreferenceController(Context context, String preferenceKey) {
            super(context, preferenceKey);
        }

        @Override
        public int getAvailabilityStatus() {
            return AVAILABLE;
        }
    }
}
+0 −124
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.dashboard;

import static com.android.settingslib.core.instrumentation.Instrumentable.METRICS_CATEGORY_UNKNOWN;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

import android.content.Context;

import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;

import com.android.settingslib.core.AbstractPreferenceController;

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 ControllerTaskTest {
    private static final String KEY = "my_key";

    private Context mContext;
    private PreferenceScreen mScreen;
    private TestPreferenceController mTestController;
    private ControllerTask mControllerTask;

    @Before
    public void setUp() {
        mContext = RuntimeEnvironment.application;
        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
        mScreen = preferenceManager.createPreferenceScreen(mContext);
        mTestController = spy(new TestPreferenceController(mContext));
        mControllerTask = new ControllerTask(mTestController, mScreen, null /* metricsFeature */,
                METRICS_CATEGORY_UNKNOWN);
    }

    @Test
    public void doRun_controlNotAvailable_noRunUpdateState() {
        mTestController.setAvailable(false);

        mControllerTask.run();

        verify(mTestController, never()).updateState(any(Preference.class));
    }

    @Test
    public void doRun_emptyKey_noRunUpdateState() {
        mTestController.setKey("");

        mControllerTask.run();

        verify(mTestController, never()).updateState(any(Preference.class));
    }

    @Test
    public void doRun_preferenceNotExist_noRunUpdateState() {
        mTestController.setKey(KEY);

        mControllerTask.run();

        verify(mTestController, never()).updateState(any(Preference.class));
    }

    @Test
    public void doRun_executeUpdateState() {
        mTestController.setKey(KEY);
        final Preference preference = new Preference(mContext);
        preference.setKey(KEY);
        mScreen.addPreference(preference);

        mControllerTask.run();

        verify(mTestController).updateState(any(Preference.class));
    }

    static class TestPreferenceController extends AbstractPreferenceController {
        private boolean mAvailable;
        private String mKey;

        TestPreferenceController(Context context) {
            super(context);
            mAvailable = true;
        }

        @Override
        public boolean isAvailable() {
            return mAvailable;
        }

        @Override
        public String getPreferenceKey() {
            return mKey;
        }

        void setAvailable(boolean available) {
            mAvailable = available;
        }

        void setKey(String key) {
            mKey = key;
        }
    }
}
Loading