| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.tabmodel; | 5 package org.chromium.chrome.browser.tabmodel; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.SharedPreferences; | 8 import android.content.SharedPreferences; |
| 9 import android.os.AsyncTask; | 9 import android.os.AsyncTask; |
| 10 import android.os.StrictMode; | 10 import android.os.StrictMode; |
| 11 import android.support.annotation.WorkerThread; | 11 import android.support.annotation.WorkerThread; |
| 12 import android.util.Pair; | 12 import android.util.Pair; |
| 13 import android.util.SparseBooleanArray; | 13 import android.util.SparseBooleanArray; |
| 14 | 14 |
| 15 import org.chromium.base.Callback; | 15 import org.chromium.base.Callback; |
| 16 import org.chromium.base.ContextUtils; | 16 import org.chromium.base.ContextUtils; |
| 17 import org.chromium.base.Log; | 17 import org.chromium.base.Log; |
| 18 import org.chromium.base.PathUtils; | 18 import org.chromium.base.PathUtils; |
| 19 import org.chromium.base.StreamUtil; | 19 import org.chromium.base.StreamUtil; |
| 20 import org.chromium.base.ThreadUtils; | 20 import org.chromium.base.ThreadUtils; |
| 21 import org.chromium.base.VisibleForTesting; | 21 import org.chromium.base.VisibleForTesting; |
| 22 import org.chromium.base.library_loader.LibraryLoader; |
| 23 import org.chromium.base.metrics.RecordHistogram; |
| 22 import org.chromium.chrome.browser.TabState; | 24 import org.chromium.chrome.browser.TabState; |
| 23 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; | 25 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; |
| 24 | 26 |
| 25 import java.io.BufferedInputStream; | 27 import java.io.BufferedInputStream; |
| 26 import java.io.DataInputStream; | 28 import java.io.DataInputStream; |
| 27 import java.io.File; | 29 import java.io.File; |
| 28 import java.io.FileInputStream; | 30 import java.io.FileInputStream; |
| 29 import java.util.ArrayList; | 31 import java.util.ArrayList; |
| 30 import java.util.List; | 32 import java.util.List; |
| 31 import java.util.concurrent.ExecutionException; | 33 import java.util.concurrent.ExecutionException; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 211 } |
| 210 setLegacyFileMigrationPref(); | 212 setLegacyFileMigrationPref(); |
| 211 } | 213 } |
| 212 | 214 |
| 213 /** | 215 /** |
| 214 * Upgrades users from an older version of Chrome when the state files for m
ulti-instance | 216 * Upgrades users from an older version of Chrome when the state files for m
ulti-instance |
| 215 * were each kept in separate subdirectories. | 217 * were each kept in separate subdirectories. |
| 216 */ | 218 */ |
| 217 @WorkerThread | 219 @WorkerThread |
| 218 private void performMultiInstanceMigration() { | 220 private void performMultiInstanceMigration() { |
| 219 // 1. Rename tab metadata file for tab directory "0". | 221 // 0. Do not rename the old metadata file if the new metadata file alrea
dy exists. This |
| 222 // should not happen, but if it does and the metadata file is overwri
tten then users |
| 223 // may lose tabs. See crbug.com/649384. |
| 220 File stateDir = getOrCreateStateDirectory(); | 224 File stateDir = getOrCreateStateDirectory(); |
| 221 File metadataFile = new File(stateDir, LEGACY_SAVED_STATE_FILE); | 225 File newMetadataFile = new File(stateDir, getStateFileName()); |
| 222 if (metadataFile.exists()) { | 226 File oldMetadataFile = new File(stateDir, LEGACY_SAVED_STATE_FILE); |
| 223 if (!metadataFile.renameTo(new File(stateDir, getStateFileName())))
{ | 227 if (newMetadataFile.exists()) { |
| 224 Log.e(TAG, "Failed to rename file: " + metadataFile); | 228 Log.e(TAG, "New metadata file already exists"); |
| 229 if (LibraryLoader.isInitialized()) { |
| 230 RecordHistogram.recordBooleanHistogram( |
| 231 "Android.MultiInstanceMigration.NewMetadataFileExists",
true); |
| 232 } |
| 233 } else if (oldMetadataFile.exists()) { |
| 234 // 1. Rename tab metadata file for tab directory "0". |
| 235 if (!oldMetadataFile.renameTo(newMetadataFile)) { |
| 236 Log.e(TAG, "Failed to rename file: " + oldMetadataFile); |
| 237 |
| 238 if (LibraryLoader.isInitialized()) { |
| 239 RecordHistogram.recordBooleanHistogram( |
| 240 "Android.MultiInstanceMigration.FailedToRenameMetada
taFile", true); |
| 241 } |
| 225 } | 242 } |
| 226 } | 243 } |
| 227 | 244 |
| 228 // 2. Move files from other state directories. | 245 // 2. Move files from other state directories. |
| 229 for (int i = TabModelSelectorImpl.CUSTOM_TABS_SELECTOR_INDEX; | 246 for (int i = TabModelSelectorImpl.CUSTOM_TABS_SELECTOR_INDEX; |
| 230 i < TabWindowManager.MAX_SIMULTANEOUS_SELECTORS; i++) { | 247 i < TabWindowManager.MAX_SIMULTANEOUS_SELECTORS; i++) { |
| 231 // Skip the directory we're migrating to. | 248 // Skip the directory we're migrating to. |
| 232 if (i == 0) continue; | 249 if (i == 0) continue; |
| 233 | 250 |
| 234 File otherStateDir = new File( | 251 File otherStateDir = new File( |
| 235 TabPersistentStore.getOrCreateBaseStateDirectory(), Integer.
toString(i)); | 252 TabPersistentStore.getOrCreateBaseStateDirectory(), Integer.
toString(i)); |
| 236 if (otherStateDir == null || !otherStateDir.exists()) continue; | 253 if (otherStateDir == null || !otherStateDir.exists()) continue; |
| 237 | 254 |
| 238 // Rename tab state file. | 255 // Rename tab state file. |
| 239 metadataFile = new File(otherStateDir, LEGACY_SAVED_STATE_FILE); | 256 oldMetadataFile = new File(otherStateDir, LEGACY_SAVED_STATE_FILE); |
| 240 if (metadataFile.exists()) { | 257 if (oldMetadataFile.exists()) { |
| 241 if (!metadataFile.renameTo(new File(stateDir, getStateFileName(i
)))) { | 258 if (!oldMetadataFile.renameTo(new File(stateDir, getStateFileNam
e(i)))) { |
| 242 Log.e(TAG, "Failed to rename file: " + metadataFile); | 259 Log.e(TAG, "Failed to rename file: " + oldMetadataFile); |
| 243 } | 260 } |
| 244 } | 261 } |
| 245 | 262 |
| 246 // Rename tab files. | 263 // Rename tab files. |
| 247 File[] files = otherStateDir.listFiles(); | 264 File[] files = otherStateDir.listFiles(); |
| 248 if (files != null) { | 265 if (files != null) { |
| 249 for (File file : files) { | 266 for (File file : files) { |
| 250 if (TabState.parseInfoFromFilename(file.getName()) != null)
{ | 267 if (TabState.parseInfoFromFilename(file.getName()) != null)
{ |
| 251 // Custom tabs does not currently use tab files. Delete
them rather than | 268 // Custom tabs does not currently use tab files. Delete
them rather than |
| 252 // migrating. | 269 // migrating. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } catch (Exception e) { | 443 } catch (Exception e) { |
| 427 Log.e(TAG, "Unable to read state for " + metadataFile.ge
tName() + ": " + e); | 444 Log.e(TAG, "Unable to read state for " + metadataFile.ge
tName() + ": " + e); |
| 428 } finally { | 445 } finally { |
| 429 StreamUtil.closeQuietly(stream); | 446 StreamUtil.closeQuietly(stream); |
| 430 } | 447 } |
| 431 } | 448 } |
| 432 } | 449 } |
| 433 } | 450 } |
| 434 } | 451 } |
| 435 } | 452 } |
| OLD | NEW |