Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b240648f3b8fc40269555549289f3c2e10d4be23 |
| --- /dev/null |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivity.java |
| @@ -0,0 +1,236 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.preferences.website; |
| + |
| +import android.app.ActivityManager; |
| +import android.app.AlertDialog; |
| +import android.content.Context; |
| +import android.content.DialogInterface; |
| +import android.content.Intent; |
| +import android.os.Bundle; |
| +import android.support.v7.app.AppCompatActivity; |
| +import android.text.format.Formatter; |
| +import android.view.View; |
| +import android.widget.Button; |
| +import android.widget.TextView; |
| + |
| +import org.chromium.base.Log; |
| +import org.chromium.base.library_loader.LibraryProcessType; |
| +import org.chromium.base.library_loader.ProcessInitException; |
| +import org.chromium.chrome.R; |
| +import org.chromium.chrome.browser.preferences.Preferences; |
| +import org.chromium.chrome.browser.preferences.PreferencesLauncher; |
| +import org.chromium.chrome.browser.preferences.website.Website.StoredDataClearedCallback; |
| +import org.chromium.content.browser.BrowserStartupController; |
| + |
| +import java.util.HashSet; |
| +import java.util.List; |
| +import java.util.Map; |
| +import java.util.Set; |
| + |
| +/** |
| + * This is the target activity for the "Manage Storage" button in the Android Settings UI. This is |
| + * configured in the AndroidManifest.xml file by setting the android:manageSpaceActivity. |
| + */ |
| +public class ManageSpaceActivity extends AppCompatActivity implements View.OnClickListener { |
| + private static final String TAG = "ManageSpaceActivity"; |
| + |
| + private View mClearAllDataSection; |
| + private TextView mUnimportantSiteDataSizeText; |
| + private TextView mSiteDataSizeText; |
| + private Button mClearUnimportantButton; |
| + private Button mManageSiteDataButton; |
| + private Button mClearAllDataButton; |
| + |
| + @Override |
| + protected void onCreate(Bundle savedInstanceState) { |
| + super.onCreate(savedInstanceState); |
| + setContentView(R.layout.manage_space_activity); |
| + |
| + mSiteDataSizeText = (TextView) findViewById(R.id.site_data_storage_size_text); |
| + mSiteDataSizeText.setText(R.string.storage_management_computing_size); |
| + mUnimportantSiteDataSizeText = |
| + (TextView) findViewById(R.id.unimportant_site_data_storage_size_text); |
| + mUnimportantSiteDataSizeText.setText(R.string.storage_management_computing_size); |
| + mManageSiteDataButton = (Button) findViewById(R.id.manage_site_data_storage); |
| + mManageSiteDataButton.setOnClickListener(this); |
| + mClearUnimportantButton = (Button) findViewById(R.id.clear_unimportant_site_data_storage); |
| + mClearUnimportantButton.setOnClickListener(this); |
| + |
| + mClearAllDataSection = findViewById(R.id.clear_all_data_section); |
| + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { |
| + mClearAllDataButton = (Button) findViewById(R.id.clear_all_data); |
| + mClearAllDataButton.setOnClickListener(this); |
| + } else { |
| + mClearAllDataSection.setVisibility(View.GONE); |
|
Finnur
2016/03/03 14:15:43
Maybe explain a little why?
dmurph
2016/04/26 21:43:13
Done.
|
| + } |
| + } |
| + |
| + @Override |
| + protected void onResume() { |
| + super.onResume(); |
| + BrowserStartupController controller = |
| + BrowserStartupController.get(this, LibraryProcessType.PROCESS_BROWSER); |
|
Finnur
2016/03/03 14:15:43
It is not immediately clear to me why this and the
dmurph
2016/04/26 21:43:12
Done.
|
| + try { |
| + controller.startBrowserProcessesAsync(new BrowserStartupController.StartupCallback() { |
| + @Override |
| + public void onSuccess(boolean alreadyStarted) { |
| + WebsitePermissionsFetcher fetcher = |
| + new WebsitePermissionsFetcher(new SizeCalculator()); |
| + fetcher.fetchPreferencesForCategory(SiteSettingsCategory.fromString( |
| + SiteSettingsCategory.CATEGORY_USE_STORAGE)); |
| + } |
| + |
| + @Override |
| + public void onFailure() { |
| + Log.e(TAG, "Failed to start browser process."); |
| + } |
| + }); |
| + } catch (ProcessInitException e) { |
| + Log.e(TAG, "Failed to attach native libraries.", e); |
| + } |
| + } |
| + |
| + private void clearUnimportantData() { |
| + mSiteDataSizeText.setText(R.string.storage_management_computing_size); |
| + mUnimportantSiteDataSizeText.setText(R.string.storage_management_computing_size); |
| + WebsitePermissionsFetcher fetcher = |
| + new WebsitePermissionsFetcher(new UnimportantDataClearer()); |
| + fetcher.fetchPreferencesForCategory( |
| + SiteSettingsCategory.fromString(SiteSettingsCategory.CATEGORY_USE_STORAGE)); |
| + } |
| + |
| + @Override |
| + public void onClick(View v) { |
|
Finnur
2016/03/03 14:15:43
s/v/view/
dmurph
2016/04/26 21:43:13
Done.
|
| + if (v == mClearUnimportantButton) { |
| + AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| + @Override |
| + public void onClick(DialogInterface dialog, int id) { |
| + clearUnimportantData(); |
| + } |
| + }); |
| + builder.setNegativeButton(R.string.cancel, null); |
| + builder.setTitle(R.string.storage_management_clear_unimportant_dialog_title); |
| + builder.setMessage(R.string.storage_management_clear_unimportant_dialog_text); |
| + builder.create().show(); |
| + } else if (v == mManageSiteDataButton) { |
| + Intent intent = PreferencesLauncher.createIntentForSettingsPage( |
| + this, SingleCategoryPreferences.class.getName()); |
| + Bundle initialArguments = new Bundle(); |
| + initialArguments.putString(SingleCategoryPreferences.EXTRA_CATEGORY, |
| + SiteSettingsCategory.CATEGORY_USE_STORAGE); |
| + initialArguments.putString(SingleCategoryPreferences.EXTRA_TITLE, |
| + getString(R.string.website_settings_storage)); |
| + intent.putExtra(Preferences.EXTRA_SHOW_FRAGMENT_ARGUMENTS, initialArguments); |
| + startActivity(intent); |
| + } else if (v == mClearAllDataButton) { |
| + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { |
| + return; |
| + } |
| + final ActivityManager activityManager = |
| + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); |
| + AlertDialog.Builder builder = new AlertDialog.Builder(this); |
| + builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| + @Override |
| + public void onClick(DialogInterface dialog, int id) { |
| + activityManager.clearApplicationUserData(); |
| + } |
| + }); |
| + builder.setNegativeButton(R.string.cancel, null); |
| + builder.setTitle(R.string.storage_management_reset_app_dialog_title); |
| + builder.setMessage(R.string.storage_management_reset_app_dialog_text); |
| + builder.create().show(); |
| + } |
| + } |
| + |
| + private void onSiteStorageSizeCalculated(long totalSize, long unimportantSize) { |
| + mSiteDataSizeText.setText(Formatter.formatFileSize(this, totalSize)); |
| + mUnimportantSiteDataSizeText.setText(Formatter.formatFileSize(this, unimportantSize)); |
| + } |
| + |
| + private void onSiteStorageCleared() { |
| + WebsitePermissionsFetcher fetcher = new WebsitePermissionsFetcher(new SizeCalculator()); |
| + fetcher.fetchPreferencesForCategory( |
| + SiteSettingsCategory.fromString(SiteSettingsCategory.CATEGORY_USE_STORAGE)); |
| + } |
| + |
| + private class SizeCalculator implements WebsitePermissionsFetcher.WebsitePermissionsCallback { |
| + @Override |
| + public void onWebsitePermissionsAvailable(Map<String, Set<Website>> sitesByOrigin, |
| + Map<String, Set<Website>> sitesByHost, List<String> importantOrigins) { |
| + long siteStorageSize = 0; |
| + // First we scan origins to get settings from there. |
| + Set<Website> sites = new HashSet<>(); |
| + for (Map.Entry<String, Set<Website>> element : sitesByOrigin.entrySet()) { |
| + for (Website site : element.getValue()) { |
| + sites.add(site); |
| + } |
| + } |
| + // Next we add sites that are only accessible by host name. |
| + for (Map.Entry<String, Set<Website>> element : sitesByHost.entrySet()) { |
| + for (Website site : element.getValue()) { |
| + if (!sites.contains(site)) { |
| + sites.add(site); |
| + } |
| + } |
| + } |
| + long importantSize = 0; |
|
Finnur
2016/03/03 14:15:43
This variable name looks a bit weird. Important Si
dmurph
2016/04/26 21:43:12
Done.
|
| + Set<String> importantSites = new HashSet<String>(); |
| + importantSites.addAll(importantOrigins); |
| + for (Website site : sites) { |
| + siteStorageSize += site.getTotalUsage(); |
| + Log.i(TAG, "Origin engagement score: " + site.getLocalStorageInfo().getOrigin() |
| + + ", " + site.getLocalStorageInfo().getSiteEngagementScore()); |
|
Finnur
2016/03/03 14:15:43
Remember to take this and all other debug log stat
dmurph
2016/04/26 21:43:12
Done.
|
| + if (importantSites.contains(site.getLocalStorageInfo().getOrigin())) { |
| + importantSize += site.getTotalUsage(); |
| + } |
| + } |
| + |
| + onSiteStorageSizeCalculated(siteStorageSize, siteStorageSize - importantSize); |
| + } |
| + } |
| + |
| + private class UnimportantDataClearer |
|
Finnur
2016/03/03 14:15:43
As you've seen, I have a mild aversion to Importan
|
| + implements WebsitePermissionsFetcher.WebsitePermissionsCallback { |
| + @Override |
| + public void onWebsitePermissionsAvailable(Map<String, Set<Website>> sitesByOrigin, |
| + Map<String, Set<Website>> sitesByHost, List<String> importantOrigins) { |
| + // First we scan origins to get settings from there. |
| + Set<Website> sites = new HashSet<>(); |
| + for (Map.Entry<String, Set<Website>> element : sitesByOrigin.entrySet()) { |
| + for (Website site : element.getValue()) { |
| + sites.add(site); |
| + } |
| + } |
| + // Next we add sites that are only accessible by host name. |
| + for (Map.Entry<String, Set<Website>> element : sitesByHost.entrySet()) { |
| + for (Website site : element.getValue()) { |
| + if (!sites.contains(site)) { |
| + sites.add(site); |
| + } |
| + } |
| + } |
| + Set<String> importantSites = new HashSet<String>(); |
| + importantSites.addAll(importantOrigins); |
| + final int[] numLeft = new int[1]; |
|
Finnur
2016/03/03 14:15:43
Same here. Why is this an array, am I missing some
dmurph
2016/04/26 21:43:12
So, we need to make the argument final so that we
Finnur
2016/04/27 13:49:15
I don't have a problem with this being |final|. I'
dmurph
2016/04/27 20:36:47
Because then I couldn't modify it (as it's final)
|
| + numLeft[0] = 0; |
| + for (Website site : sites) { |
| + if (!importantSites.contains(site.getLocalStorageInfo().getOrigin())) { |
| + numLeft[0]++; |
| + site.clearAllStoredData(new StoredDataClearedCallback() { |
| + @Override |
| + public void onStoredDataCleared() { |
| + numLeft[0]--; |
| + if (numLeft[0] == 0) { |
| + onSiteStorageCleared(); |
| + } |
| + } |
| + }); |
| + } |
| + } |
| + } |
| + } |
| +} |