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

Commit 15506404 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Allow copy on long press of build number

Test: manual
Test: atest QSFooterImpl
Fixes: 159103568
Change-Id: Iaccac45462dd886a0139273244793887133db436
parent ea6abab5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -2829,4 +2829,9 @@
    <string name="media_output_dialog_connect_failed">Couldn\'t connect. Try again.</string>
    <!-- Title for pairing item [CHAR LIMIT=60] -->
    <string name="media_output_dialog_pairing_new">Pair new device</string>

    <!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
    <string name="build_number_clip_data_label">Build number</string>
    <!-- Text to display when copying the build number off QS [CHAR LIMIT=NONE]-->
    <string name="build_number_copy_toast">Build number copied to clipboard.</string>
</resources>
+18 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;

import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -34,6 +36,7 @@ import android.os.Handler;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
@@ -154,6 +157,19 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
        mActionsContainer = findViewById(R.id.qs_footer_actions_container);
        mEditContainer = findViewById(R.id.qs_footer_actions_edit_container);
        mBuildText = findViewById(R.id.build);
        mBuildText.setOnLongClickListener(view -> {
            CharSequence buildText = mBuildText.getText();
            if (!TextUtils.isEmpty(buildText)) {
                ClipboardManager service =
                        mUserTracker.getUserContext().getSystemService(ClipboardManager.class);
                String label = mContext.getString(R.string.build_number_clip_data_label);
                service.setPrimaryClip(ClipData.newPlainText(label, buildText));
                Toast.makeText(mContext, R.string.build_number_copy_toast, Toast.LENGTH_SHORT)
                        .show();
                return true;
            }
            return false;
        });

        // RenderThread is doing more harm than good when touching the header (to expand quick
        // settings), so disable it for this view
@@ -180,6 +196,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
            mBuildText.setSelected(true);
            mShouldShowBuildText = true;
        } else {
            mBuildText.setText(null);
            mShouldShowBuildText = false;
            mBuildText.setSelected(false);
        }
@@ -321,6 +338,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
        mMultiUserSwitch.setClickable(mMultiUserSwitch.getVisibility() == View.VISIBLE);
        mEdit.setClickable(mEdit.getVisibility() == View.VISIBLE);
        mSettingsButton.setClickable(mSettingsButton.getVisibility() == View.VISIBLE);
        mBuildText.setLongClickable(mBuildText.getVisibility() == View.VISIBLE);
    }

    private void updateVisibilities() {
+36 −1
Original line number Diff line number Diff line
@@ -14,17 +14,22 @@

package com.android.systemui.qs;

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import androidx.test.filters.SmallTest;

@@ -33,12 +38,16 @@ import com.android.systemui.R.id;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.utils.leaks.LeakCheckedTest;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@@ -48,19 +57,45 @@ public class QSFooterImplTest extends LeakCheckedTest {
    private QSFooterImpl mFooter;
    private ActivityStarter mActivityStarter;
    private DeviceProvisionedController mDeviceProvisionedController;
    private UserInfoController mUserInfoController;
    private UserTracker mUserTracker;
    @Mock
    private ClipboardManager mClipboardManager;

    @Before
    public void setup() throws Exception {
        MockitoAnnotations.initMocks(this);

        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
        mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
        mDeviceProvisionedController = mDependency.injectMockDependency(
                DeviceProvisionedController.class);
        mDependency.injectMockDependency(UserTracker.class);
        mUserInfoController = mDependency.injectMockDependency(UserInfoController.class);
        mUserTracker = mDependency.injectMockDependency(UserTracker.class);

        mContext.addMockSystemService(ClipboardManager.class, mClipboardManager);

        when(mUserTracker.getUserContext()).thenReturn(mContext);

        TestableLooper.get(this).runWithLooper(
                () -> mFooter = (QSFooterImpl) LayoutInflater.from(mContext).inflate(
                        R.layout.qs_footer_impl, null));
    }

    @Test
    public void testBuildTextCopy() {
        TextView buildTextView = mFooter.requireViewById(R.id.build);
        CharSequence buildText = "TEST";
        buildTextView.setText(buildText);
        buildTextView.setLongClickable(true);

        buildTextView.performLongClick();

        ArgumentCaptor<ClipData> captor = ArgumentCaptor.forClass(ClipData.class);
        verify(mClipboardManager).setPrimaryClip(captor.capture());
        assertThat(captor.getValue().getItemAt(0).getText()).isEqualTo(buildText);
    }

    @Test
    @Ignore("failing")
    public void testSettings_UserNotSetup() {