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