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