1 /* 2 * Copyright (C) 2020 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 17 package com.example.android.inlinefillservice; 18 19 import static com.example.android.inlinefillservice.InlineFillService.TAG; 20 21 import android.content.Context; 22 import android.content.IntentSender; 23 import android.service.autofill.Dataset; 24 import android.service.autofill.InlinePresentation; 25 import android.util.Log; 26 import android.view.autofill.AutofillId; 27 import android.view.autofill.AutofillValue; 28 import android.view.inputmethod.InlineSuggestionsRequest; 29 import android.widget.RemoteViews; 30 31 import androidx.annotation.NonNull; 32 33 import java.util.Map; 34 import java.util.Optional; 35 36 class ResponseHelper { 37 newUnlockedDataset(@onNull Context context, @NonNull Map<String, AutofillId> fields, @NonNull String packageName, int index, @NonNull Optional<InlineSuggestionsRequest> inlineRequest)38 static Dataset newUnlockedDataset(@NonNull Context context, 39 @NonNull Map<String, AutofillId> fields, @NonNull String packageName, int index, 40 @NonNull Optional<InlineSuggestionsRequest> inlineRequest) { 41 42 Dataset.Builder dataset = new Dataset.Builder(); 43 for (Map.Entry<String, AutofillId> field : fields.entrySet()) { 44 final String hint = field.getKey(); 45 final AutofillId id = field.getValue(); 46 final String value = hint + (index + 1); 47 48 // We're simple - our dataset values are hardcoded as "hintN" (for example, 49 // "username1", "username2") and they're displayed as such, except if they're a 50 // password 51 Log.d(TAG, "hint: " + hint); 52 final String displayValue = hint.contains("password") ? "password for #" + (index + 1) 53 : value; 54 final RemoteViews presentation = newDatasetPresentation(packageName, displayValue); 55 56 // Add Inline Suggestion required info. 57 if (inlineRequest.isPresent()) { 58 Log.d(TAG, "Found InlineSuggestionsRequest in FillRequest: " + inlineRequest); 59 final InlinePresentation inlinePresentation = 60 InlineRequestHelper.createInlineDataset(context, inlineRequest.get(), 61 displayValue, index); 62 dataset.setValue(id, AutofillValue.forText(value), presentation, 63 inlinePresentation); 64 } else { 65 dataset.setValue(id, AutofillValue.forText(value), presentation); 66 } 67 } 68 69 return dataset.build(); 70 } 71 newLockedDataset(@onNull Context context, @NonNull Map<String, AutofillId> fields, @NonNull String packageName, int index, @NonNull Optional<InlineSuggestionsRequest> inlineRequest)72 static Dataset newLockedDataset(@NonNull Context context, 73 @NonNull Map<String, AutofillId> fields, @NonNull String packageName, int index, 74 @NonNull Optional<InlineSuggestionsRequest> inlineRequest) { 75 Dataset unlockedDataset = ResponseHelper.newUnlockedDataset(context, fields, 76 packageName, index, inlineRequest); 77 78 Dataset.Builder lockedDataset = new Dataset.Builder(); 79 for (Map.Entry<String, AutofillId> field : fields.entrySet()) { 80 String hint = field.getKey(); 81 AutofillId id = field.getValue(); 82 String value = (index + 1) + "-" + hint; 83 String displayValue = "Tap to auth " + value; 84 IntentSender authentication = 85 AuthActivity.newIntentSenderForDataset(context, unlockedDataset); 86 RemoteViews presentation = newDatasetPresentation(packageName, displayValue); 87 if (inlineRequest.isPresent()) { 88 final InlinePresentation inlinePresentation = 89 InlineRequestHelper.createInlineDataset(context, inlineRequest.get(), 90 displayValue, index); 91 lockedDataset.setValue(id, null, presentation, inlinePresentation) 92 .setAuthentication(authentication); 93 } else { 94 lockedDataset.setValue(id, null, presentation) 95 .setAuthentication(authentication); 96 } 97 } 98 return lockedDataset.build(); 99 } 100 101 /** 102 * Helper method to create a dataset presentation with the givean text. 103 */ 104 @NonNull newDatasetPresentation(@onNull String packageName, @NonNull CharSequence text)105 static RemoteViews newDatasetPresentation(@NonNull String packageName, 106 @NonNull CharSequence text) { 107 RemoteViews presentation = 108 new RemoteViews(packageName, R.layout.list_item); 109 presentation.setTextViewText(R.id.text, text); 110 return presentation; 111 } 112 } 113