summaryrefslogtreecommitdiff
path: root/java/com/android/incallui/incall/impl/MappedButtonConfig.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/incallui/incall/impl/MappedButtonConfig.java')
-rw-r--r--java/com/android/incallui/incall/impl/MappedButtonConfig.java193
1 files changed, 193 insertions, 0 deletions
diff --git a/java/com/android/incallui/incall/impl/MappedButtonConfig.java b/java/com/android/incallui/incall/impl/MappedButtonConfig.java
new file mode 100644
index 000000000..722983796
--- /dev/null
+++ b/java/com/android/incallui/incall/impl/MappedButtonConfig.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2016 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.incallui.incall.impl;
+
+import android.support.annotation.NonNull;
+import android.support.v4.util.ArrayMap;
+import android.util.ArraySet;
+import com.android.dialer.common.Assert;
+import com.android.incallui.incall.protocol.InCallButtonIds;
+import com.android.incallui.incall.protocol.InCallButtonIdsExtension;
+import com.google.auto.value.AutoValue;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Determines logical button slot and ordering based on a provided mapping.
+ *
+ * <p>The provided mapping is declared with the following pieces of information: key, the {@link
+ * InCallButtonIds} for which the mapping applies; {@link MappingInfo#getSlot()}, the arbitrarily
+ * indexed slot into which the InCallButtonId desires to be placed; {@link
+ * MappingInfo#getSlotOrder()}, the slotOrder, used to choose the correct InCallButtonId when
+ * multiple desire to be placed in the same slot; and {@link MappingInfo#getConflictOrder()}, the
+ * conflictOrder, used to determine the overall order for InCallButtonIds that weren't chosen for
+ * their desired slot.
+ */
+@Immutable
+final class MappedButtonConfig {
+
+ @NonNull private final Map<Integer, MappingInfo> mapping;
+ @NonNull private final List<Integer> orderedMappedSlots;
+
+ /**
+ * Creates this MappedButtonConfig with the given mapping of {@link InCallButtonIds} to their
+ * corresponding slots and order.
+ *
+ * @param mapping the mapping.
+ */
+ public MappedButtonConfig(@NonNull Map<Integer, MappingInfo> mapping) {
+ this.mapping = new ArrayMap<>();
+ this.mapping.putAll(Assert.isNotNull(mapping));
+ this.orderedMappedSlots = findOrderedMappedSlots();
+ }
+
+ private List<Integer> findOrderedMappedSlots() {
+ Set<Integer> slots = new ArraySet<>();
+ for (Entry<Integer, MappingInfo> entry : mapping.entrySet()) {
+ slots.add(entry.getValue().getSlot());
+ }
+ List<Integer> orderedSlots = new ArrayList<>(slots);
+ Collections.sort(orderedSlots);
+ return orderedSlots;
+ }
+
+ /** Returns an immutable list of the slots for which this class has button mapping. */
+ @NonNull
+ public List<Integer> getOrderedMappedSlots() {
+ if (mapping.isEmpty()) {
+ return Collections.emptyList();
+ }
+ return Collections.unmodifiableList(orderedMappedSlots);
+ }
+
+ /**
+ * Returns a list of {@link InCallButtonIds} that are configured to be placed in the given ui
+ * slot. The slot can be based from any index, as long as it matches the provided mapping.
+ */
+ @NonNull
+ public List<Integer> getButtonsForSlot(int slot) {
+ List<Integer> buttons = new ArrayList<>();
+ for (Entry<Integer, MappingInfo> entry : mapping.entrySet()) {
+ if (entry.getValue().getSlot() == slot) {
+ buttons.add(entry.getKey());
+ }
+ }
+ return buttons;
+ }
+
+ /**
+ * Returns a {@link Comparator} capable of ordering {@link InCallButtonIds} that are configured to
+ * be placed in the same slot. InCallButtonIds are sorted based on the natural ordering of {@link
+ * MappingInfo#getSlotOrder()}.
+ *
+ * <p>Note: the returned Comparator's compare method will throw an {@link
+ * IllegalArgumentException} if called with InCallButtonIds that have no configuration or are not
+ * to be placed in the same slot.
+ */
+ @NonNull
+ public Comparator<Integer> getSlotComparator() {
+ return new Comparator<Integer>() {
+ @Override
+ public int compare(Integer lhs, Integer rhs) {
+ MappingInfo lhsInfo = lookupMappingInfo(lhs);
+ MappingInfo rhsInfo = lookupMappingInfo(rhs);
+ if (lhsInfo.getSlot() != rhsInfo.getSlot()) {
+ throw new IllegalArgumentException("lhs and rhs don't go in the same slot");
+ }
+ return lhsInfo.getSlotOrder() - rhsInfo.getSlotOrder();
+ }
+ };
+ }
+
+ /**
+ * Returns a {@link Comparator} capable of ordering {@link InCallButtonIds} by their conflict
+ * score. This comparator should be used when multiple InCallButtonIds could have been shown in
+ * the same slot. InCallButtonIds are sorted based on the natural ordering of {@link
+ * MappingInfo#getConflictOrder()}.
+ *
+ * <p>Note: the returned Comparator's compare method will throw an {@link
+ * IllegalArgumentException} if called with InCallButtonIds that have no configuration.
+ */
+ @NonNull
+ public Comparator<Integer> getConflictComparator() {
+ return new Comparator<Integer>() {
+ @Override
+ public int compare(Integer lhs, Integer rhs) {
+ MappingInfo lhsInfo = lookupMappingInfo(lhs);
+ MappingInfo rhsInfo = lookupMappingInfo(rhs);
+ return lhsInfo.getConflictOrder() - rhsInfo.getConflictOrder();
+ }
+ };
+ }
+
+ @NonNull
+ private MappingInfo lookupMappingInfo(@InCallButtonIds int button) {
+ MappingInfo info = mapping.get(button);
+ if (info == null) {
+ throw new IllegalArgumentException(
+ "Unknown InCallButtonId: " + InCallButtonIdsExtension.toString(button));
+ }
+ return info;
+ }
+
+ /** Holds information about button mapping. */
+ @AutoValue
+ abstract static class MappingInfo {
+
+ /** The Ui slot into which a given button desires to be placed. */
+ public abstract int getSlot();
+
+ /**
+ * Returns an integer used to determine which button is chosen for a slot when multiple buttons
+ * desire to be placed in the same slot. Follows from the natural ordering of integers, i.e. a
+ * lower slotOrder results in the button being chosen.
+ */
+ public abstract int getSlotOrder();
+
+ /**
+ * Returns an integer used to determine the order in which buttons that weren't chosen for their
+ * desired slot are placed into the Ui. Follows from the natural ordering of integers, i.e. a
+ * lower conflictOrder results in the button being chosen.
+ */
+ public abstract int getConflictOrder();
+
+ static Builder builder(int slot) {
+ return new AutoValue_MappedButtonConfig_MappingInfo.Builder()
+ .setSlot(slot)
+ .setSlotOrder(Integer.MAX_VALUE)
+ .setConflictOrder(Integer.MAX_VALUE);
+ }
+
+ /** Class used to build instances of {@link MappingInfo}. */
+ @AutoValue.Builder
+ abstract static class Builder {
+ public abstract Builder setSlot(int slot);
+
+ public abstract Builder setSlotOrder(int slotOrder);
+
+ public abstract Builder setConflictOrder(int conflictOrder);
+
+ public abstract MappingInfo build();
+ }
+ }
+}