• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.android.incallui.incall.impl;
18 
19 import android.support.annotation.NonNull;
20 import com.android.dialer.common.Assert;
21 import com.android.incallui.incall.protocol.InCallButtonIds;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Set;
26 import javax.annotation.concurrent.Immutable;
27 
28 /**
29  * Determines where logical buttons should be placed in the {@link InCallFragment} based on the
30  * provided mapping.
31  *
32  * <p>The button placement returned by a call to {@link #getButtonPlacement(int, Set)} is created as
33  * follows: one button is placed at each UI slot, using the provided mapping to resolve conflicts.
34  * Any allowed buttons that were not chosen for their desired slot are filled in at the end of the
35  * list until it becomes the proper size.
36  */
37 @Immutable
38 final class ButtonChooser {
39 
40   private final MappedButtonConfig config;
41 
ButtonChooser(@onNull MappedButtonConfig config)42   public ButtonChooser(@NonNull MappedButtonConfig config) {
43     this.config = Assert.isNotNull(config);
44   }
45 
46   /**
47    * Returns the buttons that should be shown in the {@link InCallFragment}, ordered appropriately.
48    *
49    * @param numUiButtons the number of ui buttons available.
50    * @param allowedButtons the {@link InCallButtonIds} that can be shown.
51    * @param disabledButtons the {@link InCallButtonIds} that can be shown but in disabled stats.
52    * @return an immutable list whose size is at most {@code numUiButtons}, containing the buttons to
53    *     show.
54    */
55   @NonNull
getButtonPlacement( int numUiButtons, @NonNull Set<Integer> allowedButtons, @NonNull Set<Integer> disabledButtons)56   public List<Integer> getButtonPlacement(
57       int numUiButtons,
58       @NonNull Set<Integer> allowedButtons,
59       @NonNull Set<Integer> disabledButtons) {
60     Assert.isNotNull(allowedButtons);
61     Assert.checkArgument(numUiButtons >= 0);
62 
63     if (numUiButtons == 0 || allowedButtons.isEmpty()) {
64       return Collections.emptyList();
65     }
66 
67     List<Integer> placedButtons = new ArrayList<>();
68     List<Integer> conflicts = new ArrayList<>();
69     placeButtonsInSlots(numUiButtons, allowedButtons, placedButtons, conflicts);
70     placeConflictsInOpenSlots(
71         numUiButtons, allowedButtons, disabledButtons, placedButtons, conflicts);
72     return Collections.unmodifiableList(placedButtons);
73   }
74 
placeButtonsInSlots( int numUiButtons, @NonNull Set<Integer> allowedButtons, @NonNull List<Integer> placedButtons, @NonNull List<Integer> conflicts)75   private void placeButtonsInSlots(
76       int numUiButtons,
77       @NonNull Set<Integer> allowedButtons,
78       @NonNull List<Integer> placedButtons,
79       @NonNull List<Integer> conflicts) {
80     List<Integer> configuredSlots = config.getOrderedMappedSlots();
81     for (int i = 0; i < configuredSlots.size() && placedButtons.size() < numUiButtons; ++i) {
82       int slotNumber = configuredSlots.get(i);
83       List<Integer> potentialButtons = config.getButtonsForSlot(slotNumber);
84       Collections.sort(potentialButtons, config.getSlotComparator());
85       for (int j = 0; j < potentialButtons.size(); ++j) {
86         if (allowedButtons.contains(potentialButtons.get(j))) {
87           placedButtons.add(potentialButtons.get(j));
88           conflicts.addAll(potentialButtons.subList(j + 1, potentialButtons.size()));
89           break;
90         }
91       }
92     }
93   }
94 
placeConflictsInOpenSlots( int numUiButtons, @NonNull Set<Integer> allowedButtons, @NonNull Set<Integer> disabledButtons, @NonNull List<Integer> placedButtons, @NonNull List<Integer> conflicts)95   private void placeConflictsInOpenSlots(
96       int numUiButtons,
97       @NonNull Set<Integer> allowedButtons,
98       @NonNull Set<Integer> disabledButtons,
99       @NonNull List<Integer> placedButtons,
100       @NonNull List<Integer> conflicts) {
101     Collections.sort(conflicts, config.getConflictComparator());
102     for (Integer conflict : conflicts) {
103       if (placedButtons.size() >= numUiButtons) {
104         return;
105       }
106       // If the conflict button is allowed but disabled, don't place it since it probably will
107       // move when it's enabled.
108       if (!allowedButtons.contains(conflict) || disabledButtons.contains(conflict)) {
109         continue;
110       }
111       placedButtons.add(conflict);
112     }
113   }
114 }
115