1 /* 2 * Copyright 2022 The Android Open Source Project 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 17 package androidx.appsearch.localstorage.visibilitystore; 18 19 import androidx.annotation.RestrictTo; 20 import androidx.annotation.VisibleForTesting; 21 import androidx.appsearch.app.AppSearchResult; 22 import androidx.appsearch.app.InternalVisibilityConfig; 23 import androidx.appsearch.app.PackageIdentifier; 24 import androidx.appsearch.app.SetSchemaRequest; 25 import androidx.appsearch.exceptions.AppSearchException; 26 import androidx.appsearch.localstorage.AppSearchImpl; 27 import androidx.appsearch.localstorage.util.PrefixUtil; 28 import androidx.collection.ArraySet; 29 30 import org.jspecify.annotations.NonNull; 31 32 import java.util.ArrayList; 33 import java.util.Collections; 34 import java.util.List; 35 import java.util.Set; 36 37 /** 38 * The helper class to store Visibility Document information of version 1 and handle the upgrade to 39 * latest version 40 * 41 * @exportToFramework:hide 42 */ 43 @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 44 public class VisibilityStoreMigrationHelperFromV1 { VisibilityStoreMigrationHelperFromV1()45 private VisibilityStoreMigrationHelperFromV1() {} 46 47 /** Enum in {@link androidx.appsearch.app.SetSchemaRequest} AppSearch supported role. */ 48 @VisibleForTesting 49 static final int DEPRECATED_ROLE_HOME = 1; 50 51 /** Enum in {@link androidx.appsearch.app.SetSchemaRequest} AppSearch supported role. */ 52 @VisibleForTesting 53 static final int DEPRECATED_ROLE_ASSISTANT = 2; 54 55 /** Reads all stored deprecated Visibility Document in version 0 from icing. */ getVisibilityDocumentsInVersion1( @onNull AppSearchImpl appSearchImpl)56 static List<VisibilityDocumentV1> getVisibilityDocumentsInVersion1( 57 @NonNull AppSearchImpl appSearchImpl) throws AppSearchException { 58 List<String> allPrefixedSchemaTypes = appSearchImpl.getAllPrefixedSchemaTypes(); 59 List<VisibilityDocumentV1> visibilityDocumentV1s = 60 new ArrayList<>(allPrefixedSchemaTypes.size()); 61 for (int i = 0; i < allPrefixedSchemaTypes.size(); i++) { 62 String packageName = PrefixUtil.getPackageName(allPrefixedSchemaTypes.get(i)); 63 if (packageName.equals(VisibilityStore.VISIBILITY_PACKAGE_NAME)) { 64 continue; // Our own package. Skip. 65 } 66 try { 67 // Note: We use the prefixed schema type as ids 68 visibilityDocumentV1s.add(new VisibilityDocumentV1(appSearchImpl.getDocument( 69 VisibilityStore.VISIBILITY_PACKAGE_NAME, 70 VisibilityStore.DOCUMENT_VISIBILITY_DATABASE_NAME, 71 VisibilityToDocumentConverter.VISIBILITY_DOCUMENT_NAMESPACE, 72 allPrefixedSchemaTypes.get(i), 73 /*typePropertyPaths=*/ Collections.emptyMap()))); 74 } catch (AppSearchException e) { 75 if (e.getResultCode() == AppSearchResult.RESULT_NOT_FOUND) { 76 // TODO(b/172068212): This indicates some desync error. We were expecting a 77 // document, but didn't find one. Should probably reset AppSearch instead 78 // of ignoring it. 79 continue; 80 } 81 // Otherwise, this is some other error we should pass up. 82 throw e; 83 } 84 } 85 return visibilityDocumentV1s; 86 } 87 88 /** 89 * Converts the given list of deprecated Visibility Documents into a Map of {@code 90 * <PrefixedSchemaType, VisibilityDocument.Builder of the latest version>}. 91 * 92 * @param visibilityDocumentV1s The deprecated Visibility Document we found. 93 */ toVisibilityDocumentsV2( @onNull List<VisibilityDocumentV1> visibilityDocumentV1s)94 static @NonNull List<InternalVisibilityConfig> toVisibilityDocumentsV2( 95 @NonNull List<VisibilityDocumentV1> visibilityDocumentV1s) { 96 List<InternalVisibilityConfig> latestVisibilityDocuments = 97 new ArrayList<>(visibilityDocumentV1s.size()); 98 for (int i = 0; i < visibilityDocumentV1s.size(); i++) { 99 VisibilityDocumentV1 visibilityDocumentV1 = visibilityDocumentV1s.get(i); 100 Set<Set<Integer>> visibleToPermissionSets = new ArraySet<>(); 101 Set<Integer> deprecatedVisibleToRoles = visibilityDocumentV1.getVisibleToRoles(); 102 if (deprecatedVisibleToRoles != null) { 103 for (int deprecatedVisibleToRole : deprecatedVisibleToRoles) { 104 Set<Integer> visibleToPermission = new ArraySet<>(); 105 switch (deprecatedVisibleToRole) { 106 case DEPRECATED_ROLE_HOME: 107 visibleToPermission.add(SetSchemaRequest.READ_HOME_APP_SEARCH_DATA); 108 break; 109 case DEPRECATED_ROLE_ASSISTANT: 110 visibleToPermission.add(SetSchemaRequest 111 .READ_ASSISTANT_APP_SEARCH_DATA); 112 break; 113 } 114 visibleToPermissionSets.add(visibleToPermission); 115 } 116 } 117 Set<Integer> deprecatedVisibleToPermissions = 118 visibilityDocumentV1.getVisibleToPermissions(); 119 if (deprecatedVisibleToPermissions != null) { 120 visibleToPermissionSets.add(deprecatedVisibleToPermissions); 121 } 122 123 InternalVisibilityConfig.Builder latestVisibilityDocumentBuilder = 124 new InternalVisibilityConfig.Builder(visibilityDocumentV1.getId()) 125 .setNotDisplayedBySystem(visibilityDocumentV1.isNotDisplayedBySystem()); 126 String[] packageNames = visibilityDocumentV1.getPackageNames(); 127 byte[][] sha256Certs = visibilityDocumentV1.getSha256Certs(); 128 if (packageNames.length == sha256Certs.length) { 129 for (int j = 0; j < packageNames.length; j++) { 130 latestVisibilityDocumentBuilder.addVisibleToPackage( 131 new PackageIdentifier(packageNames[j], sha256Certs[j])); 132 } 133 } 134 for (Set<Integer> visibleToPermissions : visibleToPermissionSets) { 135 latestVisibilityDocumentBuilder.addVisibleToPermissions(visibleToPermissions); 136 } 137 latestVisibilityDocuments.add(latestVisibilityDocumentBuilder.build()); 138 } 139 return latestVisibilityDocuments; 140 } 141 } 142