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

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

Merge "Log contextual card is visible and homepage is displayed event"

parents 09272dab e58e0c6e
Loading
Loading
Loading
Loading
+31 −6
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

package com.android.settings.homepage.contextualcards;

import android.annotation.NonNull;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

@@ -25,6 +27,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.slice.widget.EventInfo;

import com.android.settings.R;
import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;

import java.util.List;

@@ -38,10 +41,6 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
    // Contextual card shows, log card name and rank
    private static final int CONTEXTUAL_CARD_SHOW = 39;

    // Contextual card is eligible to be shown, but doesn't rank high
    // enough, log card name and score
    private static final int CONTEXTUAL_CARD_NOT_SHOW = 40;

    // Contextual card is dismissed, log card name
    private static final int CONTEXTUAL_CARD_DISMISS = 41;

@@ -67,6 +66,11 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
    // log type
    private static final String EXTRA_CONTEXTUALCARD_ACTION_TYPE = "type";

    // displayed contextual cards
    private static final String EXTRA_CONTEXTUALCARD_VISIBLE = "visible";

    // hidden contextual cards
    private static final String EXTRA_CONTEXTUALCARD_HIDDEN = "hidden";

    // Contextual card tap target
    private static final int TARGET_DEFAULT = 0;
@@ -82,6 +86,10 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP

    @Override
    public void logHomepageDisplay(Context context, Long latency) {
        final Intent intent = new Intent();
        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_HOME_SHOW);
        intent.putExtra(EXTRA_LATENCY, latency);
        sendBroadcast(context, intent);
    }

    @Override
@@ -94,8 +102,13 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
    }

    @Override
    public void logContextualCardDisplay(Context context, List<ContextualCard> showCards,
    public void logContextualCardDisplay(Context context, List<ContextualCard> visibleCards,
            List<ContextualCard> hiddenCards) {
        final Intent intent = new Intent();
        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_SHOW);
        intent.putExtra(EXTRA_CONTEXTUALCARD_VISIBLE, serialize(visibleCards));
        intent.putExtra(EXTRA_CONTEXTUALCARD_HIDDEN, serialize(hiddenCards));
        sendBroadcast(context, intent);
    }

    @Override
@@ -116,7 +129,7 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
        final String action = context.getString(R.string.config_settingsintelligence_log_action);
        if (!TextUtils.isEmpty(action)) {
            intent.setAction(action);
            context.sendBroadcast(intent);
            context.sendBroadcastAsUser(intent, UserHandle.ALL);
        }
    }

@@ -133,4 +146,16 @@ public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureP
                return TARGET_DEFAULT;
        }
    }

    @VisibleForTesting
    @NonNull
    byte[] serialize(List<ContextualCard> cards) {
        final ContextualCardList.Builder builder = ContextualCardList.newBuilder();
        cards.stream().forEach(card -> builder.addCard(
                com.android.settings.intelligence.ContextualCardProto.ContextualCard.newBuilder()
                        .setSliceUri(card.getSliceUri().toString())
                        .setCardName(card.getName())
                        .build()));
        return builder.build().toByteArray();
    }
}
+43 −17
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@ import static android.app.slice.Slice.HINT_ERROR;

import static androidx.slice.widget.SliceLiveData.SUPPORTED_SPECS;

import static com.android.settings.slices.CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI;
import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI;

import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
@@ -34,7 +37,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.slice.Slice;

import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.AsyncLoaderCompat;

import java.util.ArrayList;
@@ -103,27 +106,50 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>
        return getFinalDisplayableCards(result);
    }

    // Get final displayed cards and log what cards will be displayed/hidden
    @VisibleForTesting
    List<ContextualCard> getFinalDisplayableCards(List<ContextualCard> candidates) {
        List<ContextualCard> eligibleCards = filterEligibleCards(candidates);
        eligibleCards = eligibleCards.stream().limit(DEFAULT_CARD_COUNT).collect(
                Collectors.toList());
        final List<ContextualCard> eligibleCards = filterEligibleCards(candidates);
        final List<ContextualCard> visibleCards = new ArrayList<>();
        final List<ContextualCard> hiddenCards = new ArrayList<>();

        final int size = eligibleCards.size();
        for (int i = 0; i < size; i++) {
            if (i < DEFAULT_CARD_COUNT) {
                visibleCards.add(eligibleCards.get(i));
            } else {
                hiddenCards.add(eligibleCards.get(i));
            }
        }

        if (eligibleCards.size() <= 2 || getNumberOfLargeCard(eligibleCards) == 0) {
            return eligibleCards;
        try {
            // The maximum cards are four small cards OR
            // one large card with two small cards OR
            // two large cards
            if (visibleCards.size() <= 2 || getNumberOfLargeCard(visibleCards) == 0) {
                // four small cards
                return visibleCards;
            }

        if (eligibleCards.size() == DEFAULT_CARD_COUNT) {
            eligibleCards.remove(eligibleCards.size() - 1);
            if (visibleCards.size() == DEFAULT_CARD_COUNT) {
                hiddenCards.add(visibleCards.remove(visibleCards.size() - 1));
            }

        if (getNumberOfLargeCard(eligibleCards) == 1) {
            return eligibleCards;
            if (getNumberOfLargeCard(visibleCards) == 1) {
                // One large card with two small cards
                return visibleCards;
            }

        eligibleCards.remove(eligibleCards.size() - 1);
            hiddenCards.add(visibleCards.remove(visibleCards.size() - 1));

        return eligibleCards;
            // Two large cards
            return visibleCards;
        } finally {
            final ContextualCardFeatureProvider contextualCardFeatureProvider =
                    FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
            contextualCardFeatureProvider.logContextualCardDisplay(mContext, visibleCards,
                    hiddenCards);
        }
    }

    @VisibleForTesting
@@ -169,8 +195,8 @@ public class ContextualCardLoader extends AsyncLoaderCompat<List<ContextualCard>

    private int getNumberOfLargeCard(List<ContextualCard> cards) {
        return (int) cards.stream()
                .filter(card -> card.getSliceUri().equals(CustomSliceRegistry.WIFI_SLICE_URI)
                        || card.getSliceUri().equals(CustomSliceRegistry.CONNECTED_DEVICE_SLICE_URI))
                .filter(card -> card.getSliceUri().equals(WIFI_SLICE_URI)
                        || card.getSliceUri().equals(CONNECTED_DEVICE_SLICE_URI))
                .count();
    }

+8 −2
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

package com.android.settings.homepage.contextualcards;

import static com.android.settings.homepage.contextualcards.ContextualCardLoader
        .CARD_CONTENT_LOADER_ID;
import static com.android.settings.homepage.contextualcards.ContextualCardLoader.CARD_CONTENT_LOADER_ID;

import static java.util.stream.Collectors.groupingBy;

@@ -33,6 +32,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;

import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;

@@ -72,6 +72,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
    private final List<LifecycleObserver> mLifecycleObservers;

    private ContextualCardUpdateListener mListener;
    private long mStartTime;

    public ContextualCardManager(Context context, Lifecycle lifecycle) {
        mContext = context;
@@ -86,6 +87,7 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
    }

    void loadContextualCards(ContextualCardsFragment fragment) {
        mStartTime = System.currentTimeMillis();
        final CardContentLoaderCallbacks cardContentLoaderCallbacks =
                new CardContentLoaderCallbacks(mContext);
        cardContentLoaderCallbacks.setListener(this);
@@ -168,6 +170,10 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
    @Override
    public void onFinishCardLoading(List<ContextualCard> cards) {
        onContextualCardUpdated(cards.stream().collect(groupingBy(ContextualCard::getCardType)));
        final long elapsedTime = System.currentTimeMillis() - mStartTime;
        final ContextualCardFeatureProvider contextualCardFeatureProvider =
                FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
        contextualCardFeatureProvider.logHomepageDisplay(mContext, elapsedTime);
    }

    public ControllerRendererPool getControllerRendererPool() {
+43 −2
Original line number Diff line number Diff line
@@ -16,13 +16,20 @@

package com.android.settings.homepage.contextualcards;

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

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

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.UserHandle;

import com.android.settings.intelligence.ContextualCardProto.ContextualCardList;
import com.android.settings.testutils.SettingsRobolectricTestRunner;

import org.junit.Before;
@@ -31,6 +38,9 @@ import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

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

@RunWith(SettingsRobolectricTestRunner.class)
public class ContextualCardFeatureProviderImplTest {

@@ -48,7 +58,7 @@ public class ContextualCardFeatureProviderImplTest {
        final Intent intent = new Intent();
        mImpl.sendBroadcast(mContext, intent);

        verify(mContext, never()).sendBroadcast(intent);
        verify(mContext, never()).sendBroadcastAsUser(intent, UserHandle.ALL);
    }

    @Test
@@ -57,6 +67,37 @@ public class ContextualCardFeatureProviderImplTest {
        final Intent intent = new Intent();
        mImpl.sendBroadcast(mContext, intent);

        verify(mContext).sendBroadcast(intent);
        verify(mContext).sendBroadcastAsUser(intent, UserHandle.ALL);
    }

    @Test
    @Config(qualifiers = "mcc999")
    public void logContextualCardDisplay_hasAction_sendBroadcast() {
        mImpl.logContextualCardDisplay(mContext, new ArrayList<>(), new ArrayList<>());

        verify(mContext).sendBroadcastAsUser(any(Intent.class), any());
    }

    @Test
    public void serialize_hasSizeTwo_returnSizeTwo() {
        final List<ContextualCard> cards = new ArrayList<>();
        cards.add(new ContextualCard.Builder()
                .setName("name1")
                .setSliceUri(Uri.parse("uri1"))
                .build());
        cards.add(new ContextualCard.Builder()
                .setName("name2")
                .setSliceUri(Uri.parse("uri2"))
                .build());


        final byte[] data = mImpl.serialize(cards);

        try {
            assertThat(ContextualCardList
                    .parseFrom(data).getCardCount()).isEqualTo(cards.size());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}
 No newline at end of file