/* * Copyright (C) 2015 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.systemui.statusbar.phone; import static com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY; import android.annotation.NonNull; import android.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; public class StatusBarIconList { private ArrayList mSlots = new ArrayList<>(); public StatusBarIconList(String[] slots) { final int N = slots.length; for (int i=0; i < N; i++) { mSlots.add(new Slot(slots[i], null)); } } public int getSlotIndex(String slot) { final int N = mSlots.size(); for (int i=0; i getSlots() { return new ArrayList<>(mSlots); } protected Slot getSlot(String name) { return mSlots.get(getSlotIndex(name)); } public int size() { return mSlots.size(); } public void setIcon(int index, @NonNull StatusBarIconHolder holder) { mSlots.get(index).addHolder(holder); } public void removeIcon(int index, int tag) { mSlots.get(index).removeForTag(tag); } public String getSlotName(int index) { return mSlots.get(index).getName(); } public StatusBarIconHolder getIcon(int index, int tag) { return mSlots.get(index).getHolderForTag(tag); } public int getViewIndex(int slotIndex, int tag) { int count = 0; for (int i = 0; i < slotIndex; i++) { Slot item = mSlots.get(i); if (item.hasIconsInSlot()) { count += item.numberOfIcons(); } } Slot viewItem = mSlots.get(slotIndex); return count + viewItem.viewIndexOffsetForTag(tag); } public void dump(PrintWriter pw) { pw.println("StatusBarIconList state:"); final int N = mSlots.size(); pw.println(" icon slots: " + N); for (int i=0; i mSubSlots; public Slot(String name, StatusBarIconHolder iconHolder) { mName = name; mHolder = iconHolder; } public String getName() { return mName; } @Nullable public StatusBarIconHolder getHolderForTag(int tag) { if (tag == TAG_PRIMARY) { return mHolder; } if (mSubSlots != null) { for (StatusBarIconHolder holder : mSubSlots) { if (holder.getTag() == tag) { return holder; } } } return null; } public void addHolder(StatusBarIconHolder holder) { int tag = holder.getTag(); if (tag == TAG_PRIMARY) { mHolder = holder; } else { setSubSlot(holder, tag); } } public void removeForTag(int tag) { if (tag == TAG_PRIMARY) { mHolder = null; } else { int index = getIndexForTag(tag); if (index != -1) { mSubSlots.remove(index); } } } @VisibleForTesting public void clear() { mHolder = null; if (mSubSlots != null) { mSubSlots = null; } } private void setSubSlot(StatusBarIconHolder holder, int tag) { if (mSubSlots == null) { mSubSlots = new ArrayList<>(); mSubSlots.add(holder); return; } if (getIndexForTag(tag) != -1) { // Holder exists for tag; no-op return; } // These holders get added to the end. Confused yet? mSubSlots.add(holder); } private int getIndexForTag(int tag) { for (int i = 0; i < mSubSlots.size(); i++) { StatusBarIconHolder h = mSubSlots.get(i); if (h.getTag() == tag) { return i; } } return -1; } public boolean hasIconsInSlot() { if (mHolder != null) return true; if (mSubSlots == null) return false; return mSubSlots.size() > 0; } public int numberOfIcons() { int num = mHolder == null ? 0 : 1; if (mSubSlots == null) return num; return num + mSubSlots.size(); } /** * View index is inverted from regular index, because they are laid out back-to-front * @param tag the tag of the holder being viewed * @return (1 + mSubSlots.size() - indexOfTag) */ public int viewIndexOffsetForTag(int tag) { if (mSubSlots == null) { return 0; } int subSlots = mSubSlots.size(); if (tag == TAG_PRIMARY) { return subSlots; } return subSlots - getIndexForTag(tag) - 1; } /** * Build a list of the {@link StatusBarIconHolder}s in the same order they appear in their * view group. This provides a safe list that can be iterated and inserted into its group. * * @return all holders contained here, in view order */ public List getHolderListInViewOrder() { ArrayList holders = new ArrayList<>(); if (mSubSlots != null) { for (int i = mSubSlots.size() - 1; i >= 0; i--) { holders.add(mSubSlots.get(i)); } } if (mHolder != null) { holders.add(mHolder); } return holders; } /** * Build a list of the {@link StatusBarIconHolder}s in the same order. * This provides a safe list that can be iterated and inserted into its group. * * @return all holders contained here */ public List getHolderList() { ArrayList holders = new ArrayList<>(); if (mHolder != null) { holders.add(mHolder); } if (mSubSlots != null) { holders.addAll(mSubSlots); } return holders; } @Override public String toString() { return String.format("(%s) %s", mName, subSlotsString()); } private String subSlotsString() { if (mSubSlots == null) { return ""; } return "" + mSubSlots.size() + " subSlots"; } } }