blob: 7268c09bb11491369e4ce90aa616307d50b69e89 [file] [log] [blame]
// Copyright 2020 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.tabpersistence;
import android.content.Context;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.StrictModeContext;
import java.io.File;
/**
* Manages the directory where tab state is saved.
*
* TODO(crbug.com/1097396): Deduplicate code between tabbed mode and custom tabs.
*/
public class TabStateDirectory {
private static final String TAG = "tabpersistence";
/** The name of the base directory where the state is saved. */
private static final String BASE_STATE_FOLDER = "tabs";
/** The name of the directory where the state for tabbed mode is saved. */
private static final String TABBED_MODE_DIRECTORY = "0";
/** The name of the directory where the state for custom tabs is saved. */
public static final String CUSTOM_TABS_DIRECTORY = "custom_tabs";
/** Prevents two state directories from getting created simultaneously. */
private static final Object TABBED_MODE_DIR_CREATION_LOCK = new Object();
/** Prevents two state directories from getting created simultaneously. */
private static final Object CUSTOM_TABS_DIR_CREATION_LOCK = new Object();
private static File sTabbedModeStateDirectory;
private static File sCustomTabsStateDirectory;
/**
* The folder where the state should be saved to.
* @return A file representing the directory that contains TabModelSelector states.
*/
public static File getOrCreateTabbedModeStateDirectory() {
synchronized (TABBED_MODE_DIR_CREATION_LOCK) {
if (sTabbedModeStateDirectory == null) {
sTabbedModeStateDirectory =
new File(getOrCreateBaseStateDirectory(), TABBED_MODE_DIRECTORY);
try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
if (!sTabbedModeStateDirectory.exists()
&& !sTabbedModeStateDirectory.mkdirs()) {
Log.e(TAG, "Failed to create state folder: " + sTabbedModeStateDirectory);
}
}
}
}
return sTabbedModeStateDirectory;
}
/**
* The folder where the state should be saved to.
* @return A file representing the directory that contains TabModelSelector states.
*/
public static File getOrCreateCustomTabModeStateDirectory() {
synchronized (CUSTOM_TABS_DIR_CREATION_LOCK) {
if (sCustomTabsStateDirectory == null) {
sCustomTabsStateDirectory =
new File(getOrCreateBaseStateDirectory(), CUSTOM_TABS_DIRECTORY);
try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
if (!sCustomTabsStateDirectory.exists()
&& !sCustomTabsStateDirectory.mkdirs()) {
Log.e(TAG, "Failed to create state folder: " + sCustomTabsStateDirectory);
}
}
}
}
return sCustomTabsStateDirectory;
}
private static class BaseStateDirectoryHolder {
// Not final for tests.
private static File sDirectory;
static {
sDirectory = ContextUtils.getApplicationContext().getDir(
BASE_STATE_FOLDER, Context.MODE_PRIVATE);
}
}
/**
* Directory containing all data for TabModels. Each subdirectory stores info about different
* TabModelSelectors, including metadata about each TabModel and TabStates for each of their
* tabs.
*
* @return The parent state directory.
*/
public static File getOrCreateBaseStateDirectory() {
return BaseStateDirectoryHolder.sDirectory;
}
/**
* Sets where the base state directory is in tests.
*/
@VisibleForTesting
public static void setBaseStateDirectoryForTests(File directory) {
BaseStateDirectoryHolder.sDirectory = directory;
}
@VisibleForTesting
public static void resetTabbedModeStateDirectoryForTesting() {
sTabbedModeStateDirectory = null;
}
}