• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.car.carlauncher;
18 
19 import android.annotation.Nullable;
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.util.Log;
23 import android.view.LayoutInflater;
24 import android.view.View;
25 import android.view.ViewGroup;
26 
27 import androidx.recyclerview.widget.RecyclerView;
28 
29 import java.util.Collections;
30 import java.util.List;
31 
32 /**
33  * The adapter that populates the grid view with apps.
34  */
35 final class AppGridAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
36     public static final int RECENT_APPS_TYPE = 1;
37     public static final int APP_ITEM_TYPE = 2;
38     private static final long RECENT_APPS_ID = 0;
39     private static final String TAG = "AppGridAdapter";
40 
41     private final Context mContext;
42     private final int mColumnNumber;
43     private final LayoutInflater mInflater;
44 
45     private List<AppMetaData> mApps;
46     private List<AppMetaData> mMostRecentApps;
47     private boolean mIsDistractionOptimizationRequired;
48 
AppGridAdapter(Context context)49     AppGridAdapter(Context context) {
50         mContext = context;
51         mInflater = LayoutInflater.from(context);
52         mColumnNumber =
53                 mContext.getResources().getInteger(R.integer.car_app_selector_column_number);
54         // Stable IDs improve performance and make rotary work better.
55         setHasStableIds(true);
56     }
57 
setIsDistractionOptimizationRequired(boolean isDistractionOptimizationRequired)58     void setIsDistractionOptimizationRequired(boolean isDistractionOptimizationRequired) {
59         mIsDistractionOptimizationRequired = isDistractionOptimizationRequired;
60         sortAllApps();
61         notifyDataSetChanged();
62     }
63 
setMostRecentApps(@ullable List<AppMetaData> mostRecentApps)64     void setMostRecentApps(@Nullable List<AppMetaData> mostRecentApps) {
65         mMostRecentApps = mostRecentApps;
66         notifyDataSetChanged();
67     }
68 
69     @Override
getItemId(int position)70     public long getItemId(int position) {
71         if (position == 0 && hasRecentlyUsedApps()) {
72             return RECENT_APPS_ID;
73         }
74         if (mApps == null) {
75             Log.w(TAG, "apps list not set");
76             return RecyclerView.NO_ID;
77         }
78         int index = hasRecentlyUsedApps() ? position - 1 : position;
79         if (index < 0 || index >= mApps.size()) {
80             Log.w(TAG, "index out of range");
81             return RecyclerView.NO_ID;
82         }
83         ComponentName componentName = mApps.get(index).getComponentName();
84         long id = componentName.getPackageName().hashCode();
85         id <<= Integer.SIZE;
86         id |= componentName.getClassName().hashCode();
87         return id;
88     }
89 
setAllApps(@ullable List<AppMetaData> apps)90     void setAllApps(@Nullable List<AppMetaData> apps) {
91         mApps = apps;
92         sortAllApps();
93         notifyDataSetChanged();
94     }
95 
getSpanSizeLookup(int position)96     public int getSpanSizeLookup(int position) {
97         if (position == 0 && hasRecentlyUsedApps()) {
98             return mColumnNumber;
99         }
100         return 1;
101     }
102 
103     @Override
getItemViewType(int position)104     public int getItemViewType(int position) {
105         if (position == 0 && hasRecentlyUsedApps()) {
106             return RECENT_APPS_TYPE;
107         }
108         return APP_ITEM_TYPE;
109     }
110 
111     @Override
onCreateViewHolder(ViewGroup parent, int viewType)112     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
113         if (viewType == RECENT_APPS_TYPE) {
114             View view =
115                     mInflater.inflate(R.layout.recent_apps_row, parent, /* attachToRoot= */ false);
116             return new RecentAppsRowViewHolder(view, mContext);
117         } else {
118             View view = mInflater.inflate(R.layout.app_item, parent, /* attachToRoot= */ false);
119             return new AppItemViewHolder(view, mContext);
120         }
121     }
122 
123     @Override
onBindViewHolder(RecyclerView.ViewHolder holder, int position)124     public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
125         switch (holder.getItemViewType()) {
126             case RECENT_APPS_TYPE:
127                 ((RecentAppsRowViewHolder) holder).bind(
128                         mMostRecentApps, mIsDistractionOptimizationRequired);
129                 break;
130             case APP_ITEM_TYPE:
131                 int index = hasRecentlyUsedApps() ? position - 1 : position;
132                 AppMetaData app = mApps.get(index);
133                 ((AppItemViewHolder) holder).bind(app, mIsDistractionOptimizationRequired);
134                 break;
135             default:
136         }
137     }
138 
139     @Override
getItemCount()140     public int getItemCount() {
141         // If there are any most recently launched apps, add a "most recently used apps row item"
142         return (mApps == null ? 0 : mApps.size()) + (hasRecentlyUsedApps() ? 1 : 0);
143     }
144 
hasRecentlyUsedApps()145     private boolean hasRecentlyUsedApps() {
146         return mMostRecentApps != null && mMostRecentApps.size() > 0;
147     }
148 
sortAllApps()149     private void sortAllApps() {
150         if (mApps != null) {
151             Collections.sort(mApps, AppLauncherUtils.ALPHABETICAL_COMPARATOR);
152         }
153     }
154 }