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

Commit 93668d60 authored by Peter_Liang's avatar Peter_Liang
Browse files

New feature “Text and reading options” for SetupWizard, Wallpaper, and Settings (4/n).

- Extending the interface of AppGridView to be flexible. It will be used
in the TextReadingPreferenceFragment.
  1. Add a new attribute "appCounts" into the view.
  2. Default app counts as 6 if not set the attribute.

Bug: 211503117
Test: make -j64 RunSettingsRoboTests ROBOTEST_FILTER=AppGridViewTest
Change-Id: I94a5f1d037551f6faba0300a176feb11fba1f203
parent 3ae979bf
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@
        <attr name="iconBackgroundColor" format="reference|color" />
    </declare-styleable>

    <!-- For AppGridView -->
    <declare-styleable name="AppGridView">
        <attr name="appCount" format="integer" />
    </declare-styleable>

    <attr name="switchBarTheme" format="reference" />
    <attr name="switchBarMarginStart" format="dimension" />
    <attr name="switchBarMarginEnd" format="dimension" />
+39 −6
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@@ -31,6 +33,7 @@ import android.widget.GridView;
import android.widget.ImageView;

import androidx.annotation.VisibleForTesting;
import androidx.core.util.Preconditions;

import com.android.settings.R;

@@ -38,7 +41,18 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * The grid view for displaying the application entries.
 *
 * <p> The attribute value {@code appCount} from XML should be more than or equal to 1, otherwise
 * throws an {@link IllegalArgumentException}.</p>
 */
public class AppGridView extends GridView {
    private static final String TAG = "AppGridView";

    private static final int APP_COUNT_DEF_VALUE = 6;
    private int mAppCount = APP_COUNT_DEF_VALUE;

    public AppGridView(Context context) {
        super(context);
        init(context);
@@ -46,24 +60,36 @@ public class AppGridView extends GridView {

    public AppGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        applyAttributeSet(context, attrs);
        init(context);
    }

    public AppGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        applyAttributeSet(context, attrs);
        init(context);
    }

    public AppGridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleResId) {
        super(context, attrs, defStyleAttr, defStyleResId);

        applyAttributeSet(context, attrs);
        init(context);

    }

    private void init(Context context) {
        setAdapter(new AppsAdapter(context, R.layout.screen_zoom_preview_app_icon,
                android.R.id.text1, android.R.id.icon1));
                android.R.id.text1, android.R.id.icon1, mAppCount));
    }

    private void applyAttributeSet(Context context, AttributeSet attrs) {
        final TypedArray styledAttrs =
                context.obtainStyledAttributes(attrs, R.styleable.AppGridView);
        mAppCount =
                styledAttrs.getInteger(R.styleable.AppGridView_appCount, APP_COUNT_DEF_VALUE);
        Preconditions.checkArgument(mAppCount >= 1,
                /* errorMessage= */ "App count may not be negative or zero");

        styledAttrs.recycle();
    }

    /**
@@ -73,12 +99,15 @@ public class AppGridView extends GridView {
    public static class AppsAdapter extends ArrayAdapter<ActivityEntry> {
        private final PackageManager mPackageManager;
        private final int mIconResId;
        private final int mAppCount;

        public AppsAdapter(Context context, int layout, int textResId, int iconResId) {
        public AppsAdapter(Context context, int layout, int textResId, int iconResId,
                int appCount) {
            super(context, layout, textResId);

            mIconResId = iconResId;
            mPackageManager = context.getPackageManager();
            mAppCount = appCount;

            loadAllApps();
        }
@@ -108,20 +137,24 @@ public class AppGridView extends GridView {
        }

        private void loadAllApps() {
            final int needAppCount = 6;
            final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

            final PackageManager pm = mPackageManager;
            final ArrayList<ActivityEntry> results = new ArrayList<>();
            final List<ResolveInfo> infos = pm.queryIntentActivities(mainIntent, 0);

            if (mAppCount > infos.size()) {
                Log.d(TAG, "Visible app icon count does not meet the target count.");
            }

            final IconDrawableFactory iconFactory = IconDrawableFactory.newInstance(getContext());
            for (ResolveInfo info : infos) {
                final CharSequence label = info.loadLabel(pm);
                if (label != null) {
                    results.add(new ActivityEntry(info, label.toString(), iconFactory));
                }
                if (results.size() >= needAppCount) {
                if (results.size() >= mAppCount) {
                    break;
                }
            }
+81 −0
Original line number Diff line number Diff line
@@ -18,26 +18,39 @@ package com.android.settings.display;

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.IconDrawableFactory;

import com.android.settings.R;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;

import java.util.ArrayList;
import java.util.List;

/**
 * Tests for {@link AppGridView}.
 */
@RunWith(RobolectricTestRunner.class)
public class AppGridViewTest {

@@ -87,4 +100,72 @@ public class AppGridViewTest {
        assertThat(entry1.compareTo(entry2)).isEqualTo(0);
        assertThat(entry1.compareTo(entry3)).isNotEqualTo(0);
    }

    @Test
    public void noAppCountAttribute_matchListSize() {
        final int appCountFromSystem = 8;
        setUpResolveInfos(appCountFromSystem);

        final AppGridView appGridView = new AppGridView(mContext, /* attrs= */ null);

        assertThat(appGridView.getAdapter().getCount()).isEqualTo(/* expected= */ 6);
    }

    @Test
    public void setAppCountAttribute_matchListSize() {
        final int appCountFromSystem = 8;
        final int appCountFromAttr = 7;
        setUpResolveInfos(appCountFromSystem);

        final AppGridView appGridView =
                new AppGridView(mContext, createAttributeSet(appCountFromAttr));

        assertThat(appGridView.getAdapter().getCount()).isEqualTo(appCountFromAttr);
    }

    @Test(expected = IllegalArgumentException.class)
    public void setAppCountAttribute_belowLowerBound_matchListSize() {
        final int appCountFromSystem = 9;
        final int appCountFromAttr = -1; // The num is just for the test.
        setUpResolveInfos(appCountFromSystem);

        new AppGridView(mContext, createAttributeSet(appCountFromAttr));
    }

    @Test
    public void setAppCountAttribute_aboveUpperBound_matchListSize() {
        final int appCountFromSystem = 10;
        final int appCountFromAttr = 15;
        setUpResolveInfos(appCountFromSystem);

        final AppGridView appGridView =
                new AppGridView(mContext, createAttributeSet(appCountFromAttr));

        assertThat(appGridView.getAdapter().getCount()).isEqualTo(appCountFromSystem);
    }

    private AttributeSet createAttributeSet(int appCount) {
        return Robolectric.buildAttributeSet()
                .addAttribute(R.attr.appCount, String.valueOf(appCount))
                .build();
    }

    private void setUpResolveInfos(int appCount) {
        when(mContext.getPackageManager().queryIntentActivities(
                any(Intent.class), anyInt()))
                .thenReturn(createFakeResolveInfos(appCount));
    }

    private List<ResolveInfo> createFakeResolveInfos(int count) {
        final List<ResolveInfo> list = new ArrayList<>();

        for (int i = 0; i < count; i++) {
            final ResolveInfo info = new ResolveInfo();
            info.nonLocalizedLabel = String.valueOf(i);

            list.add(info);
        }

        return list;
    }
}