/* * 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.testutils; import static android.app.slice.Slice.HINT_TITLE; import static android.app.slice.Slice.SUBTYPE_COLOR; import static android.app.slice.SliceItem.FORMAT_IMAGE; import static android.app.slice.SliceItem.FORMAT_INT; import static android.app.slice.SliceItem.FORMAT_TEXT; import static com.google.common.truth.Truth.assertThat; import android.app.PendingIntent; import android.content.Context; import android.text.TextUtils; import androidx.core.graphics.drawable.IconCompat; import androidx.slice.Slice; import androidx.slice.SliceItem; import androidx.slice.SliceMetadata; import androidx.slice.builders.ListBuilder; import androidx.slice.core.SliceAction; import androidx.slice.core.SliceQuery; import androidx.slice.widget.EventInfo; import com.android.settings.Utils; import com.android.settings.slices.SettingsSliceProvider; import com.android.settings.slices.SliceBuilderUtils; import com.android.settings.slices.SliceData; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; /** * Testing utility class to verify the contents of the different Settings Slices. * * TODO (77712944) check Summary, range (metadata.getRange()), toggle icons. */ public class SliceTester { /** * Test the contents of an intent based slice, including: * - No toggles * - Correct intent * - Correct title * - Correct keywords * - TTL * - Color */ public static void testSettingsIntentSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); final List toggles = metadata.getToggles(); assertThat(toggles).isEmpty(); final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); assertThat(primaryPendingIntent).isEqualTo( SliceBuilderUtils.getContentPendingIntent(context, sliceData)); assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); assertKeywords(metadata, sliceData); } /** * Test the contents of an toggle based slice, including: * - Contains one toggle * - Correct toggle intent * - Correct content intent * - Correct title * - Correct keywords * - TTL * - Color */ public static void testSettingsToggleSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); final List toggles = metadata.getToggles(); assertThat(toggles).hasSize(1); final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); final SliceAction mainToggleAction = toggles.get(0); assertThat(mainToggleAction.getIcon()).isNull(); // Check intent in Toggle Action final PendingIntent togglePendingIntent = mainToggleAction.getAction(); assertThat(togglePendingIntent).isEqualTo(SliceBuilderUtils.getActionIntent(context, SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData)); // Check primary intent final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); assertThat(primaryPendingIntent).isEqualTo( SliceBuilderUtils.getContentPendingIntent(context, sliceData)); assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); assertKeywords(metadata, sliceData); } /** * Test the contents of an slider based slice, including: * - No intent * - Correct title * - Correct keywords * - TTL * - Color */ public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat icon = primaryAction.getIcon(); if (icon == null) { final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); } else { final IconCompat expectedIcon = IconCompat.createWithResource(context, sliceData.getIconResource()); assertThat(expectedIcon.toString()).isEqualTo(icon.toString()); } final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); final int headerType = metadata.getHeaderType(); assertThat(headerType).isEqualTo(EventInfo.ROW_TYPE_SLIDER); // Check primary intent final PendingIntent primaryPendingIntent = primaryAction.getAction(); assertThat(primaryPendingIntent).isEqualTo( SliceBuilderUtils.getContentPendingIntent(context, sliceData)); assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); assertKeywords(metadata, sliceData); } /** * Test the copyable slice, including: * - No intent * - Correct title * - Correct intent * - Correct keywords * - TTL * - Color */ public static void testSettingsCopyableSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); final SliceAction primaryAction = metadata.getPrimaryAction(); final IconCompat expectedIcon = IconCompat.createWithResource(context, sliceData.getIconResource()); assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString()); final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); // Check primary intent final PendingIntent primaryPendingIntent = primaryAction.getAction(); assertThat(primaryPendingIntent).isEqualTo( SliceBuilderUtils.getContentPendingIntent(context, sliceData)); assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); assertKeywords(metadata, sliceData); } /** * Test the contents of an unavailable slice, including: * - No toggles * - Correct title * - Correct intent * - Correct keywords * - Color * - TTL */ public static void testSettingsUnavailableSlice(Context context, Slice slice, SliceData sliceData) { final SliceMetadata metadata = SliceMetadata.from(context, slice); final long sliceTTL = metadata.getExpiry(); assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY); final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR); final int color = colorItem.getInt(); assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context)); final List toggles = metadata.getToggles(); assertThat(toggles).isEmpty(); final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction(); assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent( context, sliceData)); assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle()); assertKeywords(metadata, sliceData); } /** * Assert any slice item contains title. * * @param sliceItems All slice items of a Slice. * @param title Title for asserting. */ public static void assertAnySliceItemContainsTitle(List sliceItems, String title) { assertThat(hasText(sliceItems, title, HINT_TITLE)).isTrue(); } /** * Assert any slice item contains subtitle. * * @param sliceItems All slice items of a Slice. * @param subtitle Subtitle for asserting. */ public static void assertAnySliceItemContainsSubtitle(List sliceItems, String subtitle) { // Subtitle has no hints assertThat(hasText(sliceItems, subtitle, null /* hints */)).isTrue(); } /** * Assert no slice item contains subtitle. * * @param sliceItems All slice items of a Slice. * @param subtitle Subtitle for asserting. */ public static void assertNoSliceItemContainsSubtitle(List sliceItems, String subtitle) { // Subtitle has no hints assertThat(hasText(sliceItems, subtitle, null /* hints */)).isFalse(); } private static boolean hasText(List sliceItems, String text, String hints) { boolean hasText = false; for (SliceItem item : sliceItems) { List textItems = SliceQuery.findAll(item, FORMAT_TEXT, hints, null /* non-hints */); if (textItems == null) { continue; } for (SliceItem textItem : textItems) { if (TextUtils.equals(textItem.getText(), text)) { hasText = true; break; } } } return hasText; } /** * Assert any slice item contains icon. * * @param sliceItems All slice items of a Slice. * @param icon Icon for asserting. */ public static void assertAnySliceItemContainsIcon(List sliceItems, IconCompat icon) { boolean hasIcon = false; for (SliceItem item : sliceItems) { List iconItems = SliceQuery.findAll(item, FORMAT_IMAGE, (String) null /* hints */, null /* non-hints */); if (iconItems == null) { continue; } for (SliceItem iconItem : iconItems) { if (icon.toString().equals(iconItem.getIcon().toString())) { hasIcon = true; break; } } } assertThat(hasIcon).isTrue(); } private static void assertKeywords(SliceMetadata metadata, SliceData data) { final List keywords = metadata.getSliceKeywords(); final Set expectedKeywords = Arrays.stream(data.getKeywords().split(",")) .map(s -> s = s.trim()) .collect(Collectors.toSet()); expectedKeywords.add(data.getTitle()); expectedKeywords.add(data.getScreenTitle().toString()); assertThat(keywords).containsExactlyElementsIn(expectedKeywords); } }