1 /* 2 * Copyright (C) 2016 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.storagemanager.deletionhelper; 18 19 import android.app.Activity; 20 import android.app.Fragment; 21 import android.app.FragmentManager; 22 import android.os.Bundle; 23 import android.provider.Settings; 24 import android.text.SpannableString; 25 import android.text.Spanned; 26 import android.text.TextPaint; 27 import android.text.style.ClickableSpan; 28 import android.view.Menu; 29 import android.view.MenuInflater; 30 import android.view.MenuItem; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.widget.Button; 34 import android.widget.TextView.BufferType; 35 import com.android.settingslib.widget.LinkTextView; 36 import com.android.storagemanager.ButtonBarProvider; 37 import com.android.storagemanager.R; 38 import com.android.storagemanager.utils.Utils; 39 40 /** 41 * The DeletionHelperActivity is an activity for deleting apps, photos, and downloaded files which 42 * have not been recently used. 43 */ 44 public class DeletionHelperActivity extends Activity implements ButtonBarProvider { 45 private static final int ENABLED = 1; 46 47 private ViewGroup mButtonBar; 48 private Button mNextButton, mSkipButton; 49 private DeletionHelperSettings mFragment; 50 private boolean mIsShowingInterstitial; 51 52 @Override onCreate(Bundle savedInstanceState)53 protected void onCreate(Bundle savedInstanceState) { 54 super.onCreate(savedInstanceState); 55 setContentView(R.layout.settings_main_prefs); 56 57 setIsEmptyState(false /* isEmptyState */); 58 59 // If we are not returning from an existing activity, create a new fragment. 60 if (savedInstanceState == null) { 61 FragmentManager manager = getFragmentManager(); 62 mFragment = DeletionHelperSettings.newInstance(AppsAsyncLoader.NORMAL_THRESHOLD); 63 manager.beginTransaction().replace(R.id.main_content, mFragment).commit(); 64 } 65 SpannableString linkText = 66 new SpannableString( 67 getString(R.string.empty_state_review_items_link).toUpperCase()); 68 LinkTextView emptyStateLink = (LinkTextView) findViewById(R.id.all_items_link); 69 linkText = NoThresholdSpan.linkify(linkText, this); 70 emptyStateLink.setText(linkText, BufferType.SPANNABLE); 71 72 mButtonBar = (ViewGroup) findViewById(R.id.button_bar); 73 mNextButton = (Button) findViewById(R.id.next_button); 74 mSkipButton = (Button) findViewById(R.id.skip_button); 75 76 getActionBar().setDisplayHomeAsUpEnabled(true); 77 } 78 79 @Override onRequestPermissionsResult( int requestCode, String permissions[], int[] grantResults)80 public void onRequestPermissionsResult( 81 int requestCode, String permissions[], int[] grantResults) { 82 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 83 mFragment.onRequestPermissionsResult(requestCode, permissions, grantResults); 84 } 85 setIsEmptyState(boolean isEmptyState)86 void setIsEmptyState(boolean isEmptyState) { 87 final View emptyContent = findViewById(R.id.empty_state); 88 final View mainContent = findViewById(R.id.main_content); 89 90 // Update UI 91 mainContent.setVisibility(isEmptyState ? View.GONE : View.VISIBLE); 92 emptyContent.setVisibility(isEmptyState ? View.VISIBLE : View.GONE); 93 findViewById(R.id.button_bar).setVisibility(isEmptyState ? View.GONE : View.VISIBLE); 94 setTitle(isEmptyState ? R.string.empty_state_title : R.string.deletion_helper_title); 95 96 // We are giving the user the option to show all in the interstitial, so let's hide the 97 // overflow for this. (Also, the overflow's functions are busted while the empty view is 98 // showing, so this also works around this bug.) 99 mIsShowingInterstitial = isEmptyState && emptyContent.getVisibility() != View.VISIBLE; 100 invalidateOptionsMenu(); 101 } 102 isLoadingVisible()103 public boolean isLoadingVisible() { 104 View loading_container = findViewById(R.id.loading_container); 105 if (loading_container != null) { 106 return loading_container.getVisibility() == View.VISIBLE; 107 } 108 return false; 109 } 110 setLoading(View listView, boolean loading, boolean animate)111 public void setLoading(View listView, boolean loading, boolean animate) { 112 View loading_container = findViewById(R.id.loading_container); 113 Utils.handleLoadingContainer(loading_container, listView, !loading, animate); 114 getButtonBar().setVisibility(loading ? View.GONE : View.VISIBLE); 115 } 116 117 @Override getButtonBar()118 public ViewGroup getButtonBar() { 119 return mButtonBar; 120 } 121 122 @Override getNextButton()123 public Button getNextButton() { 124 return mNextButton; 125 } 126 127 @Override getSkipButton()128 public Button getSkipButton() { 129 return mSkipButton; 130 } 131 132 @Override onCreateOptionsMenu(Menu menu)133 public boolean onCreateOptionsMenu(Menu menu) { 134 final int isNonthresholdAvailable = 135 Settings.Global.getInt( 136 getContentResolver(), 137 Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE, 138 ENABLED); 139 if (isNonthresholdAvailable < ENABLED || mIsShowingInterstitial) { 140 return false; 141 } 142 143 MenuInflater inflater = getMenuInflater(); 144 inflater.inflate(R.menu.deletion_helper_settings_menu, menu); 145 return true; 146 } 147 148 @Override onOptionsItemSelected(MenuItem item)149 public boolean onOptionsItemSelected(MenuItem item) { 150 FragmentManager manager = getFragmentManager(); 151 int thresholdType; 152 switch (item.getItemId()) { 153 case R.id.no_threshold: 154 thresholdType = AppStateUsageStatsBridge.NO_THRESHOLD; 155 break; 156 case R.id.default_threshold: 157 thresholdType = AppStateUsageStatsBridge.NORMAL_THRESHOLD; 158 break; 159 default: 160 return super.onOptionsItemSelected(item); 161 } 162 163 mFragment = DeletionHelperSettings.newInstance(thresholdType); 164 manager.beginTransaction().replace(R.id.main_content, mFragment).commit(); 165 return true; 166 } 167 168 @Override onNavigateUp()169 public boolean onNavigateUp() { 170 finish(); 171 return true; 172 } 173 174 private static class NoThresholdSpan extends ClickableSpan { 175 private final DeletionHelperActivity mParent; 176 NoThresholdSpan(DeletionHelperActivity parent)177 public NoThresholdSpan(DeletionHelperActivity parent) { 178 super(); 179 mParent = parent; 180 } 181 182 @Override onClick(View widget)183 public void onClick(View widget) { 184 FragmentManager manager = mParent.getFragmentManager(); 185 Fragment fragment = DeletionHelperSettings.newInstance(AppsAsyncLoader.NO_THRESHOLD); 186 manager.beginTransaction().replace(R.id.main_content, fragment).commit(); 187 mParent.setIsEmptyState(false); 188 } 189 190 @Override updateDrawState(TextPaint ds)191 public void updateDrawState(TextPaint ds) { 192 super.updateDrawState(ds); 193 // Remove underline 194 ds.setUnderlineText(false); 195 } 196 197 /** 198 * This method takes a string and turns it into a url span that will launch a 199 * SupportSystemInformationDialogFragment 200 * 201 * @param msg The text to turn into a link 202 * @param parent The dialog the text is in 203 * @return A CharSequence containing the original text content as a url 204 */ linkify(SpannableString msg, DeletionHelperActivity parent)205 public static SpannableString linkify(SpannableString msg, DeletionHelperActivity parent) { 206 NoThresholdSpan link = new NoThresholdSpan(parent); 207 msg.setSpan(link, 0, msg.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 208 return msg; 209 } 210 } 211 }