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

Commit 2beb5442 authored by Stanley Wang's avatar Stanley Wang Committed by Android (Google) Code Review
Browse files

Merge "Implement the Copyable interface to BuildNumberPreferenceController"

parents 3a84f484 118a7124
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@
        android:title="@string/build_number"
        android:summary="@string/summary_placeholder"
        settings:allowDividerAbove="true"
        settings:enableCopying="true" />
        settings:enableCopying="true"
        settings:controller="com.android.settings.deviceinfo.BuildNumberPreferenceController"/>

</PreferenceScreen>
+46 −40
Original line number Diff line number Diff line
@@ -16,7 +16,11 @@

package com.android.settings.deviceinfo;

import static android.content.Context.CLIPBOARD_SERVICE;

import android.app.Activity;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -29,34 +33,30 @@ import android.text.TextUtils;
import android.widget.Toast;

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

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.InstrumentedPreferenceFragment;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ChooseLockSettingsHelper;
import com.android.settings.slices.Copyable;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.development.DevelopmentSettingsEnabler;

public class BuildNumberPreferenceController extends AbstractPreferenceController implements
        PreferenceControllerMixin, LifecycleObserver, OnResume {
public class BuildNumberPreferenceController extends BasePreferenceController implements Copyable,
        LifecycleObserver, OnStart {

    static final int TAPS_TO_BE_A_DEVELOPER = 7;
    static final int REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF = 100;

    private static final String KEY_BUILD_NUMBER = "build_number";

    private final Activity mActivity;
    private final InstrumentedPreferenceFragment mFragment;
    private Activity mActivity;
    private InstrumentedPreferenceFragment mFragment;
    private final UserManager mUm;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

@@ -66,56 +66,62 @@ public class BuildNumberPreferenceController extends AbstractPreferenceControlle
    private int mDevHitCountdown;
    private boolean mProcessingLastDevHit;

    public BuildNumberPreferenceController(Context context, Activity activity,
            InstrumentedPreferenceFragment fragment, Lifecycle lifecycle) {
        super(context);
        mActivity = activity;
        mFragment = fragment;
    public BuildNumberPreferenceController(Context context, String key) {
        super(context, key);
        mUm = (UserManager) context.getSystemService(Context.USER_SERVICE);
        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
        if (lifecycle != null) {
            lifecycle.addObserver(this);
    }

    public void setHost(InstrumentedPreferenceFragment fragment) {
        mFragment = fragment;
        mActivity = fragment.getActivity();
    }

    @Override
    public void displayPreference(PreferenceScreen screen) {
        super.displayPreference(screen);
        final Preference preference = screen.findPreference(KEY_BUILD_NUMBER);
        if (preference != null) {
    public CharSequence getSummary() {
        try {
                preference.setSummary(BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY));
                preference.setEnabled(true);
            return BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY);
        } catch (Exception e) {
                preference.setSummary(R.string.device_info_default);
            return mContext.getText(R.string.device_info_default);
        }
    }

    @Override
    public void onStart() {
        mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDevHitCountdown = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
                ? -1 : TAPS_TO_BE_A_DEVELOPER;
        mDevHitToast = null;
    }

    @Override
    public String getPreferenceKey() {
        return KEY_BUILD_NUMBER;
    public int getAvailabilityStatus() {
        return AVAILABLE;
    }

    @Override
    public boolean isAvailable() {
    public boolean isSliceable() {
        return true;
    }

    @Override
    public void onResume() {
        mDebuggingFeaturesDisallowedAdmin = RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDebuggingFeaturesDisallowedBySystem = RestrictedLockUtilsInternal.hasBaseUserRestriction(
                mContext, UserManager.DISALLOW_DEBUGGING_FEATURES, UserHandle.myUserId());
        mDevHitCountdown = DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)
                ? -1 : TAPS_TO_BE_A_DEVELOPER;
        mDevHitToast = null;
    public void copy() {
        final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
                CLIPBOARD_SERVICE);
        final ClipData clip = ClipData.newPlainText("text", getSummary());
        clipboard.setPrimaryClip(clip);

        final String toast = mContext.getString(R.string.copyable_slice_toast,
                mContext.getText(R.string.build_number));
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }

    @Override
    public boolean handlePreferenceTreeClick(Preference preference) {
        if (!TextUtils.equals(preference.getKey(), KEY_BUILD_NUMBER)) {
        if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
            return false;
        }
        if (Utils.isMonkeyRunning()) {
+5 −5
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ public class MyDeviceInfoFragment extends DashboardFragment
    private static final String LOG_TAG = "MyDeviceInfoFragment";
    private static final String KEY_MY_DEVICE_INFO_HEADER = "my_device_info_header";

    private BuildNumberPreferenceController mBuildNumberPreferenceController;

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.DEVICEINFO;
@@ -79,6 +81,8 @@ public class MyDeviceInfoFragment extends DashboardFragment
        super.onAttach(context);
        use(FirmwareVersionPreferenceController.class).setHost(this /*parent*/);
        use(DeviceModelPreferenceController.class).setHost(this /* parent */);
        mBuildNumberPreferenceController = use(BuildNumberPreferenceController.class);
        mBuildNumberPreferenceController.setHost(this /* parent */);
    }

    @Override
@@ -126,17 +130,13 @@ public class MyDeviceInfoFragment extends DashboardFragment
        controllers.add(new ManualPreferenceController(context));
        controllers.add(new FeedbackPreferenceController(fragment, context));
        controllers.add(new FccEquipmentIdPreferenceController(context));
        controllers.add(
                new BuildNumberPreferenceController(context, activity, fragment, lifecycle));
        controllers.add(new UptimePreferenceController(context, lifecycle));
        return controllers;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        final BuildNumberPreferenceController buildNumberPreferenceController =
                use(BuildNumberPreferenceController.class);
        if (buildNumberPreferenceController.onActivityResult(requestCode, resultCode, data)) {
        if (mBuildNumberPreferenceController.onActivityResult(requestCode, resultCode, data)) {
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);
+17 −16
Original line number Diff line number Diff line
@@ -16,22 +16,22 @@

package com.android.settings.deviceinfo;

import static android.content.Context.CLIPBOARD_SERVICE;

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

import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;

import android.app.Activity;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Build;
import android.os.Process;
import android.os.UserManager;
import android.provider.Settings;
import android.text.BidiFormatter;

import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
@@ -61,6 +61,8 @@ import org.robolectric.shadows.ShadowUserManager;
@Config(shadows = ShadowUtils.class)
public class BuildNumberPreferenceControllerTest {

    private static final String KEY_BUILD_NUMBER = "build_number";

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Activity mActivity;
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -86,8 +88,8 @@ public class BuildNumberPreferenceControllerTest {
        mFactory = FakeFeatureFactory.setupForTest();
        mLifecycleOwner = () -> mLifecycle;
        mLifecycle = new Lifecycle(mLifecycleOwner);
        mController =
                new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);
        mController = new BuildNumberPreferenceController(mContext, KEY_BUILD_NUMBER);
        mController.setHost(mFragment);

        mPreference = new Preference(mContext);
        mPreference.setKey(mController.getPreferenceKey());
@@ -101,15 +103,6 @@ public class BuildNumberPreferenceControllerTest {
        ShadowUtils.reset();
    }

    @Test
    public void displayPref_shouldAlwaysDisplay() {
        mController.displayPreference(mScreen);

        verify((Preference) mScreen.findPreference(mController.getPreferenceKey()))
                .setSummary(BidiFormatter.getInstance().unicodeWrap(Build.DISPLAY));
        verify(mScreen, never()).removePreference(any(Preference.class));
    }

    @Test
    public void handlePrefTreeClick_onlyHandleBuildNumberPref() {
        assertThat(mController.handlePreferenceTreeClick(mock(Preference.class))).isFalse();
@@ -198,8 +191,6 @@ public class BuildNumberPreferenceControllerTest {
    @Test
    public void onActivityResult_confirmPasswordRequestCompleted_enableDevPref() {
        mShadowUserManager.setIsAdminUser(true);
        mController =
                new BuildNumberPreferenceController(mContext, mActivity, mFragment, mLifecycle);

        final boolean activityResultHandled = mController.onActivityResult(
                BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
@@ -209,4 +200,14 @@ public class BuildNumberPreferenceControllerTest {
        assertThat(activityResultHandled).isTrue();
        assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isTrue();
    }

    @Test
    public void copy_shouldCopyBuildNumberToClipboard() {
        mController.copy();

        final ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(
                CLIPBOARD_SERVICE);
        final CharSequence data = clipboard.getPrimaryClip().getItemAt(0).getText();
        assertThat(data.toString()).isEqualTo(mController.getSummary());
    }
}
+1 −6
Original line number Diff line number Diff line
@@ -104,12 +104,7 @@ public class MyDeviceInfoFragmentTest {
    public void onActivityResult_shouldCallBuildNumberPreferenceController() {
        final BuildNumberPreferenceController controller =
            mock(BuildNumberPreferenceController.class);
        final Map<Class, List<AbstractPreferenceController>> preferenceControllers =
            new ArrayMap<>();
        final List<AbstractPreferenceController> controllerList = new ArrayList<>();
        controllerList.add(controller);
        preferenceControllers.put(BuildNumberPreferenceController.class, controllerList);
        ReflectionHelpers.setField(mSettings, "mPreferenceControllers", preferenceControllers);
        ReflectionHelpers.setField(mSettings, "mBuildNumberPreferenceController", controller);

        final int requestCode = 1;
        final int resultCode = 2;