| /* |
| * Copyright (C) 2019 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 android.view.textclassifier.intent; |
| |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.content.Intent; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.text.TextUtils; |
| import android.view.textclassifier.Log; |
| import android.view.textclassifier.TextClassifier; |
| |
| import com.android.internal.annotations.VisibleForTesting; |
| |
| import com.google.android.textclassifier.NamedVariant; |
| import com.google.android.textclassifier.RemoteActionTemplate; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Creates intents based on {@link RemoteActionTemplate} objects. |
| * |
| * @hide |
| */ |
| @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) |
| public final class TemplateIntentFactory { |
| private static final String TAG = TextClassifier.DEFAULT_LOG_TAG; |
| |
| /** |
| * Constructs and returns a list of {@link LabeledIntent} based on the given templates. |
| */ |
| @Nullable |
| public List<LabeledIntent> create( |
| @NonNull RemoteActionTemplate[] remoteActionTemplates) { |
| if (remoteActionTemplates.length == 0) { |
| return new ArrayList<>(); |
| } |
| final List<LabeledIntent> labeledIntents = new ArrayList<>(); |
| for (RemoteActionTemplate remoteActionTemplate : remoteActionTemplates) { |
| if (!isValidTemplate(remoteActionTemplate)) { |
| Log.w(TAG, "Invalid RemoteActionTemplate skipped."); |
| continue; |
| } |
| labeledIntents.add( |
| new LabeledIntent( |
| remoteActionTemplate.titleWithoutEntity, |
| remoteActionTemplate.titleWithEntity, |
| remoteActionTemplate.description, |
| remoteActionTemplate.descriptionWithAppName, |
| createIntent(remoteActionTemplate), |
| remoteActionTemplate.requestCode == null |
| ? LabeledIntent.DEFAULT_REQUEST_CODE |
| : remoteActionTemplate.requestCode)); |
| } |
| return labeledIntents; |
| } |
| |
| private static boolean isValidTemplate(@Nullable RemoteActionTemplate remoteActionTemplate) { |
| if (remoteActionTemplate == null) { |
| Log.w(TAG, "Invalid RemoteActionTemplate: is null"); |
| return false; |
| } |
| if (TextUtils.isEmpty(remoteActionTemplate.titleWithEntity) |
| && TextUtils.isEmpty(remoteActionTemplate.titleWithoutEntity)) { |
| Log.w(TAG, "Invalid RemoteActionTemplate: title is null"); |
| return false; |
| } |
| if (TextUtils.isEmpty(remoteActionTemplate.description)) { |
| Log.w(TAG, "Invalid RemoteActionTemplate: description is null"); |
| return false; |
| } |
| if (!TextUtils.isEmpty(remoteActionTemplate.packageName)) { |
| Log.w(TAG, "Invalid RemoteActionTemplate: package name is set"); |
| return false; |
| } |
| if (TextUtils.isEmpty(remoteActionTemplate.action)) { |
| Log.w(TAG, "Invalid RemoteActionTemplate: intent action not set"); |
| return false; |
| } |
| return true; |
| } |
| |
| private static Intent createIntent(RemoteActionTemplate remoteActionTemplate) { |
| final Intent intent = new Intent(remoteActionTemplate.action); |
| final Uri uri = TextUtils.isEmpty(remoteActionTemplate.data) |
| ? null : Uri.parse(remoteActionTemplate.data).normalizeScheme(); |
| final String type = TextUtils.isEmpty(remoteActionTemplate.type) |
| ? null : Intent.normalizeMimeType(remoteActionTemplate.type); |
| intent.setDataAndType(uri, type); |
| intent.setFlags(remoteActionTemplate.flags == null ? 0 : remoteActionTemplate.flags); |
| if (remoteActionTemplate.category != null) { |
| for (String category : remoteActionTemplate.category) { |
| if (category != null) { |
| intent.addCategory(category); |
| } |
| } |
| } |
| intent.putExtras(nameVariantsToBundle(remoteActionTemplate.extras)); |
| return intent; |
| } |
| |
| /** |
| * Converts an array of {@link NamedVariant} to a Bundle and returns it. |
| */ |
| public static Bundle nameVariantsToBundle(@Nullable NamedVariant[] namedVariants) { |
| if (namedVariants == null) { |
| return Bundle.EMPTY; |
| } |
| Bundle bundle = new Bundle(); |
| for (NamedVariant namedVariant : namedVariants) { |
| if (namedVariant == null) { |
| continue; |
| } |
| switch (namedVariant.getType()) { |
| case NamedVariant.TYPE_INT: |
| bundle.putInt(namedVariant.getName(), namedVariant.getInt()); |
| break; |
| case NamedVariant.TYPE_LONG: |
| bundle.putLong(namedVariant.getName(), namedVariant.getLong()); |
| break; |
| case NamedVariant.TYPE_FLOAT: |
| bundle.putFloat(namedVariant.getName(), namedVariant.getFloat()); |
| break; |
| case NamedVariant.TYPE_DOUBLE: |
| bundle.putDouble(namedVariant.getName(), namedVariant.getDouble()); |
| break; |
| case NamedVariant.TYPE_BOOL: |
| bundle.putBoolean(namedVariant.getName(), namedVariant.getBool()); |
| break; |
| case NamedVariant.TYPE_STRING: |
| bundle.putString(namedVariant.getName(), namedVariant.getString()); |
| break; |
| default: |
| Log.w(TAG, |
| "Unsupported type found in nameVariantsToBundle : " |
| + namedVariant.getType()); |
| } |
| } |
| return bundle; |
| } |
| } |