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.packageinstaller.role.ui;
18 
19 import android.app.role.OnRoleHoldersChangedListener;
20 import android.app.role.RoleManager;
21 import android.content.Context;
22 import android.content.pm.ApplicationInfo;
23 import android.os.UserHandle;
24 import android.util.Log;
25 import android.util.Pair;
26 
27 import androidx.annotation.NonNull;
28 import androidx.annotation.WorkerThread;
29 import androidx.lifecycle.LiveData;
30 
31 import com.android.packageinstaller.AsyncTaskLiveData;
32 import com.android.packageinstaller.role.model.Role;
33 import com.android.packageinstaller.role.utils.PackageUtils;
34 
35 import java.util.ArrayList;
36 import java.util.List;
37 
38 /**
39  * {@link LiveData} for a role.
40  */
41 public class RoleLiveData extends AsyncTaskLiveData<List<Pair<ApplicationInfo, Boolean>>>
42         implements OnRoleHoldersChangedListener {
43 
44     private static final String LOG_TAG = RoleLiveData.class.getSimpleName();
45 
46     @NonNull
47     private final Role mRole;
48     @NonNull
49     private final UserHandle mUser;
50     @NonNull
51     private final Context mContext;
52 
RoleLiveData(@onNull Role role, @NonNull UserHandle user, @NonNull Context context)53     public RoleLiveData(@NonNull Role role, @NonNull UserHandle user, @NonNull Context context) {
54         mRole = role;
55         mUser = user;
56         mContext = context;
57     }
58 
59     @Override
onActive()60     protected void onActive() {
61         loadValue();
62 
63         RoleManager roleManager = mContext.getSystemService(RoleManager.class);
64         roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(), this, mUser);
65     }
66 
67     @Override
onInactive()68     protected void onInactive() {
69         RoleManager roleManager = mContext.getSystemService(RoleManager.class);
70         roleManager.removeOnRoleHoldersChangedListenerAsUser(this, mUser);
71     }
72 
73     @Override
onRoleHoldersChanged(@onNull String roleName, @NonNull UserHandle user)74     public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
75         loadValue();
76     }
77 
78     @Override
79     @WorkerThread
loadValueInBackground()80     protected List<Pair<ApplicationInfo, Boolean>> loadValueInBackground() {
81         RoleManager roleManager = mContext.getSystemService(RoleManager.class);
82         List<String> holderPackageNames = roleManager.getRoleHoldersAsUser(mRole.getName(), mUser);
83 
84         List<String> qualifyingPackageNames = mRole.getQualifyingPackagesAsUser(mUser, mContext);
85         List<Pair<ApplicationInfo, Boolean>> qualifyingApplications = new ArrayList<>();
86         int qualifyingPackageNamesSize = qualifyingPackageNames.size();
87         for (int i = 0; i < qualifyingPackageNamesSize; i++) {
88             String qualifyingPackageName = qualifyingPackageNames.get(i);
89 
90             ApplicationInfo qualifyingApplicationInfo = PackageUtils.getApplicationInfoAsUser(
91                     qualifyingPackageName, mUser, mContext);
92             if (qualifyingApplicationInfo == null) {
93                 Log.w(LOG_TAG, "Cannot get ApplicationInfo for application, skipping: "
94                         + qualifyingPackageName);
95                 continue;
96             }
97             if (!mRole.isApplicationVisibleAsUser(qualifyingApplicationInfo, mUser, mContext)) {
98                 continue;
99             }
100             boolean isHolderApplication = holderPackageNames.contains(qualifyingPackageName);
101             qualifyingApplications.add(new Pair<>(qualifyingApplicationInfo, isHolderApplication));
102         }
103 
104         return qualifyingApplications;
105     }
106 }
107