• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 package com.android.settings.applications;
17 
18 import android.content.Context;
19 import android.content.pm.PackageManager;
20 import android.content.pm.ResolveInfo;
21 import android.os.UserHandle;
22 import android.os.UserManager;
23 import android.util.ArrayMap;
24 import android.util.Log;
25 
26 import com.android.settings.Utils;
27 import com.android.settingslib.applications.ApplicationsState;
28 import com.android.settingslib.applications.ApplicationsState.AppEntry;
29 import com.android.settingslib.applications.ApplicationsState.AppFilter;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Map;
34 
35 /**
36  * Creates a application filter to restrict UI display of applications.
37  * This is to avoid users from changing the per apps locale
38  * Also provides app filters that can use the info.
39  */
40 public class AppStateLocaleBridge extends AppStateBaseBridge {
41     private static final String TAG = AppStateLocaleBridge.class.getSimpleName();
42 
43     private final Context mContext;
44     private final Map<Integer, AppInfoByProfiles> mUserIdToAppInfoByProfiles = new ArrayMap<>();
45 
AppStateLocaleBridge(Context context, ApplicationsState appState, Callback callback, UserManager userManager)46     public AppStateLocaleBridge(Context context, ApplicationsState appState,
47             Callback callback, UserManager userManager) {
48         super(appState, callback);
49         mContext = context;
50         collectLocaleBridgeInfo(userManager);
51     }
52 
53     @Override
updateExtraInfo(AppEntry app, String packageName, int uid)54     protected void updateExtraInfo(AppEntry app, String packageName, int uid) {
55         AppInfoByProfiles appInfoByProfiles = getAppInfo(UserHandle.getUserId(uid));
56 
57         app.extraInfo = AppLocaleUtil.canDisplayLocaleUi(appInfoByProfiles.mContextAsUser,
58                 app.info, appInfoByProfiles.mListInfos) ? Boolean.TRUE : Boolean.FALSE;
59     }
60 
61     @Override
loadAllExtraInfo()62     protected void loadAllExtraInfo() {
63         final List<AppEntry> allApps = mAppSession.getAllApps();
64         for (int i = 0; i < allApps.size(); i++) {
65             AppEntry app = allApps.get(i);
66             AppInfoByProfiles appInfoByProfiles = getAppInfo(UserHandle.getUserId(app.info.uid));
67 
68             app.extraInfo = AppLocaleUtil.canDisplayLocaleUi(appInfoByProfiles.mContextAsUser,
69                     app.info, appInfoByProfiles.mListInfos) ? Boolean.TRUE : Boolean.FALSE;
70         }
71     }
72 
73     /** For the Settings which shows category of per app's locale. */
74     public static final AppFilter FILTER_APPS_LOCALE =
75             new AppFilter() {
76                 @Override
77                 public void init() {
78                 }
79 
80                 @Override
81                 public boolean filterApp(AppEntry entry) {
82                     if (entry.extraInfo == null) {
83                         Log.d(TAG, "[" + entry.info.packageName + "]" + " has No extra info.");
84                         return false;
85                     }
86                     return entry.extraInfo == Boolean.TRUE;
87                 }
88             };
89 
collectLocaleBridgeInfo(UserManager userManager)90     private void collectLocaleBridgeInfo(UserManager userManager) {
91         List<Integer> userIds = new ArrayList<>();
92 
93         userIds.add(mContext.getUserId());
94         int workUserId = Utils.getManagedProfileId(userManager, mContext.getUserId());
95         if (workUserId != UserHandle.USER_NULL) {
96             userIds.add(workUserId);
97         }
98 
99         // Separate the app information by profiles.
100         for (int userId : userIds) {
101             if (!mUserIdToAppInfoByProfiles.containsKey(userId)) {
102                 mUserIdToAppInfoByProfiles.put(userId, new AppInfoByProfiles(mContext, userId));
103             }
104         }
105     }
106 
getAppInfo(int userId)107     private AppInfoByProfiles getAppInfo(int userId) {
108         AppInfoByProfiles info;
109         if (mUserIdToAppInfoByProfiles.containsKey(userId)) {
110             info = mUserIdToAppInfoByProfiles.get(userId);
111         } else {
112             info = new AppInfoByProfiles(mContext, userId);
113             mUserIdToAppInfoByProfiles.put(userId, info);
114         }
115 
116         return info;
117     }
118 
119     /**
120      * The app information by profiles.
121      */
122     private static class AppInfoByProfiles {
123         public final Context mContextAsUser;
124         public final List<ResolveInfo> mListInfos;
125 
AppInfoByProfiles(Context context, int userId)126         private AppInfoByProfiles(Context context, int userId) {
127             mContextAsUser = context.createContextAsUser(UserHandle.of(userId), 0);
128             mListInfos = mContextAsUser.getPackageManager().queryIntentActivities(
129                     AppLocaleUtil.LAUNCHER_ENTRY_INTENT, PackageManager.GET_META_DATA);
130         }
131     }
132 }
133