1 /*
2  * Copyright (C) 2018 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.documentsui.dirlist;
18 
19 import android.os.UserManager;
20 import android.text.TextUtils;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.widget.ImageView;
24 import android.widget.LinearLayout;
25 import android.widget.TextView;
26 
27 import com.android.documentsui.ActionHandler;
28 import com.android.documentsui.BaseActivity;
29 import com.android.documentsui.R;
30 import com.android.documentsui.UserIdManager;
31 import com.android.documentsui.base.State;
32 import com.android.documentsui.base.UserId;
33 import com.android.documentsui.dirlist.AppsRowItemData.AppData;
34 import com.android.documentsui.dirlist.AppsRowItemData.RootData;
35 import com.android.documentsui.sidebar.AppItem;
36 import com.android.documentsui.sidebar.Item;
37 import com.android.documentsui.sidebar.RootItem;
38 
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 
44 /**
45  * A manager class stored apps row chip data list. Data will be synced by RootsFragment.
46  */
47 public class AppsRowManager {
48 
49     private final ActionHandler mActionHandler;
50     private final List<AppsRowItemData> mDataList;
51     private final boolean mMaybeShowBadge;
52     private final UserIdManager mUserIdManager;
53 
AppsRowManager(ActionHandler handler, boolean maybeShowBadge, UserIdManager userIdManager)54     public AppsRowManager(ActionHandler handler, boolean maybeShowBadge,
55             UserIdManager userIdManager) {
56         mDataList = new ArrayList<>();
57         mActionHandler = handler;
58         mMaybeShowBadge = maybeShowBadge;
59         mUserIdManager = userIdManager;
60     }
61 
updateList(List<Item> itemList)62     public List<AppsRowItemData> updateList(List<Item> itemList) {
63         mDataList.clear();
64 
65         // If more than 1 item of the same package, show item summary (e.g. account id).
66         Map<String, Integer> packageNameCount = new HashMap<>();
67         for (Item item : itemList) {
68             String packageName = item.getPackageName();
69             int previousCount = packageNameCount.containsKey(packageName)
70                     && !TextUtils.isEmpty(packageName)
71                     ? packageNameCount.get(packageName) : 0;
72             packageNameCount.put(packageName, previousCount + 1);
73         }
74 
75         for (Item item : itemList) {
76             boolean shouldShowSummary = packageNameCount.get(item.getPackageName()) > 1;
77             if (item instanceof RootItem) {
78                 mDataList.add(new RootData((RootItem) item, mActionHandler, shouldShowSummary,
79                         mMaybeShowBadge));
80             } else {
81                 mDataList.add(new AppData((AppItem) item, mActionHandler, shouldShowSummary,
82                         mMaybeShowBadge));
83             }
84         }
85         return mDataList;
86     }
87 
shouldShow(State state, boolean isSearchExpanded)88     private boolean shouldShow(State state, boolean isSearchExpanded) {
89         boolean isHiddenAction = state.action == State.ACTION_CREATE
90                 || state.action == State.ACTION_OPEN_TREE
91                 || state.action == State.ACTION_PICK_COPY_DESTINATION;
92         boolean isSearchExpandedAcrossProfile = mUserIdManager.getUserIds().size() > 1
93                 && state.supportsCrossProfile()
94                 && isSearchExpanded;
95 
96         return state.stack.isRecents() && !isHiddenAction && mDataList.size() > 0
97                 && !isSearchExpandedAcrossProfile;
98     }
99 
updateView(BaseActivity activity)100     public void updateView(BaseActivity activity) {
101         final View appsRowLayout = activity.findViewById(R.id.apps_row);
102 
103         if (!shouldShow(activity.getDisplayState(), activity.isSearchExpanded())) {
104             appsRowLayout.setVisibility(View.GONE);
105             return;
106         }
107 
108         final LinearLayout appsGroup = activity.findViewById(R.id.apps_group);
109         appsGroup.removeAllViews();
110 
111         final LayoutInflater inflater = activity.getLayoutInflater();
112         final UserId selectedUser = activity.getSelectedUser();
113         for (AppsRowItemData data : mDataList) {
114             if (selectedUser.equals(data.getUserId())) {
115                 View item = inflater.inflate(R.layout.apps_item, appsGroup, false);
116                 bindView(item, data);
117                 appsGroup.addView(item);
118             }
119         }
120 
121         appsRowLayout.setVisibility(appsGroup.getChildCount() > 0 ? View.VISIBLE : View.GONE);
122     }
123 
bindView(View view, AppsRowItemData data)124     private void bindView(View view, AppsRowItemData data) {
125         final ImageView app_icon = view.findViewById(R.id.app_icon);
126         final TextView title = view.findViewById(android.R.id.title);
127         final TextView summary = view.findViewById(R.id.summary);
128 
129         app_icon.setImageDrawable(data.getIconDrawable(view.getContext()));
130         title.setText(data.getTitle());
131         title.setContentDescription(
132                 data.getUserId().getUserBadgedLabel(view.getContext(), data.getTitle()));
133         summary.setText(data.getSummary());
134         summary.setVisibility(data.getSummary() != null ? View.VISIBLE : View.GONE);
135         view.setOnClickListener(v -> data.onClicked());
136     }
137 }
138