/*
* Copyright 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 androidx.textclassifier;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.collection.ArrayMap;
import androidx.core.app.RemoteActionCompat;
import androidx.core.os.LocaleListCompat;
import androidx.versionedparcelable.ParcelUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Utilities for (un)marshalling with Bundle.
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY)
/* package */ final class BundleUtils {
private BundleUtils() {}
/** Compat wrapper for deepCopy. */
static Bundle deepCopy(Bundle bundle) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return bundle.deepCopy();
} else {
// TODO: actually perform a deep copy.
return (Bundle) bundle.clone();
}
}
/** Serializes a string keyed map to a bundle, or clears it if null is passed. */
static void putMap(
@NonNull Bundle bundle, @NonNull String key, @Nullable Map<String, Float> map) {
if (map == null) {
bundle.remove(key);
return;
}
final Bundle mapBundle = new Bundle();
for (Map.Entry<String, Float> entry : map.entrySet()) {
mapBundle.putFloat(entry.getKey(), entry.getValue());
}
bundle.putBundle(key, mapBundle);
}
/** @throws IllegalArgumentException if key can't be found in the bundle */
static Map<String, Float> getFloatStringMapOrThrow(
@NonNull Bundle bundle, @NonNull String key) {
final Bundle mapBundle = bundle.getBundle(key);
if (mapBundle == null) {
throw new IllegalArgumentException("Missing " + key);
}
final Map<String, Float> map = new ArrayMap<>(mapBundle.size());
for (String mapKey : mapBundle.keySet()) {
map.put(mapKey, mapBundle.getFloat(mapKey));
}
return map;
}
/** Serializes a list of actions to a bundle, or clears it if null is passed. */
static void putRemoteActionList(
@NonNull Bundle bundle, @NonNull String key,
@NonNull List<RemoteActionCompat> actions) {
ParcelUtils.putVersionedParcelableList(bundle, key, actions);
}
static List<RemoteActionCompat> getRemoteActionListOrThrow(
@NonNull Bundle bundle, @NonNull String key) {
return ParcelUtils.getVersionedParcelableList(bundle, key);
}
/** Serializes a list of TextLinks to a bundle, or clears it if null is passed. */
static void putTextLinkList(
@NonNull Bundle bundle, @NonNull String key, @Nullable List<TextLinks.TextLink> links) {
if (links == null) {
bundle.remove(key);
return;
}
final ArrayList<Bundle> linkBundles = new ArrayList<>(links.size());
for (TextLinks.TextLink link : links) {
linkBundles.add(link.toBundle());
}
bundle.putParcelableArrayList(key, linkBundles);
}
/** @throws IllegalArgumentException if key can't be found in the bundle */
@SuppressWarnings("deprecation")
static List<TextLinks.TextLink> getTextLinkListOrThrow(
@NonNull Bundle bundle, @NonNull String key) {
final List<Bundle> linkBundles = bundle.getParcelableArrayList(key);
if (linkBundles == null) {
throw new IllegalArgumentException("Missing " + key);
}
final List<TextLinks.TextLink> links = new ArrayList<>(linkBundles.size());
for (Bundle linkBundle : linkBundles) {
links.add(TextLinks.TextLink.createFromBundle(linkBundle));
}
return links;
}
/** Serializes a locale list to a bundle, or clears it if null is passed. */
static void putLocaleList(
@NonNull Bundle bundle, @NonNull String key, @Nullable LocaleListCompat localeList) {
if (localeList == null) {
bundle.remove(key);
return;
}
bundle.putString(key, localeList.toLanguageTags());
}
static @Nullable LocaleListCompat getLocaleList(@NonNull Bundle bundle, @NonNull String key) {
final String localeTags = bundle.getString(key);
if (localeTags == null) {
return null;
}
return LocaleListCompat.forLanguageTags(localeTags);
}
static void putLong(@NonNull Bundle bundle, @NonNull String key, @Nullable Long value) {
if (value == null) {
bundle.remove(key);
return;
}
bundle.putLong(key, value);
}
@Nullable
static Long getLong(@NonNull Bundle bundle, @NonNull String key) {
if (!bundle.containsKey(key)) {
return null;
}
return bundle.getLong(key);
}
static void putConversationActionsList(
@NonNull Bundle container, @NonNull String key,
@NonNull List<ConversationAction> actions) {
ArrayList<Bundle> bundles = new ArrayList<>(actions.size());
for (ConversationAction action : actions) {
bundles.add(action.toBundle());
}
container.putParcelableArrayList(key, bundles);
}
@NonNull
@SuppressWarnings("deprecation")
static List<ConversationAction> getConversationActionsList(
@NonNull Bundle container, @NonNull String key) {
ArrayList<Bundle> bundles = container.getParcelableArrayList(key);
ArrayList<ConversationAction> conversationActions = new ArrayList<>(bundles.size());
for (Bundle bundle : bundles) {
ConversationAction conversationAction = ConversationAction.createFromBundle(bundle);
conversationActions.add(conversationAction);
}
return conversationActions;
}
static void putConversationActionsMessageList(
@NonNull Bundle container, @NonNull String key,
@NonNull List<ConversationActions.Message> messages) {
ArrayList<Bundle> bundles = new ArrayList<>(messages.size());
for (ConversationActions.Message message : messages) {
bundles.add(message.toBundle());
}
container.putParcelableArrayList(key, bundles);
}
@NonNull
@SuppressWarnings("deprecation")
static List<ConversationActions.Message> getConversationActionsMessageList(
@NonNull Bundle container, @NonNull String key) {
ArrayList<Bundle> bundles = container.getParcelableArrayList(key);
ArrayList<ConversationActions.Message> messages = new ArrayList<>(bundles.size());
for (Bundle bundle : bundles) {
ConversationActions.Message message =
ConversationActions.Message.createFromBundle(bundle);
messages.add(message);
}
return messages;
}
}