1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.view.textclassifier; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertNotNull; 21import static org.junit.Assert.assertNull; 22 23import android.app.PendingIntent; 24import android.app.RemoteAction; 25import android.content.Context; 26import android.content.Intent; 27import android.graphics.Bitmap; 28import android.graphics.Color; 29import android.graphics.drawable.BitmapDrawable; 30import android.graphics.drawable.Drawable; 31import android.graphics.drawable.Icon; 32import android.os.LocaleList; 33import android.os.Parcel; 34import android.support.test.InstrumentationRegistry; 35import android.support.test.filters.SmallTest; 36import android.support.test.runner.AndroidJUnit4; 37import android.view.View; 38 39import org.junit.Test; 40import org.junit.runner.RunWith; 41 42import java.time.Instant; 43import java.time.ZoneId; 44import java.time.ZonedDateTime; 45import java.util.Locale; 46 47@SmallTest 48@RunWith(AndroidJUnit4.class) 49public class TextClassificationTest { 50 51 public Icon generateTestIcon(int width, int height, int colorValue) { 52 final int numPixels = width * height; 53 final int[] colors = new int[numPixels]; 54 for (int i = 0; i < numPixels; ++i) { 55 colors[i] = colorValue; 56 } 57 final Bitmap bitmap = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888); 58 return Icon.createWithBitmap(bitmap); 59 } 60 61 @Test 62 public void testParcel() { 63 final Context context = InstrumentationRegistry.getTargetContext(); 64 final String text = "text"; 65 66 final Icon primaryIcon = generateTestIcon(576, 288, Color.BLUE); 67 final String primaryLabel = "primaryLabel"; 68 final String primaryDescription = "primaryDescription"; 69 final Intent primaryIntent = new Intent("primaryIntentAction"); 70 final PendingIntent primaryPendingIntent = PendingIntent.getActivity(context, 0, 71 primaryIntent, 0); 72 final RemoteAction remoteAction0 = new RemoteAction(primaryIcon, primaryLabel, 73 primaryDescription, primaryPendingIntent); 74 75 final Icon secondaryIcon = generateTestIcon(32, 288, Color.GREEN); 76 final String secondaryLabel = "secondaryLabel"; 77 final String secondaryDescription = "secondaryDescription"; 78 final Intent secondaryIntent = new Intent("secondaryIntentAction"); 79 final PendingIntent secondaryPendingIntent = PendingIntent.getActivity(context, 0, 80 secondaryIntent, 0); 81 final RemoteAction remoteAction1 = new RemoteAction(secondaryIcon, secondaryLabel, 82 secondaryDescription, secondaryPendingIntent); 83 84 final String id = "id"; 85 final TextClassification reference = new TextClassification.Builder() 86 .setText(text) 87 .addAction(remoteAction0) 88 .addAction(remoteAction1) 89 .setEntityType(TextClassifier.TYPE_ADDRESS, 0.3f) 90 .setEntityType(TextClassifier.TYPE_PHONE, 0.7f) 91 .setId(id) 92 .build(); 93 94 // Parcel and unparcel 95 final Parcel parcel = Parcel.obtain(); 96 reference.writeToParcel(parcel, reference.describeContents()); 97 parcel.setDataPosition(0); 98 final TextClassification result = TextClassification.CREATOR.createFromParcel(parcel); 99 100 assertEquals(text, result.getText()); 101 assertEquals(id, result.getId()); 102 assertEquals(2, result.getActions().size()); 103 104 // Primary action. 105 final RemoteAction primaryAction = result.getActions().get(0); 106 assertEquals(primaryLabel, primaryAction.getTitle()); 107 assertEquals(primaryDescription, primaryAction.getContentDescription()); 108 assertEquals(primaryPendingIntent, primaryAction.getActionIntent()); 109 110 // Secondary action. 111 final RemoteAction secondaryAction = result.getActions().get(1); 112 assertEquals(secondaryLabel, secondaryAction.getTitle()); 113 assertEquals(secondaryDescription, secondaryAction.getContentDescription()); 114 assertEquals(secondaryPendingIntent, secondaryAction.getActionIntent()); 115 116 // Entities. 117 assertEquals(2, result.getEntityCount()); 118 assertEquals(TextClassifier.TYPE_PHONE, result.getEntity(0)); 119 assertEquals(TextClassifier.TYPE_ADDRESS, result.getEntity(1)); 120 assertEquals(0.7f, result.getConfidenceScore(TextClassifier.TYPE_PHONE), 1e-7f); 121 assertEquals(0.3f, result.getConfidenceScore(TextClassifier.TYPE_ADDRESS), 1e-7f); 122 } 123 124 @Test 125 public void testParcelLegacy() { 126 final Context context = InstrumentationRegistry.getInstrumentation().getContext(); 127 128 final int legacyIconWidth = 192; 129 final int legacyIconHeight = 96; 130 final int legacyIconColor = Color.BLUE; 131 final Drawable legacyIcon = generateTestIcon( 132 legacyIconWidth, legacyIconHeight, legacyIconColor) 133 .loadDrawable(context); 134 final String legacyLabel = "legacyLabel"; 135 final Intent legacyIntent = new Intent("ACTION_LEGACY"); 136 final View.OnClickListener legacyOnClick = null; 137 138 final int width = 384; 139 final int height = 192; 140 final int iconColor = Color.RED; 141 final String label = "label"; 142 final PendingIntent pendingIntent = PendingIntent.getActivity( 143 context, 0, new Intent("ACTION_0"), 0); 144 final RemoteAction remoteAction = new RemoteAction( 145 generateTestIcon(width, height, iconColor), 146 label, 147 "description", 148 pendingIntent); 149 150 final TextClassification reference = new TextClassification.Builder() 151 .setIcon(legacyIcon) 152 .setLabel(legacyLabel) 153 .setIntent(legacyIntent) 154 .setOnClickListener(legacyOnClick) 155 .addAction(remoteAction) 156 .build(); 157 158 // Parcel and unparcel 159 final Parcel parcel = Parcel.obtain(); 160 reference.writeToParcel(parcel, reference.describeContents()); 161 parcel.setDataPosition(0); 162 final TextClassification result = TextClassification.CREATOR.createFromParcel(parcel); 163 164 // Legacy fields excluding legacyIntent are replaced by first remoteAction. 165 assertNull(result.getIntent()); 166 final Bitmap resultIcon = ((BitmapDrawable) result.getIcon()).getBitmap(); 167 assertEquals(iconColor, resultIcon.getPixel(0, 0)); 168 assertEquals(width, resultIcon.getWidth()); 169 assertEquals(height, resultIcon.getHeight()); 170 assertEquals(label, result.getLabel()); 171 assertNotNull(result.getOnClickListener()); 172 } 173 174 @Test 175 public void testParcelParcel() { 176 final ZonedDateTime referenceTime = ZonedDateTime.ofInstant( 177 Instant.ofEpochMilli(946771200000L), // 2000-01-02 178 ZoneId.of("UTC")); 179 final String text = "text"; 180 181 final TextClassification.Request reference = 182 new TextClassification.Request.Builder(text, 0, text.length()) 183 .setDefaultLocales(new LocaleList(Locale.US, Locale.GERMANY)) 184 .setReferenceTime(referenceTime) 185 .build(); 186 187 // Parcel and unparcel. 188 final Parcel parcel = Parcel.obtain(); 189 reference.writeToParcel(parcel, reference.describeContents()); 190 parcel.setDataPosition(0); 191 final TextClassification.Request result = 192 TextClassification.Request.CREATOR.createFromParcel(parcel); 193 194 assertEquals(text, result.getText()); 195 assertEquals(0, result.getStartIndex()); 196 assertEquals(text.length(), result.getEndIndex()); 197 assertEquals(referenceTime, result.getReferenceTime()); 198 assertEquals("en-US,de-DE", result.getDefaultLocales().toLanguageTags()); 199 assertEquals(referenceTime, result.getReferenceTime()); 200 } 201} 202