• 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.packageinstaller.permission.ui.handheld;
18 
19 import static com.android.packageinstaller.Constants.EXTRA_SESSION_ID;
20 
21 import android.content.Context;
22 import android.content.Intent;
23 import android.graphics.drawable.Drawable;
24 import android.text.TextUtils;
25 import android.view.LayoutInflater;
26 import android.view.View;
27 import android.view.ViewGroup;
28 import android.widget.ImageView;
29 import android.widget.TextView;
30 
31 import androidx.annotation.NonNull;
32 import androidx.annotation.Nullable;
33 import androidx.preference.Preference;
34 import androidx.preference.PreferenceViewHolder;
35 
36 import com.android.packageinstaller.permission.model.AppPermissionGroup;
37 import com.android.packageinstaller.permission.ui.AppPermissionActivity;
38 import com.android.permissioncontroller.R;
39 
40 import java.util.List;
41 
42 /**
43  * A preference that links to the screen where a permission can be toggled.
44  */
45 public class PermissionControlPreference extends Preference {
46     private final @NonNull Context mContext;
47     private @Nullable Drawable mWidgetIcon;
48     private boolean mUseSmallerIcon;
49     private boolean mEllipsizeEnd;
50     private @Nullable List<Integer> mTitleIcons;
51     private @Nullable List<Integer> mSummaryIcons;
52 
PermissionControlPreference(@onNull Context context, @NonNull AppPermissionGroup group, @NonNull String caller)53     public PermissionControlPreference(@NonNull Context context,
54             @NonNull AppPermissionGroup group, @NonNull String caller) {
55         this(context, group, caller, 0);
56     }
57 
PermissionControlPreference(@onNull Context context, @NonNull AppPermissionGroup group, @NonNull String caller, long sessionId)58     public PermissionControlPreference(@NonNull Context context,
59             @NonNull AppPermissionGroup group, @NonNull String caller, long sessionId) {
60         super(context);
61         mContext = context;
62         mWidgetIcon = null;
63         mUseSmallerIcon = false;
64         mEllipsizeEnd = false;
65         mTitleIcons = null;
66         mSummaryIcons = null;
67         setOnPreferenceClickListener(preference -> {
68             Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSION);
69             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, group.getApp().packageName);
70             intent.putExtra(Intent.EXTRA_PERMISSION_NAME, group.getPermissions().get(0).getName());
71             intent.putExtra(Intent.EXTRA_USER, group.getUser());
72             intent.putExtra(AppPermissionActivity.EXTRA_CALLER_NAME, caller);
73             intent.putExtra(EXTRA_SESSION_ID, sessionId);
74             context.startActivity(intent);
75             return true;
76         });
77     }
78 
79     /**
80      * Sets this preference's right icon.
81      *
82      * Note that this must be called before preference layout to take effect.
83      *
84      * @param widgetIcon the icon to use.
85      */
setRightIcon(@onNull Drawable widgetIcon)86     public void setRightIcon(@NonNull Drawable widgetIcon) {
87         mWidgetIcon = widgetIcon;
88         setWidgetLayoutResource(R.layout.image_view);
89     }
90 
91     /**
92      * Sets this preference's left icon to be smaller than normal.
93      *
94      * Note that this must be called before preference layout to take effect.
95      */
useSmallerIcon()96     public void useSmallerIcon() {
97         mUseSmallerIcon = true;
98     }
99 
100     /**
101      * Sets this preference's title to use an ellipsis at the end.
102      *
103      * Note that this must be called before preference layout to take effect.
104      */
setEllipsizeEnd()105     public void setEllipsizeEnd() {
106         mEllipsizeEnd = true;
107     }
108 
109     /**
110      * Sets this preference's summary based on the group it represents, if applicable.
111      *
112      * @param group the permission group this preference represents.
113      */
setGroupSummary(@onNull AppPermissionGroup group)114     public void setGroupSummary(@NonNull AppPermissionGroup group) {
115         if (group.hasPermissionWithBackgroundMode() && group.areRuntimePermissionsGranted()) {
116             AppPermissionGroup backgroundGroup = group.getBackgroundPermissions();
117             if (backgroundGroup == null || !backgroundGroup.areRuntimePermissionsGranted()) {
118                 setSummary(R.string.permission_subtitle_only_in_foreground);
119                 return;
120             }
121         }
122         setSummary("");
123     }
124 
125     /**
126      * Sets this preference to show the given icons to the left of its title.
127      *
128      * @param titleIcons the icons to show.
129      */
setTitleIcons(@onNull List<Integer> titleIcons)130     public void setTitleIcons(@NonNull List<Integer> titleIcons) {
131         mTitleIcons = titleIcons;
132         setLayoutResource(R.layout.preference_usage);
133     }
134 
135     /**
136      * Sets this preference to show the given icons to the left of its summary.
137      *
138      * @param summaryIcons the icons to show.
139      */
setSummaryIcons(@onNull List<Integer> summaryIcons)140     public void setSummaryIcons(@NonNull List<Integer> summaryIcons) {
141         mSummaryIcons = summaryIcons;
142         setLayoutResource(R.layout.preference_usage);
143     }
144 
145     @Override
onBindViewHolder(PreferenceViewHolder holder)146     public void onBindViewHolder(PreferenceViewHolder holder) {
147         if (mUseSmallerIcon) {
148             ImageView icon = ((ImageView) holder.findViewById(android.R.id.icon));
149             icon.setMaxWidth(
150                     mContext.getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size));
151             icon.setMaxHeight(
152                     mContext.getResources().getDimensionPixelSize(R.dimen.secondary_app_icon_size));
153         }
154 
155         super.onBindViewHolder(holder);
156 
157         if (mWidgetIcon != null) {
158             View widgetFrame = holder.findViewById(android.R.id.widget_frame);
159             ((ImageView) widgetFrame.findViewById(R.id.icon)).setImageDrawable(mWidgetIcon);
160         }
161 
162         if (mEllipsizeEnd) {
163             TextView title = (TextView) holder.findViewById(android.R.id.title);
164             title.setMaxLines(1);
165             title.setEllipsize(TextUtils.TruncateAt.END);
166         }
167 
168         setIcons(holder, mSummaryIcons, R.id.summary_widget_frame);
169         setIcons(holder, mTitleIcons, R.id.title_widget_frame);
170     }
171 
setIcons(PreferenceViewHolder holder, @Nullable List<Integer> icons, int frameId)172     private void setIcons(PreferenceViewHolder holder, @Nullable List<Integer> icons, int frameId) {
173         ViewGroup frame = (ViewGroup) holder.findViewById(frameId);
174         if (icons != null && !icons.isEmpty()) {
175             frame.setVisibility(View.VISIBLE);
176             frame.removeAllViews();
177             int numIcons = icons.size();
178             for (int i = 0; i < numIcons; i++) {
179                 LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
180                 ViewGroup group = (ViewGroup) inflater.inflate(R.layout.title_summary_image_view,
181                         null);
182                 ImageView imageView = group.requireViewById(R.id.icon);
183                 imageView.setImageResource(icons.get(i));
184                 frame.addView(group);
185             }
186         } else if (frame != null) {
187             frame.setVisibility(View.GONE);
188         }
189     }
190 }
191