1 /*
2  * Copyright (C) 2014 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.settings.fuelgauge.batterysaver;
18 
19 import android.app.settings.SettingsEnums;
20 import android.content.Context;
21 import android.os.Bundle;
22 import android.provider.SearchIndexableResource;
23 import android.text.Annotation;
24 import android.text.Spannable;
25 import android.text.SpannableStringBuilder;
26 import android.text.Spanned;
27 import android.text.TextPaint;
28 import android.text.TextUtils;
29 import android.text.style.URLSpan;
30 import android.view.View;
31 
32 import androidx.annotation.VisibleForTesting;
33 import androidx.fragment.app.Fragment;
34 
35 import com.android.settings.R;
36 import com.android.settings.dashboard.DashboardFragment;
37 import com.android.settings.search.BaseSearchIndexProvider;
38 import com.android.settings.search.Indexable;
39 import com.android.settingslib.HelpUtils;
40 import com.android.settingslib.search.SearchIndexable;
41 import com.android.settingslib.widget.FooterPreference;
42 
43 import java.util.Arrays;
44 import java.util.List;
45 
46 /**
47  * Battery saver settings page
48  */
49 @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
50 public class BatterySaverSettings extends DashboardFragment {
51     private static final String TAG = "BatterySaverSettings";
52     public static final String KEY_FOOTER_PREFERENCE = "footer_preference";
53     private SpannableStringBuilder mFooterText;
54     private String mHelpUri;
55 
56     @Override
onStart()57     public void onStart() {
58         super.onStart();
59         setupFooter();
60     }
61 
62     @Override
getMetricsCategory()63     public int getMetricsCategory() {
64         return SettingsEnums.FUELGAUGE_BATTERY_SAVER;
65     }
66 
67     @Override
getPreferenceScreenResId()68     protected int getPreferenceScreenResId() {
69         return R.xml.battery_saver_settings;
70     }
71 
72     @Override
getLogTag()73     protected String getLogTag() {
74         return TAG;
75     }
76 
77     @Override
getHelpResource()78     public int getHelpResource() {
79         return R.string.help_url_battery_saver_settings;
80     }
81 
82     /**
83      * For Search.
84      */
85     public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
86             new BaseSearchIndexProvider() {
87                 @Override
88                 public List<SearchIndexableResource> getXmlResourcesToIndex(
89                         Context context, boolean enabled) {
90                     final SearchIndexableResource sir = new SearchIndexableResource(context);
91                     sir.xmlResId = R.xml.battery_saver_settings;
92                     return Arrays.asList(sir);
93                 }
94             };
95 
96     // Updates the footer for this page.
97     @VisibleForTesting
setupFooter()98     void setupFooter() {
99         mFooterText =  new SpannableStringBuilder(getText(
100                 com.android.internal.R.string.battery_saver_description_with_learn_more));
101         mHelpUri = getString(R.string.help_url_battery_saver_settings);
102         if (!TextUtils.isEmpty(mHelpUri)) {
103             addHelpLink();
104         }
105     }
106 
107     // Changes the text to include a learn more link if possible.
108     @VisibleForTesting
addHelpLink()109     void addHelpLink() {
110         FooterPreference pref = getPreferenceScreen().findPreference(KEY_FOOTER_PREFERENCE);
111         if (pref != null) {
112             SupportPageLearnMoreSpan.linkify(mFooterText, this, mHelpUri);
113             pref.setTitle(mFooterText);
114         }
115     }
116 
117     /**
118      * A {@link URLSpan} that opens a support page when clicked
119      */
120     public static class SupportPageLearnMoreSpan extends URLSpan {
121 
122 
123         private static final String ANNOTATION_URL = "url";
124         private final Fragment mFragment;
125         private final String mUriString;
126 
SupportPageLearnMoreSpan(Fragment fragment, String uriString)127         public SupportPageLearnMoreSpan(Fragment fragment, String uriString) {
128             // sets the url to empty string so we can prevent any other span processing from
129             // from clearing things we need in this string.
130             super("");
131             mFragment = fragment;
132             mUriString = uriString;
133         }
134 
135         @Override
onClick(View widget)136         public void onClick(View widget) {
137             if (mFragment != null) {
138                 // launch the support page
139                 mFragment.startActivityForResult(HelpUtils.getHelpIntent(mFragment.getContext(),
140                         mUriString, ""), 0);
141             }
142         }
143 
144         @Override
updateDrawState(TextPaint ds)145         public void updateDrawState(TextPaint ds) {
146             super.updateDrawState(ds);
147             // remove underline
148             ds.setUnderlineText(false);
149         }
150 
151         /**
152          * This method takes a string and turns it into a url span that will launch a support page
153          * @param msg The text to turn into a link
154          * @param fragment The fragment which contains this span
155          * @param uriString The URI string of the help article to open when clicked
156          * @return A CharSequence containing the original text content as a url
157          */
linkify(Spannable msg, Fragment fragment, String uriString)158         public static CharSequence linkify(Spannable msg, Fragment fragment, String uriString) {
159             Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class);
160             for (Annotation annotation : spans) {
161                 int start = msg.getSpanStart(annotation);
162                 int end = msg.getSpanEnd(annotation);
163                 if (ANNOTATION_URL.equals(annotation.getValue())) {
164                     SupportPageLearnMoreSpan link =
165                             new SupportPageLearnMoreSpan(fragment, uriString);
166                     msg.removeSpan(annotation);
167                     msg.setSpan(link, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
168                 }
169             }
170             return msg;
171         }
172     }
173 }
174