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

Commit 1ad5c980 authored by Raff Tsai's avatar Raff Tsai Committed by Android (Google) Code Review
Browse files

Merge "Add log feature"

parents 6f8dc162 da7a5d11
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -151,6 +151,9 @@
        com.android.settings.intelligence
    </string>

    <!-- Settings intelligence interaction log intent action -->
    <string name="config_settingsintelligence_log_action" translatable="false"></string>

    <!-- Emergency app package name -->
    <string name="config_emergency_package_name" translatable="false">
        com.android.emergency
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.homepage.contextualcards;

import android.content.Context;

import java.util.List;

/** Feature provider for the contextual card feature. */
public interface ContextualCardFeatureProvider {

    /** Homepage displays. */
    public void logHomepageDisplay(Context context, Long latency);

    /** When user clicks dismiss in contextual card */
    public void logContextualCardDismiss(Context context, ContextualCard card);

    /** After ContextualCardManager decides which cards will be displayed/hidden */
    public void logContextualCardDisplay(Context context, List<ContextualCard> showedCards,
            List<ContextualCard> hiddenCards);

    /** When user clicks toggle/title area of a contextual card. */
    public void logContextualCardClick(Context context, ContextualCard card, int row,
            int tapTarget);
}
+136 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.homepage.contextualcards;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.slice.widget.EventInfo;

import com.android.settings.R;

import java.util.List;

public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureProvider {
    private static final String TAG = "ContextualCardFeature";

    // Contextual card interaction logs
    // Settings Homepage shows
    private static final int CONTEXTUAL_HOME_SHOW = 38;

    // 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;

    // Contextual card is clicked , log card name, score, tap area
    private static final int CONTEXTUAL_CARD_CLICK = 42;

    // SettingsLogBroadcastReceiver contracts
    // contextual card name
    private static final String EXTRA_CONTEXTUALCARD_NAME = "name";

    // contextual card score
    private static final String EXTRA_CONTEXTUALCARD_SCORE = "score";

    // contextual card clicked row
    private static final String EXTRA_CONTEXTUALCARD_ROW = "row";

    // contextual card tap target
    private static final String EXTRA_CONTEXTUALCARD_TAP_TARGET = "target";

    // contextual homepage display latency
    private static final String EXTRA_LATENCY = "latency";

    // log type
    private static final String EXTRA_CONTEXTUALCARD_ACTION_TYPE = "type";


    // Contextual card tap target
    private static final int TARGET_DEFAULT = 0;

    // Click title area
    private static final int TARGET_TITLE = 1;

    // Click toggle
    private static final int TARGET_TOGGLE = 2;

    // Click slider
    private static final int TARGET_SLIDER = 3;

    @Override
    public void logHomepageDisplay(Context context, Long latency) {
    }

    @Override
    public void logContextualCardDismiss(Context context, ContextualCard card) {
        final Intent intent = new Intent();
        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_DISMISS);
        intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
        intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
        sendBroadcast(context, intent);
    }

    @Override
    public void logContextualCardDisplay(Context context, List<ContextualCard> showCards,
            List<ContextualCard> hiddenCards) {
    }

    @Override
    public void logContextualCardClick(Context context, ContextualCard card, int row,
            int actionType) {
        final Intent intent = new Intent();
        intent.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_CARD_CLICK);
        intent.putExtra(EXTRA_CONTEXTUALCARD_NAME, card.getName());
        intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
        intent.putExtra(EXTRA_CONTEXTUALCARD_ROW, row);
        intent.putExtra(EXTRA_CONTEXTUALCARD_TAP_TARGET, actionTypeToTapTarget(actionType));
        sendBroadcast(context, intent);
    }

    @VisibleForTesting
    void sendBroadcast(final Context context, final Intent intent) {
        intent.setPackage(context.getString(R.string.config_settingsintelligence_package_name));
        final String action = context.getString(R.string.config_settingsintelligence_log_action);
        if (!TextUtils.isEmpty(action)) {
            intent.setAction(action);
            context.sendBroadcast(intent);
        }
    }

    private int actionTypeToTapTarget(int actionType) {
        switch (actionType) {
            case EventInfo.ACTION_TYPE_CONTENT:
                return TARGET_TITLE;
            case EventInfo.ACTION_TYPE_TOGGLE:
                return TARGET_TOGGLE;
            case EventInfo.ACTION_TYPE_SLIDER:
                return TARGET_SLIDER;
            default:
                Log.w(TAG, "unknown type " + actionType);
                return TARGET_DEFAULT;
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -26,8 +26,10 @@ import com.android.settings.R;
import com.android.settings.homepage.contextualcards.CardDatabaseHelper;
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardController;
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
import com.android.settings.homepage.contextualcards.ContextualCardFeedbackDialog;
import com.android.settings.homepage.contextualcards.ContextualCardUpdateListener;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.ThreadUtils;

/**
@@ -67,6 +69,9 @@ public class SliceContextualCardController implements ContextualCardController {
            dbHelper.markContextualCardAsDismissed(mContext, card.getName());
        });
        showFeedbackDialog(card);
        final ContextualCardFeatureProvider contexualCardFeatureProvider =
                FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
        contexualCardFeatureProvider.logContextualCardDismiss(mContext, card);
    }

    @Override
+22 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.net.Uri;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
import android.widget.Button;
@@ -38,10 +39,13 @@ import androidx.slice.widget.SliceView;

import com.android.settings.R;
import com.android.settings.homepage.contextualcards.ContextualCard;
import com.android.settings.homepage.contextualcards.ContextualCardFeatureProvider;
import com.android.settings.homepage.contextualcards.ContextualCardRenderer;
import com.android.settings.homepage.contextualcards.ControllerRendererPool;
import com.android.settings.overlay.FeatureFactory;

import java.util.Map;
import java.util.Set;

/**
 * Card renderer for {@link ContextualCard} built as slices.
@@ -58,6 +62,7 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
    private final Context mContext;
    private final LifecycleOwner mLifecycleOwner;
    private final ControllerRendererPool mControllerRendererPool;
    private final Set<ContextualCard> mCardSet;

    public SliceContextualCardRenderer(Context context, LifecycleOwner lifecycleOwner,
            ControllerRendererPool controllerRendererPool) {
@@ -65,6 +70,7 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
        mLifecycleOwner = lifecycleOwner;
        mSliceLiveDataMap = new ArrayMap<>();
        mControllerRendererPool = controllerRendererPool;
        mCardSet = new ArraySet<>();
    }

    @Override
@@ -99,6 +105,7 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,
            sliceLiveData = SliceLiveData.fromUri(mContext, uri);
            mSliceLiveDataMap.put(uri.toString(), sliceLiveData);
        }
        mCardSet.add(card);

        sliceLiveData.removeObservers(mLifecycleOwner);
        sliceLiveData.observe(mLifecycleOwner, slice -> {
@@ -128,14 +135,27 @@ public class SliceContextualCardRenderer implements ContextualCardRenderer,

        final Button btnRemove = cardHolder.itemView.findViewById(R.id.remove);
        btnRemove.setOnClickListener(v -> {
            mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(
                    card);
            mControllerRendererPool.getController(mContext, card.getCardType()).onDismissed(card);
        });
    }

    @Override
    public void onSliceAction(@NonNull EventInfo eventInfo, @NonNull SliceItem sliceItem) {
        //TODO(b/79698338): Log user interaction

        // sliceItem.getSlice().getUri() is like
        // content://android.settings.slices/action/wifi/_gen/0/_gen/0
        // contextualCard.getSliceUri() is prefix of sliceItem.getSlice().getUri()
        for (ContextualCard card : mCardSet) {
            if (sliceItem.getSlice().getUri().toString().startsWith(
                    card.getSliceUri().toString())) {
                ContextualCardFeatureProvider contexualCardFeatureProvider =
                        FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider();
                contexualCardFeatureProvider.logContextualCardClick(mContext, card,
                        eventInfo.rowIndex, eventInfo.actionType);
                break;
            }
        }
    }

    public static class SliceViewHolder extends RecyclerView.ViewHolder {
Loading