• 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.settings.common;
18 
19 import static com.android.settingslib.drawer.TileUtils.EXTRA_SETTINGS_ACTION;
20 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_ICON;
21 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_SUMMARY;
22 import static com.android.settingslib.drawer.TileUtils.META_DATA_PREFERENCE_TITLE;
23 
24 import android.app.ActivityManager;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.pm.ActivityInfo;
28 import android.content.pm.PackageManager;
29 import android.content.pm.ResolveInfo;
30 import android.content.res.Resources;
31 import android.graphics.drawable.Icon;
32 import android.os.Bundle;
33 import android.text.TextUtils;
34 
35 import androidx.car.widget.ListItem;
36 import androidx.car.widget.TextListItem;
37 
38 import com.android.car.settings.R;
39 
40 import java.util.Collection;
41 import java.util.HashMap;
42 import java.util.LinkedList;
43 import java.util.List;
44 import java.util.Map;
45 
46 /**
47  * Loads Activity with TileUtils.EXTRA_SETTINGS_ACTION.
48  */
49 public class ExtraSettingsLoader {
50     private static final Logger LOG = new Logger(ExtraSettingsLoader.class);
51     private static final String META_DATA_PREFERENCE_CATEGORY = "com.android.settings.category";
52     public static final String WIRELESS_CATEGORY = "com.android.settings.category.wireless";
53     public static final String DEVICE_CATEGORY = "com.android.settings.category.device";
54     public static final String SYSTEM_CATEGORY = "com.android.settings.category.system";
55     public static final String PERSONAL_CATEGORY = "com.android.settings.category.personal";
56     private final Context mContext;
57 
ExtraSettingsLoader(Context context)58     public ExtraSettingsLoader(Context context) {
59         mContext = context;
60     }
61 
62     /**
63      * Returns a map of category and setting items pair loaded from 3rd party.
64      */
load()65     public Map<String, Collection<ListItem>> load() {
66         PackageManager pm = mContext.getPackageManager();
67         Intent intent = new Intent(EXTRA_SETTINGS_ACTION);
68         Map<String, Collection<ListItem>> extraSettings = new HashMap<>();
69         // initialize the categories
70         extraSettings.put(WIRELESS_CATEGORY, new LinkedList());
71         extraSettings.put(DEVICE_CATEGORY, new LinkedList());
72         extraSettings.put(SYSTEM_CATEGORY, new LinkedList());
73         extraSettings.put(PERSONAL_CATEGORY, new LinkedList());
74 
75         List<ResolveInfo> results = pm.queryIntentActivitiesAsUser(intent,
76                 PackageManager.GET_META_DATA, ActivityManager.getCurrentUser());
77 
78         for (ResolveInfo resolved : results) {
79             if (!resolved.system) {
80                 // Do not allow any app to be added to settings, only system ones.
81                 continue;
82             }
83             String title = null;
84             String summary = null;
85             String category = null;
86             ActivityInfo activityInfo = resolved.activityInfo;
87             Bundle metaData = activityInfo.metaData;
88             try {
89                 Resources res = pm.getResourcesForApplication(activityInfo.packageName);
90                 if (metaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
91                     if (metaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
92                         title = res.getString(metaData.getInt(META_DATA_PREFERENCE_TITLE));
93                     } else {
94                         title = metaData.getString(META_DATA_PREFERENCE_TITLE);
95                     }
96                 }
97                 if (TextUtils.isEmpty(title)) {
98                     LOG.d("no title.");
99                     title = activityInfo.loadLabel(pm).toString();
100                 }
101                 if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY)) {
102                     if (metaData.get(META_DATA_PREFERENCE_SUMMARY) instanceof Integer) {
103                         summary = res.getString(metaData.getInt(META_DATA_PREFERENCE_SUMMARY));
104                     } else {
105                         summary = metaData.getString(META_DATA_PREFERENCE_SUMMARY);
106                     }
107                 } else {
108                     LOG.d("no description.");
109                 }
110                 if (metaData.containsKey(META_DATA_PREFERENCE_CATEGORY)) {
111                     if (metaData.get(META_DATA_PREFERENCE_CATEGORY) instanceof Integer) {
112                         category = res.getString(metaData.getInt(META_DATA_PREFERENCE_CATEGORY));
113                     } else {
114                         category = metaData.getString(META_DATA_PREFERENCE_CATEGORY);
115                     }
116                 } else {
117                     LOG.d("no category.");
118                 }
119             } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
120                 LOG.d("Couldn't find info", e);
121             }
122             Icon icon = null;
123             if (metaData.containsKey(META_DATA_PREFERENCE_ICON)) {
124                 int iconRes = metaData.getInt(META_DATA_PREFERENCE_ICON);
125                 icon = Icon.createWithResource(activityInfo.packageName, iconRes);
126             } else {
127                 icon = Icon.createWithResource(mContext, R.drawable.ic_settings_gear);
128                 LOG.d("use default icon.");
129             }
130             Intent extraSettingIntent =
131                     new Intent().setClassName(activityInfo.packageName, activityInfo.name);
132             if (category == null || !extraSettings.containsKey(category)) {
133                 // If category is not specified or not supported, default to device.
134                 category = DEVICE_CATEGORY;
135             }
136             TextListItem item = new TextListItem(mContext);
137             item.setTitle(title);
138             item.setBody(summary);
139             item.setPrimaryActionIcon(icon.loadDrawable(mContext), /* useLargeIcon= */ false);
140             item.setSupplementalIcon(R.drawable.ic_chevron_right, /* showDivider= */ false);
141             item.setOnClickListener(v -> mContext.startActivity(extraSettingIntent));
142             extraSettings.get(category).add(item);
143         }
144         return extraSettings;
145     }
146 }
147