• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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.permissioncontroller.permission.ui.handheld;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.graphics.drawable.Drawable;
22 import android.os.Bundle;
23 import android.os.UserHandle;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.ImageView;
28 import android.widget.TextView;
29 
30 import androidx.annotation.NonNull;
31 import androidx.annotation.Nullable;
32 import androidx.preference.PreferenceScreen;
33 import androidx.preference.PreferenceViewHolder;
34 
35 import com.android.permissioncontroller.DeviceUtils;
36 import com.android.permissioncontroller.R;
37 
38 /**
39  * A class that contains a header.
40  */
41 public abstract class SettingsWithLargeHeader extends PermissionsFrameFragment  {
42     static final String HEADER_KEY = " HEADER_PREFERENCE";
43     private static final int HEADER_SORT_FIRST = -2;
44 
45     private View mHeader;
46     private LargeHeaderPreference mHeaderPreference;
47     protected Intent mInfoIntent;
48     protected UserHandle mUserHandle;
49     protected Drawable mIcon;
50     protected CharSequence mLabel;
51     protected boolean mSmallIcon;
52     private View.OnClickListener mListener;
53     private CharSequence mSummary;
54     private boolean mShouldShowHeader = true;
55 
56     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)57     public View onCreateView(LayoutInflater inflater, ViewGroup container,
58             Bundle savedInstanceState) {
59         ViewGroup root = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
60 
61         if (!DeviceUtils.isTelevision(getContext())) {
62             if (mHeader != null && mHeader.getVisibility() == View.VISIBLE) {
63                 updateHeader(mHeader);
64                 mHeader.requireViewById(R.id.header_link).setVisibility(View.VISIBLE);
65             }
66         }
67 
68         return root;
69     }
70 
71     @Override
setPreferenceScreen(PreferenceScreen screen)72     public void setPreferenceScreen(PreferenceScreen screen) {
73         mHeaderPreference = new LargeHeaderPreference(getContext(), this);
74         if (screen.findPreference(HEADER_KEY) == null) {
75             screen.addPreference(mHeaderPreference);
76         }
77         super.setPreferenceScreen(screen);
78     }
79 
80     /**
81      * Set the icon and label to use in the header.
82      *
83      * @param icon the icon
84      * @param label the label
85      * @param infoIntent the intent to show on click
86      * @param smallIcon whether the icon should be small
87      */
setHeader(@onNull Drawable icon, @NonNull CharSequence label, Intent infoIntent, @Nullable UserHandle userHandle, boolean smallIcon)88     public void setHeader(@NonNull Drawable icon, @NonNull CharSequence label,
89             Intent infoIntent, @Nullable UserHandle userHandle, boolean smallIcon) {
90         mIcon = icon;
91         mLabel = label;
92         mInfoIntent = infoIntent;
93         mUserHandle = userHandle;
94         mSmallIcon = smallIcon;
95         if (mHeader != null) {
96             updateHeader(mHeader);
97         }
98     }
99 
100     /**
101      * Updates the header to use the correct icon and title.
102      *
103      * @param header the View that contains the components.
104      */
updateHeader(@ullable View header)105     protected void updateHeader(@Nullable View header) {
106         if (header != null) {
107             header.setVisibility(View.VISIBLE);
108 
109             ImageView appIcon = header.requireViewById(
110                     com.android.settingslib.widget.preference.layout.R.id.entity_header_icon);
111             appIcon.setImageDrawable(mIcon);
112             if (mSmallIcon) {
113                 int size = getContext().getResources().getDimensionPixelSize(
114                         R.dimen.permission_icon_header_size);
115                 appIcon.getLayoutParams().width = size;
116                 appIcon.getLayoutParams().height = size;
117             }
118             if (mInfoIntent != null) {
119                 appIcon.setOnClickListener(v -> getActivity().startActivityAsUser(mInfoIntent,
120                         mUserHandle));
121                 appIcon.setContentDescription(mLabel);
122             }
123 
124             TextView appName = header.requireViewById(
125                     com.android.settingslib.widget.preference.layout.R.id.entity_header_title);
126             appName.setText(mLabel);
127 
128 
129             header.requireViewById(
130                     com.android.settingslib.widget.preference.layout.R.id.entity_header_summary)
131                     .setVisibility(View.GONE);
132 
133             header.requireViewById(
134                     com.android.settingslib.widget.preference.layout.R.id.entity_header_second_summary)
135                     .setVisibility(View.GONE);
136             header.requireViewById(R.id.header_link).setVisibility(View.GONE);
137         }
138     }
139 
140     /**
141      * Hide the entire header.
142      */
hideHeader()143     public void hideHeader() {
144         if (mHeaderPreference == null) {
145             mShouldShowHeader = false;
146             return;
147         }
148         mHeaderPreference.setVisible(false);
149         mHeader = null;
150     }
151 
152     /**
153      * Set the summary text in the header. If the header has not been created yet, then save the
154      * the summary for later.
155      *
156      * @param summary the text to display
157      * @param listener the click listener if the summary should be clickable
158      */
setSummary(@onNull CharSequence summary, @Nullable View.OnClickListener listener)159     public void setSummary(@NonNull CharSequence summary, @Nullable View.OnClickListener listener) {
160         if (mHeader == null) {
161             mSummary = summary;
162             mListener = listener;
163             return;
164         }
165         TextView textView = mHeader.requireViewById(R.id.header_text);
166         TextView linkView = mHeader.requireViewById(R.id.header_link);
167         if (listener != null) {
168             linkView.setOnClickListener(listener);
169             linkView.setVisibility(View.VISIBLE);
170             linkView.setText(summary);
171             textView.setVisibility(View.GONE);
172         } else {
173             textView.setVisibility(View.VISIBLE);
174             textView.setText(summary);
175             linkView.setVisibility(View.GONE);
176         }
177     }
178 
179     /**
180      * A Preference that will act as the "Large Header" for "SettingsWithLargeHeader" fragments.
181      */
182     public static class LargeHeaderPreference extends PermissionPreferenceCategory {
183         private SettingsWithLargeHeader mFragment;
184 
LargeHeaderPreference(Context context, SettingsWithLargeHeader fragment)185         private LargeHeaderPreference(Context context, SettingsWithLargeHeader fragment) {
186             super(context);
187             mFragment = fragment;
188             setVisible(mFragment.mShouldShowHeader);
189             setSelectable(false);
190             setLayoutResource(R.layout.header_large);
191             setKey(HEADER_KEY);
192 
193             // display the header first (lower numbers are ordered higher)
194             setOrder(HEADER_SORT_FIRST);
195         }
196 
197         @Override
onBindViewHolder(PreferenceViewHolder holder)198         public void onBindViewHolder(PreferenceViewHolder holder) {
199             if (!isVisible()) {
200                 return;
201             }
202             super.onBindViewHolder(holder);
203 
204             View view = holder.itemView;
205             if (view == mFragment.mHeader) {
206                 return;
207             }
208             mFragment.mHeader = view;
209             if (mFragment.mIcon != null) {
210                 mFragment.updateHeader(view);
211             }
212             if (mFragment.mSummary != null) {
213                 mFragment.setSummary(mFragment.mSummary, mFragment.mListener);
214             }
215         }
216     }
217 }
218