1 /* 2 * Copyright 2020 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 com.android.server.appsearch.external.localstorage.converter; 18 19 import android.annotation.NonNull; 20 import android.app.appsearch.SearchSpec; 21 22 import com.google.android.icing.proto.ResultSpecProto; 23 import com.google.android.icing.proto.ScoringSpecProto; 24 import com.google.android.icing.proto.SearchSpecProto; 25 import com.google.android.icing.proto.TermMatchType; 26 27 import java.util.Objects; 28 29 /** 30 * Translates a {@link SearchSpec} into icing search protos. 31 * 32 * @hide 33 */ 34 public final class SearchSpecToProtoConverter { SearchSpecToProtoConverter()35 private SearchSpecToProtoConverter() {} 36 37 /** Extracts {@link SearchSpecProto} information from a {@link SearchSpec}. */ 38 @NonNull toSearchSpecProto(@onNull SearchSpec spec)39 public static SearchSpecProto toSearchSpecProto(@NonNull SearchSpec spec) { 40 Objects.requireNonNull(spec); 41 SearchSpecProto.Builder protoBuilder = 42 SearchSpecProto.newBuilder() 43 .addAllSchemaTypeFilters(spec.getFilterSchemas()) 44 .addAllNamespaceFilters(spec.getFilterNamespaces()); 45 46 @SearchSpec.TermMatch int termMatchCode = spec.getTermMatch(); 47 TermMatchType.Code termMatchCodeProto = TermMatchType.Code.forNumber(termMatchCode); 48 if (termMatchCodeProto == null || termMatchCodeProto.equals(TermMatchType.Code.UNKNOWN)) { 49 throw new IllegalArgumentException("Invalid term match type: " + termMatchCode); 50 } 51 protoBuilder.setTermMatchType(termMatchCodeProto); 52 53 return protoBuilder.build(); 54 } 55 56 /** Extracts {@link ResultSpecProto} information from a {@link SearchSpec}. */ 57 @NonNull toResultSpecProto(@onNull SearchSpec spec)58 public static ResultSpecProto toResultSpecProto(@NonNull SearchSpec spec) { 59 Objects.requireNonNull(spec); 60 return ResultSpecProto.newBuilder() 61 .setNumPerPage(spec.getResultCountPerPage()) 62 .setSnippetSpec( 63 ResultSpecProto.SnippetSpecProto.newBuilder() 64 .setNumToSnippet(spec.getSnippetCount()) 65 .setNumMatchesPerProperty(spec.getSnippetCountPerProperty()) 66 .setMaxWindowBytes(spec.getMaxSnippetSize())) 67 .addAllTypePropertyMasks( 68 TypePropertyPathToProtoConverter.toTypePropertyMaskList( 69 spec.getProjections())) 70 .build(); 71 } 72 73 /** Extracts {@link ScoringSpecProto} information from a {@link SearchSpec}. */ 74 @NonNull toScoringSpecProto(@onNull SearchSpec spec)75 public static ScoringSpecProto toScoringSpecProto(@NonNull SearchSpec spec) { 76 Objects.requireNonNull(spec); 77 ScoringSpecProto.Builder protoBuilder = ScoringSpecProto.newBuilder(); 78 79 @SearchSpec.Order int orderCode = spec.getOrder(); 80 ScoringSpecProto.Order.Code orderCodeProto = 81 ScoringSpecProto.Order.Code.forNumber(orderCode); 82 if (orderCodeProto == null) { 83 throw new IllegalArgumentException("Invalid result ranking order: " + orderCode); 84 } 85 protoBuilder 86 .setOrderBy(orderCodeProto) 87 .setRankBy(toProtoRankingStrategy(spec.getRankingStrategy())); 88 89 return protoBuilder.build(); 90 } 91 toProtoRankingStrategy( @earchSpec.RankingStrategy int rankingStrategyCode)92 private static ScoringSpecProto.RankingStrategy.Code toProtoRankingStrategy( 93 @SearchSpec.RankingStrategy int rankingStrategyCode) { 94 switch (rankingStrategyCode) { 95 case SearchSpec.RANKING_STRATEGY_NONE: 96 return ScoringSpecProto.RankingStrategy.Code.NONE; 97 case SearchSpec.RANKING_STRATEGY_DOCUMENT_SCORE: 98 return ScoringSpecProto.RankingStrategy.Code.DOCUMENT_SCORE; 99 case SearchSpec.RANKING_STRATEGY_CREATION_TIMESTAMP: 100 return ScoringSpecProto.RankingStrategy.Code.CREATION_TIMESTAMP; 101 case SearchSpec.RANKING_STRATEGY_RELEVANCE_SCORE: 102 return ScoringSpecProto.RankingStrategy.Code.RELEVANCE_SCORE; 103 case SearchSpec.RANKING_STRATEGY_USAGE_COUNT: 104 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_COUNT; 105 case SearchSpec.RANKING_STRATEGY_USAGE_LAST_USED_TIMESTAMP: 106 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE1_LAST_USED_TIMESTAMP; 107 case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_COUNT: 108 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_COUNT; 109 case SearchSpec.RANKING_STRATEGY_SYSTEM_USAGE_LAST_USED_TIMESTAMP: 110 return ScoringSpecProto.RankingStrategy.Code.USAGE_TYPE2_LAST_USED_TIMESTAMP; 111 default: 112 throw new IllegalArgumentException( 113 "Invalid result ranking strategy: " + rankingStrategyCode); 114 } 115 } 116 } 117