1 /* 2 * Copyright 2022 Google LLC 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 package com.google.android.libraries.mobiledatadownload.internal; 17 18 import android.content.Context; 19 import android.content.SharedPreferences; 20 import com.google.android.libraries.mobiledatadownload.SilentFeedback; 21 import com.google.android.libraries.mobiledatadownload.internal.logging.LogUtil; 22 23 /** This class holds the migrations status of any migrations currently going on in MDD. */ 24 public class Migrations { 25 26 private static final String TAG = "Migrations"; 27 28 static final String MDD_MIGRATIONS = "gms_icing_mdd_migrations"; 29 30 static final String PREFS_KEY_MIGRATED_TO_NEW_FILE_KEY = "migrated_to_new_file_key"; 31 32 static final String MDD_FILE_KEY_VERSION = "mdd_file_key_version"; 33 isMigratedToNewFileKey(Context context)34 static boolean isMigratedToNewFileKey(Context context) { 35 SharedPreferences migrationPrefs = 36 context.getSharedPreferences(MDD_MIGRATIONS, Context.MODE_PRIVATE); 37 return migrationPrefs.getBoolean(PREFS_KEY_MIGRATED_TO_NEW_FILE_KEY, false); 38 } 39 40 // TODO(b/124072754): Change to package private once all code is refactored. setMigratedToNewFileKey(Context context, boolean value)41 public static void setMigratedToNewFileKey(Context context, boolean value) { 42 LogUtil.d("%s: Setting migration to new file key to %s", TAG, value); 43 SharedPreferences migrationPrefs = 44 context.getSharedPreferences(MDD_MIGRATIONS, Context.MODE_PRIVATE); 45 migrationPrefs.edit().putBoolean(PREFS_KEY_MIGRATED_TO_NEW_FILE_KEY, value).commit(); 46 } 47 48 /** Enum for FileKey Migration, NEW_FILE_KEY is the base version. */ 49 public enum FileKeyVersion { 50 NEW_FILE_KEY(0), 51 ADD_DOWNLOAD_TRANSFORM(1), 52 53 // Remove byte size and url from the key, and only de-dup files on checksum of the file. 54 USE_CHECKSUM_ONLY(2); 55 56 public final int value; 57 FileKeyVersion(int value)58 FileKeyVersion(int value) { 59 this.value = value; 60 } 61 getVersion(int ver)62 static FileKeyVersion getVersion(int ver) { 63 switch (ver) { 64 case 0: 65 return NEW_FILE_KEY; 66 case 1: 67 return ADD_DOWNLOAD_TRANSFORM; 68 case 2: 69 return USE_CHECKSUM_ONLY; 70 default: 71 throw new IllegalArgumentException("Unknown MDD FileKey version:" + ver); 72 } 73 } 74 } 75 76 // TODO(b/124072754): Change to package private once all code is refactored. getCurrentVersion(Context context, SilentFeedback silentFeedback)77 public static FileKeyVersion getCurrentVersion(Context context, SilentFeedback silentFeedback) { 78 SharedPreferences migrationPrefs = 79 context.getSharedPreferences(MDD_MIGRATIONS, Context.MODE_PRIVATE); 80 // Make NEW_FILE_KEY the default, it is the base version. Without NEW_FILE_KEY migration, the 81 // version migration won't happen 82 int fileKeyVersion = 83 migrationPrefs.getInt(MDD_FILE_KEY_VERSION, FileKeyVersion.NEW_FILE_KEY.value); 84 try { 85 return FileKeyVersion.getVersion(fileKeyVersion); 86 } catch (IllegalArgumentException ex) { 87 // Clear the corrupted file key metadata, return the default file key version. 88 silentFeedback.send( 89 ex, "FileKey version metadata corrupted with unknown version: %d", fileKeyVersion); 90 clear(context); 91 return FileKeyVersion.USE_CHECKSUM_ONLY; 92 } 93 } 94 setCurrentVersion(Context context, FileKeyVersion newVersion)95 public static boolean setCurrentVersion(Context context, FileKeyVersion newVersion) { 96 LogUtil.d("%s: Setting FileKeyVersion to %s", TAG, newVersion.name()); 97 SharedPreferences migrationPrefs = 98 context.getSharedPreferences(MDD_MIGRATIONS, Context.MODE_PRIVATE); 99 return migrationPrefs.edit().putInt(MDD_FILE_KEY_VERSION, newVersion.value).commit(); 100 } 101 102 // TODO(b/124072754): Change to package private once all code is refactored. clear(Context context)103 public static void clear(Context context) { 104 SharedPreferences migrationPrefs = 105 context.getSharedPreferences(MDD_MIGRATIONS, Context.MODE_PRIVATE); 106 migrationPrefs.edit().clear().commit(); 107 } 108 } 109