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