15f1f885f598baaf48f31bc7fce953975285e8b42jovanak/* 25f1f885f598baaf48f31bc7fce953975285e8b42jovanak * Copyright (C) 2018 The Android Open Source Project 35f1f885f598baaf48f31bc7fce953975285e8b42jovanak * 45f1f885f598baaf48f31bc7fce953975285e8b42jovanak * Licensed under the Apache License, Version 2.0 (the "License"); 55f1f885f598baaf48f31bc7fce953975285e8b42jovanak * you may not use this file except in compliance with the License. 65f1f885f598baaf48f31bc7fce953975285e8b42jovanak * You may obtain a copy of the License at 75f1f885f598baaf48f31bc7fce953975285e8b42jovanak * 85f1f885f598baaf48f31bc7fce953975285e8b42jovanak * http://www.apache.org/licenses/LICENSE-2.0 95f1f885f598baaf48f31bc7fce953975285e8b42jovanak * 105f1f885f598baaf48f31bc7fce953975285e8b42jovanak * Unless required by applicable law or agreed to in writing, software 115f1f885f598baaf48f31bc7fce953975285e8b42jovanak * distributed under the License is distributed on an "AS IS" BASIS, 125f1f885f598baaf48f31bc7fce953975285e8b42jovanak * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f1f885f598baaf48f31bc7fce953975285e8b42jovanak * See the License for the specific language governing permissions and 148179594f875d7b99c37f53381219497375da8abdjovanak * limitations under the License. 155f1f885f598baaf48f31bc7fce953975285e8b42jovanak */ 165f1f885f598baaf48f31bc7fce953975285e8b42jovanak 175f1f885f598baaf48f31bc7fce953975285e8b42jovanakpackage com.android.car.settings.accounts; 185f1f885f598baaf48f31bc7fce953975285e8b42jovanak 195f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport android.accounts.Account; 208c1ce5e5256d0ea4806dc83117ebf5fe368286caYing Zhengimport android.car.user.CarUserManagerHelper; 215f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport android.content.Context; 225f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport android.content.pm.UserInfo; 23a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanakimport android.support.annotation.VisibleForTesting; 2437088fbc6831218f53c5a825274a2beb87db8ba0jovanakimport android.text.TextUtils; 255f1f885f598baaf48f31bc7fce953975285e8b42jovanak 262cdde282dc639f86d21dc64b50a5e382fae38313jovanakimport androidx.car.widget.ListItem; 272cdde282dc639f86d21dc64b50a5e382fae38313jovanakimport androidx.car.widget.ListItemProvider; 282cdde282dc639f86d21dc64b50a5e382fae38313jovanakimport androidx.car.widget.TextListItem; 292cdde282dc639f86d21dc64b50a5e382fae38313jovanak 305f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport com.android.car.settings.R; 315f1f885f598baaf48f31bc7fce953975285e8b42jovanak 325f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport java.util.ArrayList; 33a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanakimport java.util.Collections; 34a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanakimport java.util.Comparator; 355f1f885f598baaf48f31bc7fce953975285e8b42jovanakimport java.util.List; 365f1f885f598baaf48f31bc7fce953975285e8b42jovanak 375f1f885f598baaf48f31bc7fce953975285e8b42jovanak/** 388179594f875d7b99c37f53381219497375da8abdjovanak * Implementation of {@link ListItemProvider} for {@link AccountsListFragment}. 398179594f875d7b99c37f53381219497375da8abdjovanak * Creates items that represent current user's accounts. 405f1f885f598baaf48f31bc7fce953975285e8b42jovanak */ 418179594f875d7b99c37f53381219497375da8abdjovanakclass AccountsItemProvider extends ListItemProvider { 425f1f885f598baaf48f31bc7fce953975285e8b42jovanak private final List<ListItem> mItems = new ArrayList<>(); 435f1f885f598baaf48f31bc7fce953975285e8b42jovanak private final Context mContext; 448179594f875d7b99c37f53381219497375da8abdjovanak private final AccountClickListener mItemClickListener; 458c1ce5e5256d0ea4806dc83117ebf5fe368286caYing Zheng private final CarUserManagerHelper mCarUserManagerHelper; 465f1f885f598baaf48f31bc7fce953975285e8b42jovanak private final AccountManagerHelper mAccountManagerHelper; 475f1f885f598baaf48f31bc7fce953975285e8b42jovanak 488179594f875d7b99c37f53381219497375da8abdjovanak AccountsItemProvider(Context context, AccountClickListener itemClickListener, 493e6b5001ea887b56c1de5c51195d84cffc83708cjovanak CarUserManagerHelper carUserManagerHelper, AccountManagerHelper accountManagerHelper) { 505f1f885f598baaf48f31bc7fce953975285e8b42jovanak mContext = context; 515f1f885f598baaf48f31bc7fce953975285e8b42jovanak mItemClickListener = itemClickListener; 528c1ce5e5256d0ea4806dc83117ebf5fe368286caYing Zheng mCarUserManagerHelper = carUserManagerHelper; 535f1f885f598baaf48f31bc7fce953975285e8b42jovanak mAccountManagerHelper = accountManagerHelper; 545f1f885f598baaf48f31bc7fce953975285e8b42jovanak refreshItems(); 555f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 565f1f885f598baaf48f31bc7fce953975285e8b42jovanak 575f1f885f598baaf48f31bc7fce953975285e8b42jovanak @Override 585f1f885f598baaf48f31bc7fce953975285e8b42jovanak public ListItem get(int position) { 595f1f885f598baaf48f31bc7fce953975285e8b42jovanak return mItems.get(position); 605f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 615f1f885f598baaf48f31bc7fce953975285e8b42jovanak 625f1f885f598baaf48f31bc7fce953975285e8b42jovanak @Override 635f1f885f598baaf48f31bc7fce953975285e8b42jovanak public int size() { 645f1f885f598baaf48f31bc7fce953975285e8b42jovanak return mItems.size(); 655f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 665f1f885f598baaf48f31bc7fce953975285e8b42jovanak 675f1f885f598baaf48f31bc7fce953975285e8b42jovanak /** 685f1f885f598baaf48f31bc7fce953975285e8b42jovanak * Clears and recreates the list of items. 695f1f885f598baaf48f31bc7fce953975285e8b42jovanak */ 705f1f885f598baaf48f31bc7fce953975285e8b42jovanak public void refreshItems() { 715f1f885f598baaf48f31bc7fce953975285e8b42jovanak mItems.clear(); 725f1f885f598baaf48f31bc7fce953975285e8b42jovanak 738c1ce5e5256d0ea4806dc83117ebf5fe368286caYing Zheng UserInfo currUserInfo = mCarUserManagerHelper.getCurrentProcessUserInfo(); 745f1f885f598baaf48f31bc7fce953975285e8b42jovanak 75a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak List<Account> accounts = getSortedUserAccounts(); 765f1f885f598baaf48f31bc7fce953975285e8b42jovanak 7780c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal // Only add account-related items if the User can Modify Accounts 788c1ce5e5256d0ea4806dc83117ebf5fe368286caYing Zheng if (mCarUserManagerHelper.canCurrentProcessModifyAccounts()) { 7980c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal // Add "Account for $User" title for a list of accounts. 8080c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal mItems.add(createSubtitleItem( 818179594f875d7b99c37f53381219497375da8abdjovanak mContext.getString(R.string.account_list_title, currUserInfo.name), 828179594f875d7b99c37f53381219497375da8abdjovanak accounts.isEmpty() ? mContext.getString(R.string.no_accounts_added) : "")); 835f1f885f598baaf48f31bc7fce953975285e8b42jovanak 8480c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal // Add an item for each account owned by the current user (1st and 3rd party accounts) 8580c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal for (Account account : accounts) { 8680c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal mItems.add(createAccountItem(account, account.type, currUserInfo)); 8780c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal } 885f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 895f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 905f1f885f598baaf48f31bc7fce953975285e8b42jovanak 91a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) 92a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak List<Account> getSortedUserAccounts() { 93a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak List<Account> accounts = mAccountManagerHelper.getAccountsForCurrentUser(); 94a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak 95a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak // Sort accounts 96a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak Collections.sort(accounts, Comparator.comparing( 97a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak (Account a) -> mAccountManagerHelper.getLabelForType(a.type).toString()) 98a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak .thenComparing(a -> a.name)); 99a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak 100a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak return accounts; 101a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak } 102a3d1a73e231b8cecbc54b3f77eef41d8d52e1bb7jovanak 1035f1f885f598baaf48f31bc7fce953975285e8b42jovanak // Creates a subtitle line for visual separation in the list 1048179594f875d7b99c37f53381219497375da8abdjovanak private ListItem createSubtitleItem(String title, String body) { 1055f1f885f598baaf48f31bc7fce953975285e8b42jovanak TextListItem item = new TextListItem(mContext); 1065f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.setTitle(title); 1078179594f875d7b99c37f53381219497375da8abdjovanak item.setBody(body); 1085f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.addViewBinder(viewHolder -> 1095f1f885f598baaf48f31bc7fce953975285e8b42jovanak viewHolder.getTitle().setTextAppearance(R.style.SettingsListHeader)); 1105f1f885f598baaf48f31bc7fce953975285e8b42jovanak // Hiding the divider after subtitle, since subtitle is a header for a group of items. 1115f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.setHideDivider(true); 1125f1f885f598baaf48f31bc7fce953975285e8b42jovanak return item; 1135f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 1145f1f885f598baaf48f31bc7fce953975285e8b42jovanak 1155f1f885f598baaf48f31bc7fce953975285e8b42jovanak // Creates a line for an account that belongs to a given user 1165f1f885f598baaf48f31bc7fce953975285e8b42jovanak private ListItem createAccountItem(Account account, String accountType, 1175f1f885f598baaf48f31bc7fce953975285e8b42jovanak UserInfo userInfo) { 1185f1f885f598baaf48f31bc7fce953975285e8b42jovanak TextListItem item = new TextListItem(mContext); 1195f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.setPrimaryActionIcon(mAccountManagerHelper.getDrawableForType(accountType), 1205076ef3bb9acfb82baea650fa00dc8187532edc0Rodrigo Lagos /* useLargeIcon= */ false); 1215f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.setTitle(account.name); 12237088fbc6831218f53c5a825274a2beb87db8ba0jovanak 12337088fbc6831218f53c5a825274a2beb87db8ba0jovanak // Set item body = account label. 12437088fbc6831218f53c5a825274a2beb87db8ba0jovanak CharSequence itemBody = mAccountManagerHelper.getLabelForType(accountType); 12537088fbc6831218f53c5a825274a2beb87db8ba0jovanak if (!TextUtils.isEmpty(itemBody)) { 12637088fbc6831218f53c5a825274a2beb87db8ba0jovanak item.setBody(itemBody.toString()); 12737088fbc6831218f53c5a825274a2beb87db8ba0jovanak } 12837088fbc6831218f53c5a825274a2beb87db8ba0jovanak 1295f1f885f598baaf48f31bc7fce953975285e8b42jovanak item.setOnClickListener(view -> mItemClickListener.onAccountClicked(account, userInfo)); 1305f1f885f598baaf48f31bc7fce953975285e8b42jovanak 1311a62a6aebae497433e6fbd996668d6d7f448ac03jovanak // setHideDivider = true will hide the divider to group the items together visually. 1321a62a6aebae497433e6fbd996668d6d7f448ac03jovanak // All of those without a divider between them will be part of the same "group". 1331a62a6aebae497433e6fbd996668d6d7f448ac03jovanak item.setHideDivider(true); 1345f1f885f598baaf48f31bc7fce953975285e8b42jovanak return item; 1355f1f885f598baaf48f31bc7fce953975285e8b42jovanak } 13680c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal 13780c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal /** 1388179594f875d7b99c37f53381219497375da8abdjovanak * Interface for registering clicks on account items. 13980c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal */ 1408179594f875d7b99c37f53381219497375da8abdjovanak interface AccountClickListener { 14180c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal /** 14280c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal * Invoked when a specific account is clicked on. 14380c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal * 14480c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal * @param account Account for which to display details. 14580c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal * @param userInfo User who's the owner of the account. 14680c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal */ 14780c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal void onAccountClicked(Account account, UserInfo userInfo); 14880c03a7c307615475c1898f1a2bb8001b34348d9Roshan Agrawal } 1498179594f875d7b99c37f53381219497375da8abdjovanak} 150