Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(887)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java

Issue 2292083004: Revert of Add tab persistence support for CustomTabs. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java
deleted file mode 100644
index f3ea43ad3acffa0dd3f6ac86e56f9347f28aee8f..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java
+++ /dev/null
@@ -1,387 +0,0 @@
-// Copyright 2016 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.customtabs;
-
-import android.app.Activity;
-import android.os.AsyncTask;
-import android.os.StrictMode;
-import android.util.Pair;
-import android.util.SparseBooleanArray;
-
-import org.chromium.base.ApiCompatibilityUtils;
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.Callback;
-import org.chromium.base.Log;
-import org.chromium.base.StreamUtil;
-import org.chromium.base.ThreadUtils;
-import org.chromium.chrome.browser.TabState;
-import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
-import org.chromium.chrome.browser.tabmodel.TabModel;
-import org.chromium.chrome.browser.tabmodel.TabModelSelector;
-import org.chromium.chrome.browser.tabmodel.TabPersistencePolicy;
-import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-
-import javax.annotation.Nullable;
-
-/**
- * Handles the Custom Tab specific behaviors of tab persistence.
- */
-public class CustomTabTabPersistencePolicy implements TabPersistencePolicy {
-
- static final String SAVED_STATE_DIRECTORY = "custom_tabs";
-
- /** Threshold where old state files should be deleted (30 days). */
- protected static final long STATE_EXPIRY_THRESHOLD = 30L * 24 * 60 * 60 * 1000;
-
- /** Maximum number of state files before we should start deleting old ones. */
- protected static final int MAXIMUM_STATE_FILES = 30;
-
- private static final String TAG = "tabmodel";
-
- /** Prevents two state directories from getting created simultaneously. */
- private static final Object DIR_CREATION_LOCK = new Object();
-
- /**
- * Prevents two clean up tasks from getting created simultaneously. Also protects against
- * incorrectly interleaving create/run/cancel on the task.
- */
- private static final Object CLEAN_UP_TASK_LOCK = new Object();
-
- private static File sStateDirectory;
- private static AsyncTask<Void, Void, Void> sCleanupTask;
-
- /**
- * The folder where the state should be saved to.
- * @return A file representing the directory that contains TabModelSelector states.
- */
- public static File getOrCreateCustomTabModeStateDirectory() {
- synchronized (DIR_CREATION_LOCK) {
- if (sStateDirectory == null) {
- sStateDirectory = new File(
- TabPersistentStore.getOrCreateBaseStateDirectory(), SAVED_STATE_DIRECTORY);
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- StrictMode.allowThreadDiskWrites();
- try {
- if (!sStateDirectory.exists() && !sStateDirectory.mkdirs()) {
- Log.e(TAG, "Failed to create state folder: " + sStateDirectory);
- }
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
- }
- }
- return sStateDirectory;
- }
-
- private final int mTaskId;
- private final boolean mShouldRestore;
-
- private AsyncTask<Void, Void, Void> mInitializationTask;
- private boolean mDestroyed;
-
- /**
- * Constructs a persistence policy for a given Custom Tab.
- *
- * @param taskId The task ID that the owning Custom Tab is in.
- * @param shouldRestore Whether an attempt to restore tab state information should be done on
- * startup.
- */
- public CustomTabTabPersistencePolicy(int taskId, boolean shouldRestore) {
- mTaskId = taskId;
- mShouldRestore = shouldRestore;
- }
-
- @Override
- public File getOrCreateStateDirectory() {
- return getOrCreateCustomTabModeStateDirectory();
- }
-
- @Override
- public String getStateFileName() {
- return TabPersistentStore.getStateFileName(Integer.toString(mTaskId));
- }
-
- @Override
- @Nullable
- public String getStateToBeMergedFileName() {
- return null;
- }
-
- @Override
- public boolean performInitialization(Executor executor) {
- mInitializationTask = new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- File stateDir = getOrCreateStateDirectory();
- File metadataFile = new File(stateDir, getStateFileName());
- if (metadataFile.exists()) {
- if (mShouldRestore) {
- if (!metadataFile.setLastModified(System.currentTimeMillis())) {
- Log.e(TAG, "Unable to update last modified time: " + metadataFile);
- }
- } else {
- if (!metadataFile.delete()) {
- Log.e(TAG, "Failed to delete file: " + metadataFile);
- }
- }
- }
- return null;
- }
- }.executeOnExecutor(executor);
-
- return true;
- }
-
- @Override
- public void waitForInitializationToFinish() {
- if (mInitializationTask == null) return;
- try {
- mInitializationTask.get();
- } catch (InterruptedException | ExecutionException e) {
- // Ignore and proceed.
- }
- }
-
- @Override
- public boolean isMergeInProgress() {
- return false;
- }
-
- @Override
- public void setMergeInProgress(boolean isStarted) {
- assert false : "Merge not supported in Custom Tabs";
- }
-
- @Override
- public void cancelCleanupInProgress() {
- synchronized (CLEAN_UP_TASK_LOCK) {
- if (sCleanupTask != null) sCleanupTask.cancel(true);
- }
- }
-
- @Override
- public void cleanupUnusedFiles(Callback<List<String>> filesToDelete) {
- synchronized (CLEAN_UP_TASK_LOCK) {
- if (sCleanupTask != null) sCleanupTask.cancel(true);
- sCleanupTask = new CleanUpTabStateDataTask(filesToDelete);
- sCleanupTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
- }
-
- @Override
- public void setTabContentManager(TabContentManager cache) {
- }
-
- @Override
- public void destroy() {
- mDestroyed = true;
- }
-
- /**
- * Given a list of metadata files, determine which are applicable for deletion based on the
- * deletion strategy of Custom Tabs.
- *
- * @param currentTimeMillis The current time in milliseconds
- * ({@link System#currentTimeMillis()}.
- * @param allMetadataFiles The complete list of all metadata files to check.
- * @return The list of metadata files that are applicable for deletion.
- */
- protected static List<File> getMetadataFilesForDeletion(
- long currentTimeMillis, List<File> allMetadataFiles) {
- Collections.sort(allMetadataFiles, new Comparator<File>() {
- @Override
- public int compare(File lhs, File rhs) {
- long lhsModifiedTime = lhs.lastModified();
- long rhsModifiedTime = rhs.lastModified();
-
- // Sort such that older files (those with an lower timestamp number) are at the
- // end of the sorted listed.
- return ApiCompatibilityUtils.compareLong(rhsModifiedTime, lhsModifiedTime);
- }
- });
-
- List<File> stateFilesApplicableForDeletion = new ArrayList<File>();
- for (int i = 0; i < allMetadataFiles.size(); i++) {
- File file = allMetadataFiles.get(i);
- long fileAge = currentTimeMillis - file.lastModified();
- if (i >= MAXIMUM_STATE_FILES || fileAge >= STATE_EXPIRY_THRESHOLD) {
- stateFilesApplicableForDeletion.add(file);
- }
- }
- return stateFilesApplicableForDeletion;
- }
-
- /**
- * Get all current Tab IDs used by the specified activity.
- *
- * @param activity The activity whose tab IDs are to be collected from.
- * @param tabIds Where the tab IDs should be added to.
- */
- private static void getAllTabIdsForActivity(CustomTabActivity activity, Set<Integer> tabIds) {
- if (activity == null) return;
- TabModelSelector selector = activity.getTabModelSelector();
- if (selector == null) return;
- List<TabModel> models = selector.getModels();
- for (int i = 0; i < models.size(); i++) {
- TabModel model = models.get(i);
- for (int j = 0; j < model.getCount(); j++) {
- tabIds.add(model.getTabAt(j).getId());
- }
- }
- }
-
- /**
- * Gathers all of the tab IDs and task IDs for all currently live Custom Tabs.
- *
- * @param liveTabIds Where tab IDs will be added.
- * @param liveTaskIds Where task IDs will be added.
- */
- protected static void getAllLiveTabAndTaskIds(
- Set<Integer> liveTabIds, Set<Integer> liveTaskIds) {
- ThreadUtils.assertOnUiThread();
-
- List<WeakReference<Activity>> activities = ApplicationStatus.getRunningActivities();
- for (int i = 0; i < activities.size(); i++) {
- Activity activity = activities.get(i).get();
- if (activity == null) continue;
- if (!(activity instanceof CustomTabActivity)) continue;
- getAllTabIdsForActivity((CustomTabActivity) activity, liveTabIds);
- liveTaskIds.add(activity.getTaskId());
- }
- }
-
- private class CleanUpTabStateDataTask extends AsyncTask<Void, Void, Void> {
- private final Callback<List<String>> mFilesToDeleteCallback;
-
- private Set<Integer> mUnreferencedTabIds;
- private List<File> mDeletableMetadataFiles;
- private Map<File, SparseBooleanArray> mTabIdsByMetadataFile;
-
- CleanUpTabStateDataTask(Callback<List<String>> filesToDelete) {
- mFilesToDeleteCallback = filesToDelete;
- }
-
- @Override
- protected Void doInBackground(Void... voids) {
- if (mDestroyed) return null;
-
- mTabIdsByMetadataFile = new HashMap<>();
- mUnreferencedTabIds = new HashSet<>();
-
- File[] stateFiles = getOrCreateStateDirectory().listFiles();
- if (stateFiles == null) return null;
-
- Set<Integer> allTabIds = new HashSet<>();
- Set<Integer> allReferencedTabIds = new HashSet<>();
- List<File> metadataFiles = new ArrayList<>();
- for (File file : stateFiles) {
- if (TabPersistentStore.isStateFile(file.getName())) {
- metadataFiles.add(file);
-
- SparseBooleanArray tabIds = new SparseBooleanArray();
- mTabIdsByMetadataFile.put(file, tabIds);
- getTabsFromStateFile(tabIds, file);
- for (int i = 0; i < tabIds.size(); i++) {
- allReferencedTabIds.add(tabIds.keyAt(i));
- }
- continue;
- }
-
- Pair<Integer, Boolean> tabInfo = TabState.parseInfoFromFilename(file.getName());
- if (tabInfo == null) continue;
- allTabIds.add(tabInfo.first);
- }
-
- mUnreferencedTabIds.addAll(allTabIds);
- mUnreferencedTabIds.removeAll(allReferencedTabIds);
-
- mDeletableMetadataFiles = getMetadataFilesForDeletion(
- System.currentTimeMillis(), metadataFiles);
- return null;
- }
-
- @Override
- protected void onPostExecute(Void unused) {
- List<String> filesToDelete = new ArrayList<>();
- if (mDestroyed) {
- mFilesToDeleteCallback.onResult(filesToDelete);
- return;
- }
-
- if (mUnreferencedTabIds.isEmpty() && mDeletableMetadataFiles.isEmpty()) {
- mFilesToDeleteCallback.onResult(filesToDelete);
- return;
- }
-
- Set<Integer> liveTabIds = new HashSet<>();
- Set<Integer> liveTaskIds = new HashSet<>();
- getAllLiveTabAndTaskIds(liveTabIds, liveTaskIds);
-
- for (Integer unreferencedTabId : mUnreferencedTabIds) {
- // Ignore tabs that are referenced by live activities as they might not have been
- // able to write out their state yet.
- if (liveTabIds.contains(unreferencedTabId)) continue;
-
- // The tab state is not referenced by any current activities or any metadata files,
- // so mark it for deletion.
- filesToDelete.add(TabState.getTabStateFilename(unreferencedTabId, false));
- }
-
- for (int i = 0; i < mDeletableMetadataFiles.size(); i++) {
- File metadataFile = mDeletableMetadataFiles.get(i);
- String id = TabPersistentStore.getStateFileUniqueId(metadataFile.getName());
- try {
- int taskId = Integer.parseInt(id);
-
- // Ignore the metadata file if it belongs to a currently live CustomTabActivity.
- if (liveTaskIds.contains(taskId)) continue;
-
- filesToDelete.add(metadataFile.getName());
-
- SparseBooleanArray unusedTabIds = mTabIdsByMetadataFile.get(metadataFile);
- if (unusedTabIds == null) continue;
- for (int j = 0; j < unusedTabIds.size(); j++) {
- filesToDelete.add(TabState.getTabStateFilename(
- unusedTabIds.keyAt(j), false));
- }
- } catch (NumberFormatException ex) {
- assert false : "Unexpected tab metadata file found: " + metadataFile.getName();
- continue;
- }
- }
-
- mFilesToDeleteCallback.onResult(filesToDelete);
- }
-
- private void getTabsFromStateFile(SparseBooleanArray tabIds, File metadataFile) {
- DataInputStream stream = null;
- try {
- stream = new DataInputStream(
- new BufferedInputStream(new FileInputStream(metadataFile)));
- TabPersistentStore.readSavedStateFile(stream, null, tabIds, false);
- } catch (Exception e) {
- Log.e(TAG, "Unable to read state for " + metadataFile.getName() + ": " + e);
- } finally {
- StreamUtil.closeQuietly(stream);
- }
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698