Merge "Remove old format contextual card log" into qt-dev
This commit is contained in:
@@ -20,17 +20,4 @@ import java.util.List;
|
|||||||
|
|
||||||
/** Feature provider for the contextual card feature. */
|
/** Feature provider for the contextual card feature. */
|
||||||
public interface ContextualCardFeatureProvider {
|
public interface ContextualCardFeatureProvider {
|
||||||
|
|
||||||
/** Homepage displays. */
|
|
||||||
void logHomepageDisplay(long latency);
|
|
||||||
|
|
||||||
/** When user clicks dismiss in contextual card */
|
|
||||||
void logContextualCardDismiss(ContextualCard card);
|
|
||||||
|
|
||||||
/** After ContextualCardManager decides which cards will be displayed/hidden */
|
|
||||||
void logContextualCardDisplay(List<ContextualCard> showedCards,
|
|
||||||
List<ContextualCard> hiddenCards);
|
|
||||||
|
|
||||||
/** When user clicks toggle/title area of a contextual card. */
|
|
||||||
void logContextualCardClick(ContextualCard card, int sliceRow, int tapTarget, int uiPosition);
|
|
||||||
}
|
}
|
||||||
|
@@ -16,161 +16,12 @@
|
|||||||
|
|
||||||
package com.android.settings.homepage.contextualcards;
|
package com.android.settings.homepage.contextualcards;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
public class ContextualCardFeatureProviderImpl implements ContextualCardFeatureProvider {
|
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 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 uri
|
|
||||||
private static final String EXTRA_CONTEXTUALCARD_URI = "uri";
|
|
||||||
|
|
||||||
// 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 card ui position
|
|
||||||
private static final String EXTRA_CONTEXTUALCARD_UI_POSTITION = "ui_position";
|
|
||||||
|
|
||||||
// contextual homepage display latency
|
|
||||||
private static final String EXTRA_LATENCY = "latency";
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
public ContextualCardFeatureProviderImpl(Context context) {
|
public ContextualCardFeatureProviderImpl(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logHomepageDisplay(long latency) {
|
|
||||||
sendBroadcast(new Intent()
|
|
||||||
.putExtra(EXTRA_CONTEXTUALCARD_ACTION_TYPE, CONTEXTUAL_HOME_SHOW)
|
|
||||||
.putExtra(EXTRA_LATENCY, latency));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logContextualCardDismiss(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_URI, card.getSliceUri().toString());
|
|
||||||
intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logContextualCardDisplay(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(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void logContextualCardClick(ContextualCard card, int row,
|
|
||||||
int actionType, int uiPosition) {
|
|
||||||
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_URI, card.getSliceUri().toString());
|
|
||||||
intent.putExtra(EXTRA_CONTEXTUALCARD_SCORE, card.getRankingScore());
|
|
||||||
intent.putExtra(EXTRA_CONTEXTUALCARD_ROW, row);
|
|
||||||
intent.putExtra(EXTRA_CONTEXTUALCARD_TAP_TARGET, actionTypeToTapTarget(actionType));
|
|
||||||
intent.putExtra(EXTRA_CONTEXTUALCARD_UI_POSTITION, uiPosition);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
void sendBroadcast(final Intent intent) {
|
|
||||||
intent.setPackage(mContext.getString(R.string.config_settingsintelligence_package_name));
|
|
||||||
final String action = mContext.getString(R.string.config_settingsintelligence_log_action);
|
|
||||||
if (!TextUtils.isEmpty(action)) {
|
|
||||||
intent.setAction(action);
|
|
||||||
mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@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())
|
|
||||||
.setCardScore(card.getRankingScore())
|
|
||||||
.build()));
|
|
||||||
return builder.build().toByteArray();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -228,8 +228,6 @@ public class ContextualCardManager implements ContextualCardLoader.CardContentLo
|
|||||||
}
|
}
|
||||||
//only log homepage display upon a fresh launch
|
//only log homepage display upon a fresh launch
|
||||||
final long totalTime = System.currentTimeMillis() - mStartTime;
|
final long totalTime = System.currentTimeMillis() - mStartTime;
|
||||||
FeatureFactory.getFactory(mContext).getContextualCardFeatureProvider(mContext)
|
|
||||||
.logHomepageDisplay(totalTime);
|
|
||||||
metricsFeatureProvider.action(mContext,
|
metricsFeatureProvider.action(mContext,
|
||||||
SettingsEnums.ACTION_CONTEXTUAL_HOME_SHOW, (int) totalTime);
|
SettingsEnums.ACTION_CONTEXTUAL_HOME_SHOW, (int) totalTime);
|
||||||
|
|
||||||
|
@@ -78,11 +78,6 @@
|
|||||||
<item>fake_package/fake_service</item>
|
<item>fake_package/fake_service</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<!-- Settings intelligence interaction log intent action -->
|
|
||||||
<string name="config_settingsintelligence_log_action" translatable="false">
|
|
||||||
aaa.bbb.ccc
|
|
||||||
</string>
|
|
||||||
|
|
||||||
<!-- List of packages that should be whitelisted for slice uri access. Do not translate -->
|
<!-- List of packages that should be whitelisted for slice uri access. Do not translate -->
|
||||||
<string-array name="slice_whitelist_package_names" translatable="false">
|
<string-array name="slice_whitelist_package_names" translatable="false">
|
||||||
<item>com.android.settings.slice_whitelist_package</item>
|
<item>com.android.settings.slice_whitelist_package</item>
|
||||||
|
@@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.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 org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
public class ContextualCardFeatureProviderImplTest {
|
|
||||||
|
|
||||||
private Context mContext;
|
|
||||||
private ContextualCardFeatureProviderImpl mImpl;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
mContext = spy(RuntimeEnvironment.application);
|
|
||||||
mImpl = new ContextualCardFeatureProviderImpl(mContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void sendBroadcast_emptyAction_notSendBroadcast() {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
mImpl.sendBroadcast(intent);
|
|
||||||
|
|
||||||
verify(mContext, never()).sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Config(qualifiers = "mcc999")
|
|
||||||
public void sendBroadcast_hasAction_sendBroadcast() {
|
|
||||||
final Intent intent = new Intent();
|
|
||||||
mImpl.sendBroadcast(intent);
|
|
||||||
|
|
||||||
verify(mContext).sendBroadcastAsUser(intent, UserHandle.CURRENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Config(qualifiers = "mcc999")
|
|
||||||
public void logContextualCardDisplay_hasAction_sendBroadcast() {
|
|
||||||
mImpl.logContextualCardDisplay(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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -197,8 +197,8 @@ public class ContextualCardLoaderTest {
|
|||||||
|
|
||||||
mContextualCardLoader.getDisplayableCards(new ArrayList<>());
|
mContextualCardLoader.getDisplayableCards(new ArrayList<>());
|
||||||
|
|
||||||
verify(mFakeFeatureFactory.mContextualCardFeatureProvider, never())
|
verify(mFakeFeatureFactory.metricsFeatureProvider, never()).action(any(),
|
||||||
.logContextualCardDisplay(anyList(), anyList());
|
eq(SettingsEnums.ACTION_CONTEXTUAL_CARD_SHOW), any(String.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContextualCard getContextualCard(String sliceUri) {
|
private ContextualCard getContextualCard(String sliceUri) {
|
||||||
|
Reference in New Issue
Block a user