diff options
| author | 2020-02-25 21:15:03 -0800 | |
|---|---|---|
| committer | 2020-02-25 21:15:03 -0800 | |
| commit | 0b291791c80091e3abb12874d72ef7a1740389d6 (patch) | |
| tree | b6b5a0ccd1d957634ff732e2f960d9887e17cc42 | |
| parent | bd463a2b2d19f539d0486a1aabe1dd59e015d959 (diff) | |
DO NOT MERGE: Remove AppSearch from Android R.
Test: presubmit
Bug: 150249538
Change-Id: Idb86be6586ae400552f8ceeca5c667fba8e0c43a
42 files changed, 0 insertions, 4434 deletions
diff --git a/Android.bp b/Android.bp index 11f5c41c73bc..196e6d08a1ab 100644 --- a/Android.bp +++ b/Android.bp @@ -282,7 +282,6 @@ filegroup { filegroup { name: "framework-updatable-sources", srcs: [ - ":framework-appsearch-sources", ":framework-sdkextensions-sources", ":framework-statsd-sources", ":framework-tethering-srcs", @@ -468,7 +467,6 @@ java_library { defaults: ["framework-defaults"], srcs: [":framework-non-updatable-sources"], libs: [ - "framework-appsearch-stubs", "framework-sdkextensions-stubs-systemapi", "framework-statsd-stubs-module_libs_api", "framework-permission-stubs-systemapi", @@ -493,7 +491,6 @@ java_library { visibility: [ "//frameworks/base", // TODO(b/147128803) remove the below lines - "//frameworks/base/apex/appsearch/framework", "//frameworks/base/apex/blobstore/framework", "//frameworks/base/apex/jobscheduler/framework", "//frameworks/base/apex/statsd/service", @@ -516,7 +513,6 @@ java_library { installable: false, // this lib is a build-only library static_libs: [ "framework-minus-apex", - "framework-appsearch", // TODO(b/146218515): should be framework-appsearch-stubs "framework-media-stubs-systemapi", "framework-mediaprovider-stubs-systemapi", "framework-permission-stubs-systemapi", @@ -541,7 +537,6 @@ java_library { "exoplayer2-extractor", "android.hardware.wifi-V1.0-java-constants", ], - libs: ["icing-java-proto-lite"], apex_available: ["//apex_available:platform"], visibility: [ // DO NOT ADD ANY MORE ENTRIES TO THIS LIST @@ -562,7 +557,6 @@ java_library { libs: [ "app-compat-annotations", "ext", - "icing-java-proto-lite", "unsupportedappusage", ], diff --git a/apex/appsearch/Android.bp b/apex/appsearch/Android.bp deleted file mode 100644 index b014fdcb3df3..000000000000 --- a/apex/appsearch/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -apex { - name: "com.android.appsearch", - manifest: "apex_manifest.json", - java_libs: [ - "framework-appsearch", - "service-appsearch", - ], - key: "com.android.appsearch.key", - certificate: ":com.android.appsearch.certificate", -} - -apex_key { - name: "com.android.appsearch.key", - public_key: "com.android.appsearch.avbpubkey", - private_key: "com.android.appsearch.pem", -} - -android_app_certificate { - name: "com.android.appsearch.certificate", - // This will use com.android.appsearch.x509.pem (the cert) and - // com.android.appsearch.pk8 (the private key) - certificate: "com.android.appsearch", -} diff --git a/apex/appsearch/apex_manifest.json b/apex/appsearch/apex_manifest.json deleted file mode 100644 index 39a2d38fa642..000000000000 --- a/apex/appsearch/apex_manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "com.android.appsearch", - "version": 300000000 -} diff --git a/apex/appsearch/com.android.appsearch.avbpubkey b/apex/appsearch/com.android.appsearch.avbpubkey Binary files differdeleted file mode 100644 index 4e5acae9c1e4..000000000000 --- a/apex/appsearch/com.android.appsearch.avbpubkey +++ /dev/null diff --git a/apex/appsearch/com.android.appsearch.pem b/apex/appsearch/com.android.appsearch.pem deleted file mode 100644 index 4ed5945acc86..000000000000 --- a/apex/appsearch/com.android.appsearch.pem +++ /dev/null @@ -1,51 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIJKQIBAAKCAgEAro9f/jvoIsj6ywuRmuUQS8UtprhohJitrovDMfm/T2R/WQvy -AvUxgetyF4XvBPCDRqCsGxXCJMQOn1furrAeTmWbGHPhA0PI1Ys/qtfNMbh9THyn -70I2c4X70CUQ+8/Y8BJ8CAB4iER/s9QtD28QLvM2BBUzRoKUSBGUYNMlYobjgRdK -57V7yg48LkvUIg1fzIW3M5gCgOXa0u1xOadKX3m7tzCboHcXp5anfWX5PH1+okRu -jzdI8OjtUq23qhoRw5Skz0Vbf4a+8t3kT3slF/Q7O8LoRPwpZsvIcvTyCGAqlra7 -2L2LN4H1p+u2ko3r/QmRbJn2eXW07elkyrggXMyn2rTxibQgk53wYfSavMyNd/E7 -+de/uJ60l2aPa+5KUaR8eYwchXEELdqQ+zRgSZ2711xCaY4glEj7DT6VlEEdr26x -akX0ra7e2sVGv1um/dvSyVO5aFKKjVvo4LqhWKWO8yvDMxmDDTNatvWhY2Bhd3RA -0hilYpWQFb9Tv5f4E0tZmfvlddgux7sw++Y/RIimBFoSyf5AezAUIFYYoYvEzytB -muq1/ecNHr+Z2tZMxN88sJVhzRzD9tKUyXhvxOV2Lg9TIeVTWGwQqgSnHWtIe+1p -cw8inPfYEhP4Q+3W/RlPvNdu75x8Nj2aG7bxZnhoQDRDw5ddgma27I+a8esCAwEA -AQKCAgBsNh9I6HRAVBz8kCBkSEnw3rwtFTZdtJQ+lw+bRHpvShqT5g7R/JQDOSTS -JkoE4uBOgT4P0E45Inz6FLW2/yDacqxR3UwJDRVMI/WFACCJCRhLuR8V+BLvTIjN -AJ1lrPSL5rmS8E/IEcakgQyp+6ypnkXHBCl0NXCcuKEl4N7VFE+mb/0UZPHnUSnH -fWR085uGmwH17u7mXxdnGKDPH8DALSPMLUrcj9dPIdqUpwl5kUZWa1uqVphWF98/ -GMe5oE2Q0+3TO+i7xplKz3lAOFPHZLTvmCUK1tMHkZ6ifOwpewwLwB30/5N1BpB1 -126nrWk0xKCtFUixBOHzdnLwJHKSbi7chQU5q39oAJoTfxdmAJlaG0zQHUQZ44MQ -gemzSA7uJbtoAOAZVF1K14xbIpnfidqTB7N3RCmiJE+/Hpkq6PxgPfu5rqocPbPC -t0FgJ4NXNmKOAuJllSlrrHATcUOhF4g5pX7tvOc8X4y7bvfwOmtw5ez3INKMF0q6 -/y0vVCi6N1Z7CTa9eY8feZ1PImk/Fkq4NInSPyx7ZE3pLYmsvuJjliFrWo9TRVae -Dt5vvBKBOpAfhDiHkeXbX7Raj2B6c6adF4no/3SAVlAjIq1iBVjfQWyHAGUoEW1O -u3LdHTIb6gSTLJ4AfryEKrOE+1VMlYt92GwX692KKXMaJjytSQKCAQEA3pYbl8HD -Y++UyEN5VzWAQedT3//GDwpDfgdERe2E4smYrkVNJ2WAG2SqY1A35DIl8be3eHvl -soaL38j48ailfDYY9tI+IlapNh+VOLej+HiOytaPlLhcv2FpSC2qZT4EiU6IBXLo -+l6FrmD/VQXTjvoktzsDB/n1t4Dfa3Ogf+lLf1Jxr94YpEnDh18V5ofj78SplVLm -NrzsHxAafE4Ni2a7dyWjcDYIuL7FTShT+0K4W45tRr+CGxThxu7LEe7zw4Z1IagU -jJNtXjvDD/Zw4UTqI6RwWGZsu6UjPS6LHhOqnWqflWmFRIfMbDkuWvnGZTM9DkVg -kk1+BNi1PECZXwKCAQEAyMOjbVo6XV3lFN0X8TpHyg/z9ar00/SE7WEJHqPSuzYT -rSfU4vDDlaPAwkYvGi9ZKi9VM+R3CyBNxnK9Yq6NurHhhrYcAwdS/hGLT1K2o0Y8 -Pgv7gZCFb+SIwLBhlUG9otGULcBzLneqgVUqyMG6IoCjuC2LRyB71Xc2UMyg6n/f -XpV2RTMb8f+26cgm6nj0SDAfgpr8HV6uNV80c6l1A8gq86nUWwiVAEUdmExSDe7J -shsfWAj8RSErqDXf1BtEdPLJUSIPX5VXkzAXOXIkengwVno0vv0dBN8uraS8iQSG -0JsJLLcw9b5kvnh6FEbE7POsIqKyCZV9VADwO6YW9QKCAQBYQsdwNqoGv6KMgozj -8tgHyfWtVduwbQ50M+dznwpZbzz2pY5Bd/MDabhSpyVyfBwlrAa5ZM+hKc7fDu7/ -zDLKfR0LCjUPIrP4PS/LjK4dQZjFf6zxeOV2EedQcqMlgCEGXTh8iKMvXDm/+sBk -c2n/QNs8OM8r44b2m8h78B6NefGw6/0ekn/M7V72F9M0VWAh3Cauim+09tbePmFy -NvUR+MuPJEKZpSNyNltADCS49izqSSC1tAygNniMjHXDh6/rMS7TCLYVRARTIHlp -o/wAp3X8aiEOPJcTFRlTElihtYSq5POgqHXqxbpek5H5CyALUvT76rCvcsDspQ3A -dZEbAoIBAQCoLEmP5o8Rev/UdEgECB/uwWJIngYsLp3TAv/SrMRvkiL1X3JTD/+m -L9/eXVBDjPoR/khPCcg2h77ex2qhaTrL8wnKAG6CkvYQYb3impTnPIRmLT9nDxrX -2gY78wQrNUCXTRvlH1rcx90KLb+DH9S95ig+tdf/otRYwl27XU5GYQtJfcXuvZth -IiWku8btjpiCh909WHpsV81yY+faI08j9d8U8WQzRYMbEMpzsyrhBO/rxBCDfDNl -7R1W8JooYRb9KAs/bVqXZNBROW2a72RjOp6zMfdRLVHLrPC7AE32MNaFk/khfesD -T5OwgdcxeP6oxo2hDcw5fwHXBlo2fTCpAoIBAQChgjv5AfQ50spqvHy6MNem4tV0 -L0IsxmNLsi8X2a6s4kStwUzOxDA8c/e54XabxQNZ0ERU1q+bgbG7PWC4twDMPR8i -2DO6rgqSK4MjGOTgAoeDuy3mElFQmCLRs04Wf4jh8kPi217WFlYBynh2HmBKbh42 -JmIrLetbKEK13FXRvMkgZcX4OIDrT5TOvev4VZArU8PTRlWv3sqsKAVXjX0clGHf -I0/2kSsr2qq1UY7JrYWZsZ9uqz2ZH0pF19a6O/Cq4uqTYoL+sYzFTSeFmChRjV1g -ancTvTn9lcBqECDMgq5DE/p96Oxg/t8elalR6WDUlysafphVz3nTuyMTh7ka ------END RSA PRIVATE KEY----- diff --git a/apex/appsearch/com.android.appsearch.pk8 b/apex/appsearch/com.android.appsearch.pk8 Binary files differdeleted file mode 100644 index 77e98b20877b..000000000000 --- a/apex/appsearch/com.android.appsearch.pk8 +++ /dev/null diff --git a/apex/appsearch/com.android.appsearch.x509.pem b/apex/appsearch/com.android.appsearch.x509.pem deleted file mode 100644 index e37c4b9fcead..000000000000 --- a/apex/appsearch/com.android.appsearch.x509.pem +++ /dev/null @@ -1,35 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIGETCCA/mgAwIBAgIUGl+MIvpEi0+TWzj0ieh6WtjXmP8wDQYJKoZIhvcNAQEL -BQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH -DA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdBbmRyb2lkMRAwDgYDVQQLDAdBbmRy -b2lkMRIwEAYDVQQDDAlhcHBzZWFyY2gxIjAgBgkqhkiG9w0BCQEWE2FuZHJvaWRA -YW5kcm9pZC5jb20wIBcNMTkxMTIwMjMxNTM1WhgPNDc1NzEwMTYyMzE1MzVaMIGW -MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91 -bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDES -MBAGA1UEAwwJYXBwc2VhcmNoMSIwIAYJKoZIhvcNAQkBFhNhbmRyb2lkQGFuZHJv -aWQuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsyPlp3q3P9Xg -W1WhIwQiF9em9oqaGQ/3dbIxickAy591qcRbpHb4lDTZusRECfqlV215mV+lv5x4 -EhOnId3uPKBAJ/YDtL7zUW6TWL7to7zEnUqSIKTcoQzNF2EiCeGuRhrtgYvAD3HQ -dwr4xrbSADbDArF04A49voLpsmq1fyNgl86VISiMRqoSLJnA6eghlduuOt+nf252 -6WgxDs/JrO/eK70q0+RwmWzVJ/tVr+36a65N4EHhfL4t2hdV0k0XFob7hBn7XWzC -QrSR3jCvE3yAfAr3tq5c19/WWBA7V45nEHzXyAvBUHWubYvDi+vm/yzqU2rQwScC -bzp4zK4CnhBHqb4gHoy0+kfFIwJ1A3GT2pl3ba/NsIYgliMtPQfkDV5PE5RTNcwH -21ewH7vm2+spQv5Z/2TEV2lEHlp2vuAliyn2AT4u1ginr6vtBRFLmpPeziFcfB0y -7h04GctZpX8odz+XI7aMDe47RNu9XyJX0vulntxmlDF76k8Z9DIXg02hY+yc/i7+ -2ztnj1eXL51p+HyhK5VbvJWbKkVaMQijlbuIMYNzMA6L0WHWRc2Cux9UDODMGoiC -w09JpqudCS/95I/F1xaWJ/Kh3vKeQshHAz0hrL7v7wpjmfeXf6NGsWJGy+giCwZj -ABtn9nFQoesgi7M1LeazD5Q/4v4AMaUCAwEAAaNTMFEwHQYDVR0OBBYEFJpHCy2Y -3qaL6cLpE9fe53L61KEEMB8GA1UdIwQYMBaAFJpHCy2Y3qaL6cLpE9fe53L61KEE -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAGDYAcOhbOYcDB2K -WDZka+FCORFFvz4nLQGE7Z9TAn1g7XusM2KbXlb2drIN6CWOFlnKQrUsNsAHrc+s -tl+A1vC3/NfYKKBVuizPx/kHUgz3k/UIJzbzEu/uCJd86idcJoUTqC/qEJAeeQqM -XpsNP1Yg7oyzZT8sFlUAKeDeXJ7fIDXR6nduUQ6uJXkee/5JF3VedHdgHAUsC19/ -KHhyVU3MLDUNBdAmM79+DsdVYi2Pw31jojMu95Zz1MYTRBcgQAiEw5nncr38k6ac -Gy+JffgJR68FzI4QLBSxnDRFD2zXJ09lpP6Sjb1FVcDzk7Bi/EQDLBkrkbeLsk5F -a0xz9VoJ3kM7Cc4R9MXN4ZWuePjdJwgasnHmllsXn45R9odgJgmfzuUwtgNw/XKQ -QcQl7Q9QUrBCqIoHijxscUZCBSmIHVNBBDckRAmSXHeWMRlO3uBR4IA/Jfrt//4f -uc7CNUp+LQ6EzBXJOVFrXRtau6Oj+jM1+fzxKo1uV2+T+GdVEE5jeF/6nB3qna6h -2NmyLqbqeqp2QxgzBWSGy8Ugs6zg4wItJBqOoRLKKFxTJu5OAzJ4fUA+g7WFXNhR -kG56SJ863LZoORKHWE72oXYeIW98Tq0qKLH3NzH5L4tfX8DeBTq+APezHetH1ljA -D0avPy62g0i643bbpwZgezBgRIKL ------END CERTIFICATE----- diff --git a/apex/appsearch/framework/Android.bp b/apex/appsearch/framework/Android.bp deleted file mode 100644 index 24309d7c4e0d..000000000000 --- a/apex/appsearch/framework/Android.bp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -filegroup { - name: "framework-appsearch-sources", - srcs: [ - "java/**/*.java", - "java/**/*.aidl", - ], - path: "java", -} - -java_library { - name: "framework-appsearch", - installable: true, - sdk_version: "core_platform", // TODO(b/146218515) should be core_current - srcs: [":framework-appsearch-sources"], - hostdex: true, // for hiddenapi check - libs: [ - "framework-minus-apex", // TODO(b/146218515) should be framework-system-stubs - ], - static_libs: ["icing-java-proto-lite"], - visibility: [ - // TODO(b/146218515) remove this when framework is built with the stub of appsearch - "//frameworks/base", - "//frameworks/base/apex/appsearch:__subpackages__", - ], - permitted_packages: ["android.app.appsearch"], - apex_available: ["com.android.appsearch"], -} - -metalava_appsearch_docs_args = - "--hide-package com.android.server " + - "--error UnhiddenSystemApi " + - "--hide RequiresPermission " + - "--hide MissingPermission " + - "--hide BroadcastBehavior " + - "--hide HiddenSuperclass " + - "--hide DeprecationMismatch " + - "--hide UnavailableSymbol " + - "--hide SdkConstant " + - "--hide HiddenTypeParameter " + - "--hide Todo --hide Typo " + - "--hide HiddenTypedefConstant " + - "--show-annotation android.annotation.SystemApi " - -droidstubs { - name: "framework-appsearch-stubs-srcs", - srcs: [ - ":framework-annotations", - ":framework-appsearch-sources", - ], - aidl: { - include_dirs: ["frameworks/base/core/java"], - }, - args: metalava_appsearch_docs_args, - sdk_version: "core_current", - libs: ["android_system_stubs_current"], -} - -java_library { - name: "framework-appsearch-stubs", - srcs: [":framework-appsearch-stubs-srcs"], - aidl: { - export_include_dirs: [ - "java", - ], - }, - sdk_version: "core_current", - libs: ["android_system_stubs_current"], - installable: false, -} diff --git a/apex/appsearch/framework/java/android/app/TEST_MAPPING b/apex/appsearch/framework/java/android/app/TEST_MAPPING deleted file mode 100644 index 12188f83a29f..000000000000 --- a/apex/appsearch/framework/java/android/app/TEST_MAPPING +++ /dev/null @@ -1,7 +0,0 @@ -{ - "imports": [ - { - "path": "frameworks/base/apex/appsearch/service/java/com/android/server/appsearch" - } - ] -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java deleted file mode 100644 index 773db9346625..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.ArrayMap; - -import java.util.Collections; -import java.util.Map; - -/** - * Provides access to multiple results from a batch operation accepting multiple inputs. - * - * @param <KeyType> The type of the keys for {@link #getResults} and {@link #getFailures}. - * @param <ValueType> The type of result objects associated with the keys. - * @hide - */ -public class AppSearchBatchResult<KeyType, ValueType> implements Parcelable { - @NonNull private final Map<KeyType, ValueType> mResults; - @NonNull private final Map<KeyType, Throwable> mFailures; - - private AppSearchBatchResult( - @NonNull Map<KeyType, ValueType> results, @NonNull Map<KeyType, Throwable> failures) { - mResults = results; - mFailures = failures; - } - - private AppSearchBatchResult(@NonNull Parcel in) { - mResults = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null)); - mFailures = Collections.unmodifiableMap(in.readHashMap(/*loader=*/ null)); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeMap(mResults); - dest.writeMap(mFailures); - } - - /** Returns {@code true} if this {@link AppSearchBatchResult} has no failures. */ - public boolean isSuccess() { - return mFailures.isEmpty(); - } - - /** - * Returns a {@link Map} of all successful keys mapped to the results they produced. - * - * <p>The values of the {@link Map} may be {@code null}. - */ - @NonNull - public Map<KeyType, ValueType> getResults() { - return mResults; - } - - /** - * Returns a {@link Map} of all failed keys mapped to a {@link Throwable} representing the cause - * of failure. - * - * <p>The values of the {@link Map} may be {@code null}. - */ - @NonNull - public Map<KeyType, Throwable> getFailures() { - return mFailures; - } - - @Override - public int describeContents() { - return 0; - } - - public static final Creator<AppSearchBatchResult> CREATOR = - new Creator<AppSearchBatchResult>() { - @NonNull - @Override - public AppSearchBatchResult createFromParcel(@NonNull Parcel in) { - return new AppSearchBatchResult(in); - } - - @NonNull - @Override - public AppSearchBatchResult[] newArray(int size) { - return new AppSearchBatchResult[size]; - } - }; - - /** - * Creates a new {@link Builder} for this {@link AppSearchBatchResult}. - * @hide - */ - @NonNull - public static <KeyType, ValueType> Builder<KeyType, ValueType> newBuilder() { - return new Builder<>(); - } - - /** - * Builder for {@link AppSearchBatchResult} objects. - * - * @param <KeyType> The type of keys. - * @param <ValueType> The type of result objects associated with the keys. - * @hide - */ - public static final class Builder<KeyType, ValueType> { - @NonNull private final Map<KeyType, ValueType> mResults = new ArrayMap<>(); - @NonNull private final Map<KeyType, Throwable> mFailures = new ArrayMap<>(); - - private Builder() {} - - /** - * Registers that the {@code key} was processed successfully and associates it with - * {@code value}. Any previous mapping for a key, whether success or failure, is deleted. - */ - public Builder setSuccess(@NonNull KeyType key, @Nullable ValueType value) { - mResults.put(key, value); - mFailures.remove(key); - return this; - } - - /** - * Registers that the {@code key} failed and associates it with {@code throwable}. Any - * previous mapping for a key, whether success or failure, is deleted. - */ - public Builder setFailure(@NonNull KeyType key, @Nullable Throwable throwable) { - mFailures.put(key, throwable); - mResults.remove(key); - return this; - } - - /** Builds an {@link AppSearchBatchResult} from the contents of this {@link Builder}. */ - @NonNull - public AppSearchBatchResult<KeyType, ValueType> build() { - return new AppSearchBatchResult<>(mResults, mFailures); - } - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java deleted file mode 100644 index ff0f0dda55b9..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java +++ /dev/null @@ -1,724 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.CurrentTimeMillisLong; -import android.annotation.DurationMillisLong; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.util.ArrayMap; -import android.util.Log; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.Preconditions; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.protobuf.ByteString; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Represents a document unit. - * - * <p>Documents are constructed via {@link AppSearchDocument.Builder}. - * @hide - */ -public class AppSearchDocument { - private static final String TAG = "AppSearchDocument"; - - /** - * The maximum number of elements in a repeatable field. Will reject the request if exceed - * this limit. - */ - private static final int MAX_REPEATED_PROPERTY_LENGTH = 100; - - /** - * The maximum {@link String#length} of a {@link String} field. Will reject the request if - * {@link String}s longer than this. - */ - private static final int MAX_STRING_LENGTH = 20_000; - - /** - * Contains {@link AppSearchDocument} basic information (uri, schemaType etc) and properties - * ordered by keys. - */ - @NonNull - private final DocumentProto mProto; - - /** Contains all properties in {@link #mProto} to support getting properties via keys. */ - @NonNull - private final Map<String, Object> mProperties; - - /** - * Create a new {@link AppSearchDocument}. - * @param proto Contains {@link AppSearchDocument} basic information (uri, schemaType etc) and - * properties ordered by keys. - * @param propertiesMap Contains all properties in {@link #mProto} to support get properties - * via keys. - */ - private AppSearchDocument(@NonNull DocumentProto proto, - @NonNull Map<String, Object> propertiesMap) { - mProto = proto; - mProperties = propertiesMap; - } - - /** - * Create a new {@link AppSearchDocument} from an existing instance. - * - * <p>This method should be only used by constructor of a subclass. - */ - protected AppSearchDocument(@NonNull AppSearchDocument document) { - this(document.mProto, document.mProperties); - } - - /** @hide */ - AppSearchDocument(@NonNull DocumentProto documentProto) { - this(documentProto, new ArrayMap<>()); - for (int i = 0; i < documentProto.getPropertiesCount(); i++) { - PropertyProto property = documentProto.getProperties(i); - String name = property.getName(); - if (property.getStringValuesCount() > 0) { - String[] values = new String[property.getStringValuesCount()]; - for (int j = 0; j < values.length; j++) { - values[j] = property.getStringValues(j); - } - mProperties.put(name, values); - } else if (property.getInt64ValuesCount() > 0) { - long[] values = new long[property.getInt64ValuesCount()]; - for (int j = 0; j < values.length; j++) { - values[j] = property.getInt64Values(j); - } - mProperties.put(property.getName(), values); - } else if (property.getDoubleValuesCount() > 0) { - double[] values = new double[property.getDoubleValuesCount()]; - for (int j = 0; j < values.length; j++) { - values[j] = property.getDoubleValues(j); - } - mProperties.put(property.getName(), values); - } else if (property.getBooleanValuesCount() > 0) { - boolean[] values = new boolean[property.getBooleanValuesCount()]; - for (int j = 0; j < values.length; j++) { - values[j] = property.getBooleanValues(j); - } - mProperties.put(property.getName(), values); - } else if (property.getBytesValuesCount() > 0) { - byte[][] values = new byte[property.getBytesValuesCount()][]; - for (int j = 0; j < values.length; j++) { - values[j] = property.getBytesValues(j).toByteArray(); - } - mProperties.put(name, values); - } else if (property.getDocumentValuesCount() > 0) { - AppSearchDocument[] values = - new AppSearchDocument[property.getDocumentValuesCount()]; - for (int j = 0; j < values.length; j++) { - values[j] = new AppSearchDocument(property.getDocumentValues(j)); - } - mProperties.put(name, values); - } else { - throw new IllegalStateException("Unknown type of value: " + name); - } - } - } - - /** - * Get the {@link DocumentProto} of the {@link AppSearchDocument}. - * - * <p>The {@link DocumentProto} contains {@link AppSearchDocument}'s basic information and all - * properties ordered by keys. - * @hide - */ - @NonNull - @VisibleForTesting - public DocumentProto getProto() { - return mProto; - } - - /** - * Get the uri of the {@link AppSearchDocument}. - * - * @hide - */ - @NonNull - public String getUri() { - return mProto.getUri(); - } - - /** - * Get the schema type of the {@link AppSearchDocument}. - * @hide - */ - @NonNull - public String getSchemaType() { - return mProto.getSchema(); - } - - /** - * Get the creation timestamp in milliseconds of the {@link AppSearchDocument}. Value will be in - * the {@link System#currentTimeMillis()} time base. - * - * @hide - */ - @CurrentTimeMillisLong - public long getCreationTimestampMillis() { - return mProto.getCreationTimestampMs(); - } - - /** - * Returns the TTL (Time To Live) of the {@link AppSearchDocument}, in milliseconds. - * - * <p>The default value is 0, which means the document is permanent and won't be auto-deleted - * until the app is uninstalled. - * - * @hide - */ - @DurationMillisLong - public long getTtlMillis() { - return mProto.getTtlMs(); - } - - /** - * Returns the score of the {@link AppSearchDocument}. - * - * <p>The score is a query-independent measure of the document's quality, relative to other - * {@link AppSearchDocument}s of the same type. - * - * <p>The default value is 0. - * - * @hide - */ - public int getScore() { - return mProto.getScore(); - } - - /** - * Retrieve a {@link String} value by key. - * - * @param key The key to look for. - * @return The first {@link String} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. - * @hide - */ - @Nullable - public String getPropertyString(@NonNull String key) { - String[] propertyArray = getPropertyStringArray(key); - if (ArrayUtils.isEmpty(propertyArray)) { - return null; - } - warnIfSinglePropertyTooLong("String", key, propertyArray.length); - return propertyArray[0]; - } - - /** - * Retrieve a {@link Long} value by key. - * - * @param key The key to look for. - * @return The first {@link Long} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. - * @hide - */ - @Nullable - public Long getPropertyLong(@NonNull String key) { - long[] propertyArray = getPropertyLongArray(key); - if (ArrayUtils.isEmpty(propertyArray)) { - return null; - } - warnIfSinglePropertyTooLong("Long", key, propertyArray.length); - return propertyArray[0]; - } - - /** - * Retrieve a {@link Double} value by key. - * - * @param key The key to look for. - * @return The first {@link Double} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. - * @hide - */ - @Nullable - public Double getPropertyDouble(@NonNull String key) { - double[] propertyArray = getPropertyDoubleArray(key); - // TODO(tytytyww): Add support double array to ArraysUtils.isEmpty(). - if (propertyArray == null || propertyArray.length == 0) { - return null; - } - warnIfSinglePropertyTooLong("Double", key, propertyArray.length); - return propertyArray[0]; - } - - /** - * Retrieve a {@link Boolean} value by key. - * - * @param key The key to look for. - * @return The first {@link Boolean} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. - * @hide - */ - @Nullable - public Boolean getPropertyBoolean(@NonNull String key) { - boolean[] propertyArray = getPropertyBooleanArray(key); - if (ArrayUtils.isEmpty(propertyArray)) { - return null; - } - warnIfSinglePropertyTooLong("Boolean", key, propertyArray.length); - return propertyArray[0]; - } - - /** - * Retrieve a {@code byte[]} value by key. - * - * @param key The key to look for. - * @return The first {@code byte[]} associated with the given key or {@code null} if there - * is no such key or the value is of a different type. - */ - @Nullable - public byte[] getPropertyBytes(@NonNull String key) { - byte[][] propertyArray = getPropertyBytesArray(key); - if (ArrayUtils.isEmpty(propertyArray)) { - return null; - } - warnIfSinglePropertyTooLong("ByteArray", key, propertyArray.length); - return propertyArray[0]; - } - - /** - * Retrieve a {@link AppSearchDocument} value by key. - * - * @param key The key to look for. - * @return The first {@link AppSearchDocument} associated with the given key or {@code null} if - * there is no such key or the value is of a different type. - */ - @Nullable - public AppSearchDocument getPropertyDocument(@NonNull String key) { - AppSearchDocument[] propertyArray = getPropertyDocumentArray(key); - if (ArrayUtils.isEmpty(propertyArray)) { - return null; - } - warnIfSinglePropertyTooLong("Document", key, propertyArray.length); - return propertyArray[0]; - } - - /** Prints a warning to logcat if the given propertyLength is greater than 1. */ - private static void warnIfSinglePropertyTooLong( - @NonNull String propertyType, @NonNull String key, int propertyLength) { - if (propertyLength > 1) { - Log.w(TAG, "The value for \"" + key + "\" contains " + propertyLength - + " elements. Only the first one will be returned from " - + "getProperty" + propertyType + "(). Try getProperty" + propertyType - + "Array()."); - } - } - - /** - * Retrieve a repeated {@code String} property by key. - * - * @param key The key to look for. - * @return The {@code String[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. - * @hide - */ - @Nullable - public String[] getPropertyStringArray(@NonNull String key) { - return getAndCastPropertyArray(key, String[].class); - } - - /** - * Retrieve a repeated {@code long} property by key. - * - * @param key The key to look for. - * @return The {@code long[]} associated with the given key, or {@code null} if no value is - * set or the value is of a different type. - * @hide - */ - @Nullable - public long[] getPropertyLongArray(@NonNull String key) { - return getAndCastPropertyArray(key, long[].class); - } - - /** - * Retrieve a repeated {@code double} property by key. - * - * @param key The key to look for. - * @return The {@code double[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. - * @hide - */ - @Nullable - public double[] getPropertyDoubleArray(@NonNull String key) { - return getAndCastPropertyArray(key, double[].class); - } - - /** - * Retrieve a repeated {@code boolean} property by key. - * - * @param key The key to look for. - * @return The {@code boolean[]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. - * @hide - */ - @Nullable - public boolean[] getPropertyBooleanArray(@NonNull String key) { - return getAndCastPropertyArray(key, boolean[].class); - } - - /** - * Retrieve a {@code byte[][]} property by key. - * - * @param key The key to look for. - * @return The {@code byte[][]} associated with the given key, or {@code null} if no value - * is set or the value is of a different type. - */ - @Nullable - public byte[][] getPropertyBytesArray(@NonNull String key) { - return getAndCastPropertyArray(key, byte[][].class); - } - - /** - * Retrieve a repeated {@link AppSearchDocument} property by key. - * - * @param key The key to look for. - * @return The {@link AppSearchDocument[]} associated with the given key, or {@code null} if no - * value is set or the value is of a different type. - */ - @Nullable - public AppSearchDocument[] getPropertyDocumentArray(@NonNull String key) { - return getAndCastPropertyArray(key, AppSearchDocument[].class); - } - - /** - * Gets a repeated property of the given key, and casts it to the given class type, which - * must be an array class type. - */ - @Nullable - private <T> T getAndCastPropertyArray(@NonNull String key, @NonNull Class<T> tClass) { - Object value = mProperties.get(key); - if (value == null) { - return null; - } - try { - return tClass.cast(value); - } catch (ClassCastException e) { - Log.w(TAG, "Error casting to requested type for key \"" + key + "\"", e); - return null; - } - } - - @Override - public boolean equals(@Nullable Object other) { - // Check only proto's equality is sufficient here since all properties in - // mProperties are ordered by keys and stored in proto. - if (this == other) { - return true; - } - if (!(other instanceof AppSearchDocument)) { - return false; - } - AppSearchDocument otherDocument = (AppSearchDocument) other; - return this.mProto.equals(otherDocument.mProto); - } - - @Override - public int hashCode() { - // Hash only proto is sufficient here since all properties in mProperties are ordered by - // keys and stored in proto. - return mProto.hashCode(); - } - - @Override - public String toString() { - return mProto.toString(); - } - - /** - * The builder class for {@link AppSearchDocument}. - * - * @param <BuilderType> Type of subclass who extend this. - * @hide - */ - public static class Builder<BuilderType extends Builder> { - - private final Map<String, Object> mProperties = new ArrayMap<>(); - private final DocumentProto.Builder mProtoBuilder = DocumentProto.newBuilder(); - private final BuilderType mBuilderTypeInstance; - - /** - * Create a new {@link AppSearchDocument.Builder}. - * - * @param uri The uri of {@link AppSearchDocument}. - * @param schemaType The schema type of the {@link AppSearchDocument}. The passed-in - * {@code schemaType} must be defined using {@link AppSearchManager#setSchema} prior - * to inserting a document of this {@code schemaType} into the AppSearch index using - * {@link AppSearchManager#putDocuments(List)}. Otherwise, the document will be - * rejected by {@link AppSearchManager#putDocuments(List)}. - * @hide - */ - public Builder(@NonNull String uri, @NonNull String schemaType) { - mBuilderTypeInstance = (BuilderType) this; - mProtoBuilder.setUri(uri).setSchema(schemaType); - // Set current timestamp for creation timestamp by default. - setCreationTimestampMillis(System.currentTimeMillis()); - } - - /** - * Sets the score of the {@link AppSearchDocument}. - * - * <p>The score is a query-independent measure of the document's quality, relative to - * other {@link AppSearchDocument}s of the same type. - * - * @throws IllegalArgumentException If the provided value is negative. - * @hide - */ - @NonNull - public BuilderType setScore(@IntRange(from = 0, to = Integer.MAX_VALUE) int score) { - if (score < 0) { - throw new IllegalArgumentException("Document score cannot be negative."); - } - mProtoBuilder.setScore(score); - return mBuilderTypeInstance; - } - - /** - * Set the creation timestamp in milliseconds of the {@link AppSearchDocument}. Should be - * set using a value obtained from the {@link System#currentTimeMillis()} time base. - * - * @hide - */ - @NonNull - public BuilderType setCreationTimestampMillis( - @CurrentTimeMillisLong long creationTimestampMillis) { - mProtoBuilder.setCreationTimestampMs(creationTimestampMillis); - return mBuilderTypeInstance; - } - - /** - * Set the TTL (Time To Live) of the {@link AppSearchDocument}, in milliseconds. - * - * <p>After this many milliseconds since the {@link #setCreationTimestampMillis(long)} - * creation timestamp}, the document is deleted. - * - * @param ttlMillis A non-negative duration in milliseconds. - * @throws IllegalArgumentException If the provided value is negative. - */ - @NonNull - public BuilderType setTtlMillis(@DurationMillisLong long ttlMillis) { - Preconditions.checkArgumentNonNegative( - ttlMillis, "Document ttlMillis cannot be negative."); - mProtoBuilder.setTtlMs(ttlMillis); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@code String} values for a property, replacing its previous - * values. - * - * @param key The key associated with the {@code values}. - * @param values The {@code String} values of the property. - * @hide - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull String... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@code boolean} values for a property, replacing its previous - * values. - * - * @param key The key associated with the {@code values}. - * @param values The {@code boolean} values of the property. - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull boolean... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@code long} values for a property, replacing its previous - * values. - * - * @param key The key associated with the {@code values}. - * @param values The {@code long} values of the property. - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull long... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@code double} values for a property, replacing its previous - * values. - * - * @param key The key associated with the {@code values}. - * @param values The {@code double} values of the property. - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull double... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@code byte[]} for a property, replacing its previous values. - * - * @param key The key associated with the {@code values}. - * @param values The {@code byte[]} of the property. - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull byte[]... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - /** - * Sets one or multiple {@link AppSearchDocument} values for a property, replacing its - * previous values. - * - * @param key The key associated with the {@code values}. - * @param values The {@link AppSearchDocument} values of the property. - */ - @NonNull - public BuilderType setProperty(@NonNull String key, @NonNull AppSearchDocument... values) { - putInPropertyMap(key, values); - return mBuilderTypeInstance; - } - - private void putInPropertyMap(@NonNull String key, @NonNull String[] values) - throws IllegalArgumentException { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - validateRepeatedPropertyLength(key, values.length); - for (int i = 0; i < values.length; i++) { - if (values[i] == null) { - throw new IllegalArgumentException("The String at " + i + " is null."); - } else if (values[i].length() > MAX_STRING_LENGTH) { - throw new IllegalArgumentException("The String at " + i + " length is: " - + values[i].length() + ", which exceeds length limit: " - + MAX_STRING_LENGTH + "."); - } - } - mProperties.put(key, values); - } - - private void putInPropertyMap(@NonNull String key, @NonNull boolean[] values) { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - validateRepeatedPropertyLength(key, values.length); - mProperties.put(key, values); - } - - private void putInPropertyMap(@NonNull String key, @NonNull double[] values) { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - validateRepeatedPropertyLength(key, values.length); - mProperties.put(key, values); - } - - private void putInPropertyMap(@NonNull String key, @NonNull long[] values) { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - validateRepeatedPropertyLength(key, values.length); - mProperties.put(key, values); - } - - private void putInPropertyMap(@NonNull String key, @NonNull byte[][] values) { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - validateRepeatedPropertyLength(key, values.length); - mProperties.put(key, values); - } - - private void putInPropertyMap(@NonNull String key, @NonNull AppSearchDocument[] values) { - Objects.requireNonNull(key); - Objects.requireNonNull(values); - for (int i = 0; i < values.length; i++) { - if (values[i] == null) { - throw new IllegalArgumentException("The document at " + i + " is null."); - } - } - validateRepeatedPropertyLength(key, values.length); - mProperties.put(key, values); - } - - private static void validateRepeatedPropertyLength(@NonNull String key, int length) { - if (length == 0) { - throw new IllegalArgumentException("The input array is empty."); - } else if (length > MAX_REPEATED_PROPERTY_LENGTH) { - throw new IllegalArgumentException( - "Repeated property \"" + key + "\" has length " + length - + ", which exceeds the limit of " - + MAX_REPEATED_PROPERTY_LENGTH); - } - } - - /** - * Builds the {@link AppSearchDocument} object. - * @hide - */ - public AppSearchDocument build() { - // Build proto by sorting the keys in mProperties to exclude the influence of - // order. Therefore documents will generate same proto as long as the contents are - // same. Note that the order of repeated fields is still preserved. - ArrayList<String> keys = new ArrayList<>(mProperties.keySet()); - Collections.sort(keys); - for (int i = 0; i < keys.size(); i++) { - String name = keys.get(i); - Object values = mProperties.get(name); - PropertyProto.Builder propertyProto = PropertyProto.newBuilder().setName(name); - if (values instanceof boolean[]) { - for (boolean value : (boolean[]) values) { - propertyProto.addBooleanValues(value); - } - } else if (values instanceof long[]) { - for (long value : (long[]) values) { - propertyProto.addInt64Values(value); - } - } else if (values instanceof double[]) { - for (double value : (double[]) values) { - propertyProto.addDoubleValues(value); - } - } else if (values instanceof String[]) { - for (String value : (String[]) values) { - propertyProto.addStringValues(value); - } - } else if (values instanceof AppSearchDocument[]) { - for (AppSearchDocument value : (AppSearchDocument[]) values) { - propertyProto.addDocumentValues(value.getProto()); - } - } else if (values instanceof byte[][]) { - for (byte[] value : (byte[][]) values) { - propertyProto.addBytesValues(ByteString.copyFrom(value)); - } - } else { - throw new IllegalStateException( - "Property \"" + name + "\" has unsupported value type \"" - + values.getClass().getSimpleName() + "\""); - } - mProtoBuilder.addProperties(propertyProto); - } - return new AppSearchDocument(mProtoBuilder.build(), mProperties); - } - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java deleted file mode 100644 index 5b9457b77ea0..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.appsearch.AppSearchSchema.PropertyConfig; - -/** - * Encapsulates a {@link AppSearchDocument} that represent an email. - * - * <p>This class is a higher level implement of {@link AppSearchDocument}. - * - * <p>This class will eventually migrate to Jetpack, where it will become public API. - * - * @hide - */ -public class AppSearchEmail extends AppSearchDocument { - private static final String KEY_FROM = "from"; - private static final String KEY_TO = "to"; - private static final String KEY_CC = "cc"; - private static final String KEY_BCC = "bcc"; - private static final String KEY_SUBJECT = "subject"; - private static final String KEY_BODY = "body"; - - /** The name of the schema type for {@link AppSearchEmail} documents.*/ - public static final String SCHEMA_TYPE = "builtin:Email"; - - public static final AppSearchSchema SCHEMA = AppSearchSchema.newBuilder(SCHEMA_TYPE) - .addProperty(AppSearchSchema.newPropertyBuilder(KEY_FROM) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_TO) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_REPEATED) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_CC) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_REPEATED) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BCC) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_REPEATED) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_SUBJECT) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).addProperty(AppSearchSchema.newPropertyBuilder(KEY_BODY) - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .build() - - ).build(); - - /** - * Creates a new {@link AppSearchEmail} from the contents of an existing - * {@link AppSearchDocument}. - * - * @param document The {@link AppSearchDocument} containing the email content. - */ - public AppSearchEmail(@NonNull AppSearchDocument document) { - super(document); - } - - /** - * Get the from address of {@link AppSearchEmail}. - * - * @return Returns the subject of {@link AppSearchEmail} or {@code null} if it's not been set - * yet. - * @hide - */ - @Nullable - public String getFrom() { - return getPropertyString(KEY_FROM); - } - - /** - * Get the destination addresses of {@link AppSearchEmail}. - * - * @return Returns the destination addresses of {@link AppSearchEmail} or {@code null} if it's - * not been set yet. - * @hide - */ - @Nullable - public String[] getTo() { - return getPropertyStringArray(KEY_TO); - } - - /** - * Get the CC list of {@link AppSearchEmail}. - * - * @return Returns the CC list of {@link AppSearchEmail} or {@code null} if it's not been set - * yet. - * @hide - */ - @Nullable - public String[] getCc() { - return getPropertyStringArray(KEY_CC); - } - - /** - * Get the BCC list of {@link AppSearchEmail}. - * - * @return Returns the BCC list of {@link AppSearchEmail} or {@code null} if it's not been set - * yet. - * @hide - */ - @Nullable - public String[] getBcc() { - return getPropertyStringArray(KEY_BCC); - } - - /** - * Get the subject of {@link AppSearchEmail}. - * - * @return Returns the value subject of {@link AppSearchEmail} or {@code null} if it's not been - * set yet. - * @hide - */ - @Nullable - public String getSubject() { - return getPropertyString(KEY_SUBJECT); - } - - /** - * Get the body of {@link AppSearchEmail}. - * - * @return Returns the body of {@link AppSearchEmail} or {@code null} if it's not been set yet. - * @hide - */ - @Nullable - public String getBody() { - return getPropertyString(KEY_BODY); - } - - /** - * The builder class for {@link AppSearchEmail}. - * @hide - */ - public static class Builder extends AppSearchDocument.Builder<AppSearchEmail.Builder> { - - /** - * Create a new {@link AppSearchEmail.Builder} - * @param uri The Uri of the Email. - * @hide - */ - public Builder(@NonNull String uri) { - super(uri, SCHEMA_TYPE); - } - - /** - * Set the from address of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setFrom(@NonNull String from) { - setProperty(KEY_FROM, from); - return this; - } - - /** - * Set the destination address of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setTo(@NonNull String... to) { - setProperty(KEY_TO, to); - return this; - } - - /** - * Set the CC list of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setCc(@NonNull String... cc) { - setProperty(KEY_CC, cc); - return this; - } - - /** - * Set the BCC list of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setBcc(@NonNull String... bcc) { - setProperty(KEY_BCC, bcc); - return this; - } - - /** - * Set the subject of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setSubject(@NonNull String subject) { - setProperty(KEY_SUBJECT, subject); - return this; - } - - /** - * Set the body of {@link AppSearchEmail} - * @hide - */ - @NonNull - public AppSearchEmail.Builder setBody(@NonNull String body) { - setProperty(KEY_BODY, body); - return this; - } - - /** - * Builds the {@link AppSearchEmail} object. - * - * @hide - */ - @NonNull - @Override - public AppSearchEmail build() { - return new AppSearchEmail(super.build()); - } - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java deleted file mode 100644 index e2c9b0f74870..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.app.appsearch; - -import android.annotation.CallbackExecutor; -import android.annotation.NonNull; -import android.annotation.SystemService; -import android.content.Context; -import android.os.RemoteException; - -import com.android.internal.infra.AndroidFuture; - -import com.google.android.icing.proto.SchemaProto; -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.SearchSpecProto; -import com.google.android.icing.proto.StatusProto; -import com.google.android.icing.protobuf.InvalidProtocolBufferException; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; -import java.util.function.BiConsumer; - -/** - * This class provides access to the centralized AppSearch index maintained by the system. - * - * <p>Apps can index structured text documents with AppSearch, which can then be retrieved through - * the query API. - * - * @hide - */ -@SystemService(Context.APP_SEARCH_SERVICE) -public class AppSearchManager { - private final IAppSearchManager mService; - - /** @hide */ - public AppSearchManager(@NonNull IAppSearchManager service) { - mService = service; - } - - /** - * Sets the schema being used by documents provided to the {@link #putDocuments} method. - * - * <p>The schema provided here is compared to the stored copy of the schema previously supplied - * to {@link #setSchema}, if any, to determine how to treat existing documents. The following - * types of schema modifications are always safe and are made without deleting any existing - * documents: - * <ul> - * <li>Addition of new types - * <li>Addition of new - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL - * OPTIONAL} or - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED - * REPEATED} properties to a type - * <li>Changing the cardinality of a data type to be less restrictive (e.g. changing an - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL - * OPTIONAL} property into a - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REPEATED - * REPEATED} property. - * </ul> - * - * <p>The following types of schema changes are not backwards-compatible. Supplying a schema - * with such changes will result in this call throwing an {@link IllegalSchemaException} - * describing the incompatibility, and the previously set schema will remain active: - * <ul> - * <li>Removal of an existing type - * <li>Removal of a property from a type - * <li>Changing the data type ({@code boolean}, {@code long}, etc.) of an existing property - * <li>For properties of {@code Document} type, changing the schema type of - * {@code Document Documents} of that property - * <li>Changing the cardinality of a data type to be more restrictive (e.g. changing an - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_OPTIONAL - * OPTIONAL} property into a - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED - * REQUIRED} property). - * <li>Adding a - * {@link android.app.appsearch.AppSearchSchema.PropertyConfig#CARDINALITY_REQUIRED - * REQUIRED} property. - * </ul> - * - * <p>If you need to make non-backwards-compatible changes as described above, instead use the - * {@link #setSchema(List, boolean)} method with the {@code forceOverride} parameter set to - * {@code true}. - * - * <p>It is a no-op to set the same schema as has been previously set; this is handled - * efficiently. - * - * @param schemas The schema configs for the types used by the calling app. - * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the - * previous schema. - * - * @hide - */ - public void setSchema(@NonNull AppSearchSchema... schemas) { - setSchema(Arrays.asList(schemas), /*forceOverride=*/false); - } - - /** - * Sets the schema being used by documents provided to the {@link #putDocuments} method. - * - * <p>This method is similar to {@link #setSchema(AppSearchSchema...)}, except for the - * {@code forceOverride} parameter. If a backwards-incompatible schema is specified but the - * {@code forceOverride} parameter is set to {@code true}, instead of throwing an - * {@link IllegalSchemaException}, all documents which are not compatible with the new schema - * will be deleted and the incompatible schema will be applied. - * - * @param schemas The schema configs for the types used by the calling app. - * @param forceOverride Whether to force the new schema to be applied even if there are - * incompatible changes versus the previously set schema. Documents which are incompatible - * with the new schema will be deleted. - * @throws IllegalSchemaException If the provided schema is invalid, or is incompatible with the - * previous schema and the {@code forceOverride} parameter is set to {@code false}. - * - * @hide - */ - public void setSchema(@NonNull List<AppSearchSchema> schemas, boolean forceOverride) { - // Prepare the merged schema for transmission. - SchemaProto.Builder schemaProtoBuilder = SchemaProto.newBuilder(); - for (AppSearchSchema schema : schemas) { - schemaProtoBuilder.addTypes(schema.getProto()); - } - - // Serialize and send the schema. - // TODO: This should use com.android.internal.infra.RemoteStream or another mechanism to - // avoid binder limits. - byte[] schemaBytes = schemaProtoBuilder.build().toByteArray(); - AndroidFuture<Void> future = new AndroidFuture<>(); - try { - mService.setSchema(schemaBytes, forceOverride, future); - } catch (RemoteException e) { - future.completeExceptionally(e); - } - getFutureOrThrow(future); - } - - /** - * Index {@link AppSearchDocument Documents} into AppSearch. - * - * <p>You should not call this method directly; instead, use the - * {@code AppSearch#putDocuments()} API provided by JetPack. - * - * <p>Each {@link AppSearchDocument Document's} {@code schemaType} field must be set to the - * name of a schema type previously registered via the {@link #setSchema} method. - * - * @param documents {@link AppSearchDocument Documents} that need to be indexed. - * @return An {@link AppSearchBatchResult} mapping the document URIs to {@link Void} if they - * were successfully indexed, or a {@link Throwable} describing the failure if they could - * not be indexed. - * @hide - */ - public AppSearchBatchResult<String, Void> putDocuments( - @NonNull List<AppSearchDocument> documents) { - // TODO(b/146386470): Transmit these documents as a RemoteStream instead of sending them in - // one big list. - List<byte[]> documentsBytes = new ArrayList<>(documents.size()); - for (AppSearchDocument document : documents) { - documentsBytes.add(document.getProto().toByteArray()); - } - AndroidFuture<AppSearchBatchResult> future = new AndroidFuture<>(); - try { - mService.putDocuments(documentsBytes, future); - } catch (RemoteException e) { - future.completeExceptionally(e); - } - return getFutureOrThrow(future); - } - - /** - * This method searches for documents based on a given query string. It also accepts - * specifications regarding how to search and format the results. - * - *<p>Currently we support following features in the raw query format: - * <ul> - * <li>AND - * <p>AND joins (e.g. “match documents that have both the terms ‘dog’ and - * ‘cat’”). - * Example: hello world matches documents that have both ‘hello’ and ‘world’ - * <li>OR - * <p>OR joins (e.g. “match documents that have either the term ‘dog’ or - * ‘cat’”). - * Example: dog OR puppy - * <li>Exclusion - * <p>Exclude a term (e.g. “match documents that do - * not have the term ‘dog’”). - * Example: -dog excludes the term ‘dog’ - * <li>Grouping terms - * <p>Allow for conceptual grouping of subqueries to enable hierarchical structures (e.g. - * “match documents that have either ‘dog’ or ‘puppy’, and either ‘cat’ or ‘kitten’”). - * Example: (dog puppy) (cat kitten) two one group containing two terms. - * <li>Property restricts - * <p> Specifies which properties of a document to specifically match terms in (e.g. - * “match documents where the ‘subject’ property contains ‘important’”). - * Example: subject:important matches documents with the term ‘important’ in the - * ‘subject’ property - * <li>Schema type restricts - * <p>This is similar to property restricts, but allows for restricts on top-level document - * fields, such as schema_type. Clients should be able to limit their query to documents of - * a certain schema_type (e.g. “match documents that are of the ‘Email’ schema_type”). - * Example: { schema_type_filters: “Email”, “Video”,query: “dog” } will match documents - * that contain the query term ‘dog’ and are of either the ‘Email’ schema type or the - * ‘Video’ schema type. - * </ul> - * - * <p> It is strongly recommended to use Jetpack APIs. - * - * @param queryExpression Query String to search. - * @param searchSpec Spec for setting filters, raw query etc. - * @param executor Executor on which to invoke the callback. - * @param callback Callback to receive errors resulting from the query operation. If the - * operation succeeds, the callback will be invoked with {@code null}. - * @hide - */ - @NonNull - public void query( - @NonNull String queryExpression, - @NonNull SearchSpec searchSpec, - @NonNull @CallbackExecutor Executor executor, - @NonNull BiConsumer<? super SearchResults, ? super Throwable> callback) { - AndroidFuture<byte[]> future = new AndroidFuture<>(); - future.whenCompleteAsync((searchResultBytes, err) -> { - if (err != null) { - callback.accept(null, err); - return; - } - - if (searchResultBytes != null) { - SearchResultProto searchResultProto; - try { - searchResultProto = SearchResultProto.parseFrom(searchResultBytes); - } catch (InvalidProtocolBufferException e) { - callback.accept(null, e); - return; - } - if (searchResultProto.getStatus().getCode() != StatusProto.Code.OK) { - // TODO(sidchhabra): Add better exception handling. - callback.accept( - null, - new RuntimeException(searchResultProto.getStatus().getMessage())); - return; - } - SearchResults searchResults = new SearchResults(searchResultProto); - callback.accept(searchResults, null); - return; - } - - // Nothing was supplied in the future at all - callback.accept( - null, new IllegalStateException("Unknown failure occurred while querying")); - }, executor); - - try { - SearchSpecProto searchSpecProto = searchSpec.getSearchSpecProto(); - searchSpecProto = searchSpecProto.toBuilder().setQuery(queryExpression).build(); - mService.query(searchSpecProto.toByteArray(), - searchSpec.getResultSpecProto().toByteArray(), - searchSpec.getScoringSpecProto().toByteArray(), future); - } catch (RemoteException e) { - future.completeExceptionally(e); - } - } - - private static <T> T getFutureOrThrow(@NonNull AndroidFuture<T> future) { - try { - return future.get(); - } catch (Throwable e) { - if (e instanceof ExecutionException) { - e = e.getCause(); - } - if (e instanceof RuntimeException) { - throw (RuntimeException) e; - } - if (e instanceof Error) { - throw (Error) e; - } - throw new RuntimeException(e); - } - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java deleted file mode 100644 index 02cc967e7daf..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.app.appsearch; - -import android.annotation.SystemApi; -import android.app.SystemServiceRegistry; -import android.content.Context; - -/** - * Class holding initialization code for the AppSearch module. - * - * @hide - */ -@SystemApi -public class AppSearchManagerFrameworkInitializer { - private AppSearchManagerFrameworkInitializer() {} - - /** - * Called by {@link SystemServiceRegistry}'s static initializer and registers all AppSearch - * services to {@link Context}, so that {@link Context#getSystemService} can return them. - * - * @throws IllegalStateException if this is called from anywhere besides - * {@link SystemServiceRegistry} - */ - public static void initialize() { - SystemServiceRegistry.registerStaticService( - Context.APP_SEARCH_SERVICE, AppSearchManager.class, - (service) -> new AppSearchManager(IAppSearchManager.Stub.asInterface(service))); - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java deleted file mode 100644 index 1d54dc4971a6..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.util.ArraySet; - -import com.android.internal.annotations.VisibleForTesting; - -import com.google.android.icing.proto.PropertyConfigProto; -import com.google.android.icing.proto.SchemaTypeConfigProto; -import com.google.android.icing.proto.TermMatchType; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Set; - -/** - * The AppSearch Schema for a particular type of document. - * - * <p>For example, an e-mail message or a music recording could be a schema type. - * - * <p>The schema consists of type information, properties, and config (like tokenization type). - * - * @hide - */ -public final class AppSearchSchema { - private final SchemaTypeConfigProto mProto; - - private AppSearchSchema(SchemaTypeConfigProto proto) { - mProto = proto; - } - - /** Creates a new {@link AppSearchSchema.Builder}. */ - @NonNull - public static AppSearchSchema.Builder newBuilder(@NonNull String typeName) { - return new AppSearchSchema.Builder(typeName); - } - - /** Creates a new {@link PropertyConfig.Builder}. */ - @NonNull - public static PropertyConfig.Builder newPropertyBuilder(@NonNull String propertyName) { - return new PropertyConfig.Builder(propertyName); - } - - /** - * Returns the {@link SchemaTypeConfigProto} populated by this builder. - * @hide - */ - @NonNull - @VisibleForTesting - public SchemaTypeConfigProto getProto() { - return mProto; - } - - @Override - public String toString() { - return mProto.toString(); - } - - /** Builder for {@link AppSearchSchema objects}. */ - public static final class Builder { - private final SchemaTypeConfigProto.Builder mProtoBuilder = - SchemaTypeConfigProto.newBuilder(); - - private Builder(@NonNull String typeName) { - mProtoBuilder.setSchemaType(typeName); - } - - /** Adds a property to the given type. */ - @NonNull - public AppSearchSchema.Builder addProperty(@NonNull PropertyConfig propertyConfig) { - mProtoBuilder.addProperties(propertyConfig.mProto); - return this; - } - - /** - * Constructs a new {@link AppSearchSchema} from the contents of this builder. - * - * <p>After calling this method, the builder must no longer be used. - */ - @NonNull - public AppSearchSchema build() { - Set<String> propertyNames = new ArraySet<>(); - for (PropertyConfigProto propertyConfigProto : mProtoBuilder.getPropertiesList()) { - if (!propertyNames.add(propertyConfigProto.getPropertyName())) { - throw new IllegalSchemaException( - "Property defined more than once: " - + propertyConfigProto.getPropertyName()); - } - } - return new AppSearchSchema(mProtoBuilder.build()); - } - } - - /** - * Configuration for a single property (field) of a document type. - * - * <p>For example, an {@code EmailMessage} would be a type and the {@code subject} would be - * a property. - */ - public static final class PropertyConfig { - /** Physical data-types of the contents of the property. */ - // NOTE: The integer values of these constants must match the proto enum constants in - // com.google.android.icing.proto.PropertyConfigProto.DataType.Code. - @IntDef(prefix = {"DATA_TYPE_"}, value = { - DATA_TYPE_STRING, - DATA_TYPE_INT64, - DATA_TYPE_DOUBLE, - DATA_TYPE_BOOLEAN, - DATA_TYPE_BYTES, - DATA_TYPE_DOCUMENT, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface DataType {} - - public static final int DATA_TYPE_STRING = 1; - public static final int DATA_TYPE_INT64 = 2; - public static final int DATA_TYPE_DOUBLE = 3; - public static final int DATA_TYPE_BOOLEAN = 4; - - /** Unstructured BLOB. */ - public static final int DATA_TYPE_BYTES = 5; - - /** - * Indicates that the property itself is an Document, making it part a hierarchical - * Document schema. Any property using this DataType MUST have a valid - * {@code schemaType}. - */ - public static final int DATA_TYPE_DOCUMENT = 6; - - /** The cardinality of the property (whether it is required, optional or repeated). */ - // NOTE: The integer values of these constants must match the proto enum constants in - // com.google.android.icing.proto.PropertyConfigProto.Cardinality.Code. - @IntDef(prefix = {"CARDINALITY_"}, value = { - CARDINALITY_REPEATED, - CARDINALITY_OPTIONAL, - CARDINALITY_REQUIRED, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface Cardinality {} - - /** Any number of items (including zero) [0...*]. */ - public static final int CARDINALITY_REPEATED = 1; - - /** Zero or one value [0,1]. */ - public static final int CARDINALITY_OPTIONAL = 2; - - /** Exactly one value [1]. */ - public static final int CARDINALITY_REQUIRED = 3; - - /** Encapsulates the configurations on how AppSearch should query/index these terms. */ - @IntDef(prefix = {"INDEXING_TYPE_"}, value = { - INDEXING_TYPE_NONE, - INDEXING_TYPE_EXACT_TERMS, - INDEXING_TYPE_PREFIXES, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface IndexingType {} - - /** - * Content in this property will not be tokenized or indexed. - * - * <p>Useful if the data type is not made up of terms (e.g. - * {@link PropertyConfig#DATA_TYPE_DOCUMENT} or {@link PropertyConfig#DATA_TYPE_BYTES} - * type). All the properties inside the nested property won't be indexed regardless of the - * value of {@code indexingType} for the nested properties. - */ - public static final int INDEXING_TYPE_NONE = 0; - - /** - * Content in this property should only be returned for queries matching the exact tokens - * appearing in this property. - * - * <p>Ex. A property with "fool" should NOT match a query for "foo". - */ - public static final int INDEXING_TYPE_EXACT_TERMS = 1; - - /** - * Content in this property should be returned for queries that are either exact matches or - * query matches of the tokens appearing in this property. - * - * <p>Ex. A property with "fool" <b>should</b> match a query for "foo". - */ - public static final int INDEXING_TYPE_PREFIXES = 2; - - /** Configures how tokens should be extracted from this property. */ - // NOTE: The integer values of these constants must match the proto enum constants in - // com.google.android.icing.proto.IndexingConfig.TokenizerType.Code. - @IntDef(prefix = {"TOKENIZER_TYPE_"}, value = { - TOKENIZER_TYPE_NONE, - TOKENIZER_TYPE_PLAIN, - }) - @Retention(RetentionPolicy.SOURCE) - public @interface TokenizerType {} - - /** - * It is only valid for tokenizer_type to be 'NONE' if the data type is - * {@link PropertyConfig#DATA_TYPE_DOCUMENT}. - */ - public static final int TOKENIZER_TYPE_NONE = 0; - - /** Tokenization for plain text. */ - public static final int TOKENIZER_TYPE_PLAIN = 1; - - private final PropertyConfigProto mProto; - - private PropertyConfig(PropertyConfigProto proto) { - mProto = proto; - } - - @Override - public String toString() { - return mProto.toString(); - } - - /** - * Builder for {@link PropertyConfig}. - * - * <p>The following properties must be set, or {@link PropertyConfig} construction will - * fail: - * <ul> - * <li>dataType - * <li>cardinality - * </ul> - * - * <p>In addition, if {@code schemaType} is {@link #DATA_TYPE_DOCUMENT}, {@code schemaType} - * is also required. - */ - public static final class Builder { - private final PropertyConfigProto.Builder mPropertyConfigProto = - PropertyConfigProto.newBuilder(); - private final com.google.android.icing.proto.IndexingConfig.Builder - mIndexingConfigProto = - com.google.android.icing.proto.IndexingConfig.newBuilder(); - - private Builder(String propertyName) { - mPropertyConfigProto.setPropertyName(propertyName); - } - - /** - * Type of data the property contains (e.g. string, int, bytes, etc). - * - * <p>This property must be set. - */ - @NonNull - public PropertyConfig.Builder setDataType(@DataType int dataType) { - PropertyConfigProto.DataType.Code dataTypeProto = - PropertyConfigProto.DataType.Code.forNumber(dataType); - if (dataTypeProto == null) { - throw new IllegalArgumentException("Invalid dataType: " + dataType); - } - mPropertyConfigProto.setDataType(dataTypeProto); - return this; - } - - /** - * The logical schema-type of the contents of this property. - * - * <p>Only required when {@link #setDataType(int)} is set to - * {@link #DATA_TYPE_DOCUMENT}. Otherwise, it is ignored. - */ - @NonNull - public PropertyConfig.Builder setSchemaType(@NonNull String schemaType) { - mPropertyConfigProto.setSchemaType(schemaType); - return this; - } - - /** - * The cardinality of the property (whether it is optional, required or repeated). - * - * <p>This property must be set. - */ - @NonNull - public PropertyConfig.Builder setCardinality(@Cardinality int cardinality) { - PropertyConfigProto.Cardinality.Code cardinalityProto = - PropertyConfigProto.Cardinality.Code.forNumber(cardinality); - if (cardinalityProto == null) { - throw new IllegalArgumentException("Invalid cardinality: " + cardinality); - } - mPropertyConfigProto.setCardinality(cardinalityProto); - return this; - } - - /** - * Configures how a property should be indexed so that it can be retrieved by queries. - */ - @NonNull - public PropertyConfig.Builder setIndexingType(@IndexingType int indexingType) { - TermMatchType.Code termMatchTypeProto; - switch (indexingType) { - case INDEXING_TYPE_NONE: - termMatchTypeProto = TermMatchType.Code.UNKNOWN; - break; - case INDEXING_TYPE_EXACT_TERMS: - termMatchTypeProto = TermMatchType.Code.EXACT_ONLY; - break; - case INDEXING_TYPE_PREFIXES: - termMatchTypeProto = TermMatchType.Code.PREFIX; - break; - default: - throw new IllegalArgumentException("Invalid indexingType: " + indexingType); - } - mIndexingConfigProto.setTermMatchType(termMatchTypeProto); - return this; - } - - /** Configures how this property should be tokenized (split into words). */ - @NonNull - public PropertyConfig.Builder setTokenizerType(@TokenizerType int tokenizerType) { - com.google.android.icing.proto.IndexingConfig.TokenizerType.Code - tokenizerTypeProto = - com.google.android.icing.proto.IndexingConfig - .TokenizerType.Code.forNumber(tokenizerType); - if (tokenizerTypeProto == null) { - throw new IllegalArgumentException("Invalid tokenizerType: " + tokenizerType); - } - mIndexingConfigProto.setTokenizerType(tokenizerTypeProto); - return this; - } - - /** - * Constructs a new {@link PropertyConfig} from the contents of this builder. - * - * <p>After calling this method, the builder must no longer be used. - * - * @throws IllegalSchemaException If the property is not correctly populated (e.g. - * missing {@code dataType}). - */ - @NonNull - public PropertyConfig build() { - mPropertyConfigProto.setIndexingConfig(mIndexingConfigProto); - // TODO(b/147692920): Send the schema to Icing Lib for official validation, instead - // of partially reimplementing some of the validation Icing does here. - if (mPropertyConfigProto.getDataType() - == PropertyConfigProto.DataType.Code.UNKNOWN) { - throw new IllegalSchemaException("Missing field: dataType"); - } - if (mPropertyConfigProto.getSchemaType().isEmpty() - && mPropertyConfigProto.getDataType() - == PropertyConfigProto.DataType.Code.DOCUMENT) { - throw new IllegalSchemaException( - "Missing field: schemaType (required for configs with " - + "dataType = DOCUMENT)"); - } - if (mPropertyConfigProto.getCardinality() - == PropertyConfigProto.Cardinality.Code.UNKNOWN) { - throw new IllegalSchemaException("Missing field: cardinality"); - } - return new PropertyConfig(mPropertyConfigProto.build()); - } - } - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl b/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl deleted file mode 100644 index eef41ed7104d..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright 2020, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.app.appsearch; - -import com.android.internal.infra.AndroidFuture; - -parcelable AppSearchBatchResult; - -/** {@hide} */ -interface IAppSearchManager { - /** - * Sets the schema. - * - * @param schemaBytes Serialized SchemaProto. - * @param forceOverride Whether to apply the new schema even if it is incompatible. All - * incompatible documents will be deleted. - * @param callback {@link AndroidFuture}<{@link Void}>. Will be completed with - * {@code null} upon successful completion of the setSchema call, or completed - * exceptionally if setSchema fails. - */ - void setSchema(in byte[] schemaBytes, boolean forceOverride, in AndroidFuture callback); - - /** - * Inserts documents into the index. - * - * @param documentsBytes {@link List}<byte[]> of serialized DocumentProtos. - * @param callback - * {@link AndroidFuture}<{@link AppSearchBatchResult}<{@link String}, {@link Void}>>. - * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise, - * {@code callback} will be completed with an - * {@link AppSearchBatchResult}<{@link String}, {@link Void}> - * where the keys are document URIs, and the values are {@code null}. - */ - void putDocuments(in List documentsBytes, in AndroidFuture<AppSearchBatchResult> callback); - - /** - * Searches a document based on a given specifications. - * - * @param searchSpecBytes Serialized SearchSpecProto. - * @param resultSpecBytes Serialized SearchResultsProto. - * @param scoringSpecBytes Serialized ScoringSpecProto. - * @param callback {@link AndroidFuture}. Will be completed with a serialized - * {@link SearchResultsProto}, or completed exceptionally if query fails. - */ - void query(in byte[] searchSpecBytes, in byte[] resultSpecBytes, - in byte[] scoringSpecBytes, in AndroidFuture callback); -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/IllegalSchemaException.java b/apex/appsearch/framework/java/android/app/appsearch/IllegalSchemaException.java deleted file mode 100644 index f9e528cd2951..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/IllegalSchemaException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; - -/** - * Indicates that a {@link android.app.appsearch.AppSearchSchema} has logical inconsistencies such - * as unpopulated mandatory fields or illegal combinations of parameters. - * - * @hide - */ -public class IllegalSchemaException extends IllegalArgumentException { - /** - * Constructs a new {@link IllegalSchemaException}. - * - * @param message A developer-readable description of the issue with the bundle. - */ - public IllegalSchemaException(@NonNull String message) { - super(message); - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/IllegalSearchSpecException.java b/apex/appsearch/framework/java/android/app/appsearch/IllegalSearchSpecException.java deleted file mode 100644 index 0d029f029ee5..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/IllegalSearchSpecException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; - -/** - * Indicates that a {@link android.app.appsearch.SearchResults} has logical inconsistencies such - * as unpopulated mandatory fields or illegal combinations of parameters. - * - * @hide - */ -public class IllegalSearchSpecException extends IllegalArgumentException { - /** - * Constructs a new {@link IllegalSearchSpecException}. - * - * @param message A developer-readable description of the issue with the bundle. - */ - public IllegalSearchSpecException(@NonNull String message) { - super(message); - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/MatchInfo.java b/apex/appsearch/framework/java/android/app/appsearch/MatchInfo.java deleted file mode 100644 index 5ce296082d70..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/MatchInfo.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; -import android.util.Range; - -import com.google.android.icing.proto.SnippetMatchProto; - -/** - * Snippet: It refers to a substring of text from the content of document that is returned as a - * part of search result. - * This class represents a match objects for any Snippets that might be present in - * {@link SearchResults} from query. Using this class user can get the full text, exact matches and - * Snippets of document content for a given match. - * - * <p>Class Example 1: - * A document contains following text in property subject: - * <p>A commonly used fake word is foo. Another nonsense word that’s used a lot is bar. - * - * <p>If the queryExpression is "foo". - * - * <p>{@link MatchInfo#getPropertyPath()} returns "subject" - * <p>{@link MatchInfo#getFullText()} returns "A commonly used fake word is foo. Another nonsense - * word that’s used a lot is bar." - * <p>{@link MatchInfo#getExactMatchPosition()} returns [29, 32] - * <p>{@link MatchInfo#getExactMatch()} returns "foo" - * <p>{@link MatchInfo#getSnippetPosition()} returns [29, 41] - * <p>{@link MatchInfo#getSnippet()} returns "is foo. Another" - * <p> - * <p>Class Example 2: - * A document contains a property name sender which contains 2 property names name and email, so - * we will have 2 property paths: {@code sender.name} and {@code sender.email}. - * <p> Let {@code sender.name = "Test Name Jr."} and {@code sender.email = "TestNameJr@gmail.com"} - * - * <p>If the queryExpression is "Test". We will have 2 matches. - * - * <p> Match-1 - * <p>{@link MatchInfo#getPropertyPath()} returns "sender.name" - * <p>{@link MatchInfo#getFullText()} returns "Test Name Jr." - * <p>{@link MatchInfo#getExactMatchPosition()} returns [0, 4] - * <p>{@link MatchInfo#getExactMatch()} returns "Test" - * <p>{@link MatchInfo#getSnippetPosition()} returns [0, 9] - * <p>{@link MatchInfo#getSnippet()} returns "Test Name Jr." - * <p> Match-2 - * <p>{@link MatchInfo#getPropertyPath()} returns "sender.email" - * <p>{@link MatchInfo#getFullText()} returns "TestNameJr@gmail.com" - * <p>{@link MatchInfo#getExactMatchPosition()} returns [0, 20] - * <p>{@link MatchInfo#getExactMatch()} returns "TestNameJr@gmail.com" - * <p>{@link MatchInfo#getSnippetPosition()} returns [0, 20] - * <p>{@link MatchInfo#getSnippet()} returns "TestNameJr@gmail.com" - * @hide - */ -// TODO(sidchhabra): Capture real snippet after integration with icingLib. -public final class MatchInfo { - - private final String mPropertyPath; - private final SnippetMatchProto mSnippetMatch; - private final AppSearchDocument mDocument; - /** - * List of content with same property path in a document when there are multiple matches in - * repeated sections. - */ - private final String[] mValues; - - /** @hide */ - public MatchInfo(@NonNull String propertyPath, @NonNull SnippetMatchProto snippetMatch, - @NonNull AppSearchDocument document) { - mPropertyPath = propertyPath; - mSnippetMatch = snippetMatch; - mDocument = document; - // In IcingLib snippeting is available for only 3 data types i.e String, double and long, - // so we need to check which of these three are requested. - // TODO (sidchhabra): getPropertyStringArray takes property name, handle for property path. - String[] values = mDocument.getPropertyStringArray(propertyPath); - if (values == null) { - values = doubleToString(mDocument.getPropertyDoubleArray(propertyPath)); - } - if (values == null) { - values = longToString(mDocument.getPropertyLongArray(propertyPath)); - } - if (values == null) { - throw new IllegalStateException("No content found for requested property path!"); - } - mValues = values; - } - - /** - * Gets the property path corresponding to the given entry. - * <p>Property Path: '.' - delimited sequence of property names indicating which property in - * the Document these snippets correspond to. - * <p>Example properties: 'body', 'sender.name', 'sender.emailaddress', etc. - * For class example 1 this returns "subject" - */ - @NonNull - public String getPropertyPath() { - return mPropertyPath; - } - - /** - * Gets the full text corresponding to the given entry. - * <p>For class example this returns "A commonly used fake word is foo. Another nonsense word - * that’s used a lot is bar." - */ - @NonNull - public String getFullText() { - return mValues[mSnippetMatch.getValuesIndex()]; - } - - /** - * Gets the exact match range corresponding to the given entry. - * <p>For class example 1 this returns [29, 32] - */ - @NonNull - public Range getExactMatchPosition() { - return new Range(mSnippetMatch.getExactMatchPosition(), - mSnippetMatch.getExactMatchPosition() + mSnippetMatch.getExactMatchBytes()); - } - - /** - * Gets the exact match corresponding to the given entry. - * <p>For class example 1 this returns "foo" - */ - @NonNull - public CharSequence getExactMatch() { - return getSubstring(getExactMatchPosition()); - } - - /** - * Gets the snippet range corresponding to the given entry. - * <p>For class example 1 this returns [29, 41] - */ - @NonNull - public Range getSnippetPosition() { - return new Range(mSnippetMatch.getWindowPosition(), - mSnippetMatch.getWindowPosition() + mSnippetMatch.getWindowBytes()); - } - - /** - * Gets the snippet corresponding to the given entry. - * <p>Snippet - Provides a subset of the content to display. The - * length of this content can be changed {@link SearchSpec.Builder#setMaxSnippetSize(int)}. - * Windowing is centered around the middle of the matched token with content on either side - * clipped to token boundaries. - * <p>For class example 1 this returns "foo. Another" - */ - @NonNull - public CharSequence getSnippet() { - return getSubstring(getSnippetPosition()); - } - - private CharSequence getSubstring(Range range) { - return getFullText() - .substring((int) range.getLower(), (int) range.getUpper()); - } - - /** Utility method to convert double[] to String[] */ - private String[] doubleToString(double[] values) { - //TODO(sidchhabra): Implement the method. - return null; - } - - /** Utility method to convert long[] to String[] */ - private String[] longToString(long[] values) { - //TODO(sidchhabra): Implement the method. - return null; - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java deleted file mode 100644 index 7287fe68f519..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.NonNull; -import android.annotation.Nullable; - -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.SnippetMatchProto; -import com.google.android.icing.proto.SnippetProto; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; - -/** - * SearchResults are a list of results that are returned from a query. Each result from this - * list contains a document and may contain other fields like snippets based on request. - * This iterator class is not thread safe. - * @hide - */ -public final class SearchResults implements Iterator<SearchResults.Result> { - - private final SearchResultProto mSearchResultProto; - private int mNextIdx; - - /** @hide */ - public SearchResults(SearchResultProto searchResultProto) { - mSearchResultProto = searchResultProto; - } - - @Override - public boolean hasNext() { - return mNextIdx < mSearchResultProto.getResultsCount(); - } - - @NonNull - @Override - public Result next() { - if (!hasNext()) { - throw new NoSuchElementException(); - } - Result result = new Result(mSearchResultProto.getResults(mNextIdx)); - mNextIdx++; - return result; - } - - - - /** - * This class represents the result obtained from the query. It will contain the document which - * which matched the specified query string and specifications. - * @hide - */ - public static final class Result { - private final SearchResultProto.ResultProto mResultProto; - - @Nullable - private AppSearchDocument mDocument; - - private Result(SearchResultProto.ResultProto resultProto) { - mResultProto = resultProto; - } - - /** - * Contains the matching {@link AppSearchDocument}. - * @return Document object which matched the query. - * @hide - */ - @NonNull - public AppSearchDocument getDocument() { - if (mDocument == null) { - mDocument = new AppSearchDocument(mResultProto.getDocument()); - } - return mDocument; - } - - /** - * Contains a list of Snippets that matched the request. Only populated when requested in - * {@link SearchSpec.Builder#setMaxSnippetSize(int)}. - * @return List of matches based on {@link SearchSpec}, if snippeting is disabled and this - * method is called it will return {@code null}. Users can also restrict snippet population - * using {@link SearchSpec.Builder#setNumToSnippet} and - * {@link SearchSpec.Builder#setNumMatchesPerProperty}, for all results after that value - * this method will return {@code null}. - * @hide - */ - // TODO(sidchhabra): Replace Document with proper constructor. - @Nullable - public List<MatchInfo> getMatchInfo() { - if (!mResultProto.hasSnippet()) { - return null; - } - AppSearchDocument document = getDocument(); - List<MatchInfo> matchList = new ArrayList<>(); - for (Iterator entryProtoIterator = mResultProto.getSnippet() - .getEntriesList().iterator(); entryProtoIterator.hasNext(); ) { - SnippetProto.EntryProto entry = (SnippetProto.EntryProto) entryProtoIterator.next(); - for (Iterator snippetMatchProtoIterator = entry.getSnippetMatchesList().iterator(); - snippetMatchProtoIterator.hasNext(); ) { - matchList.add(new MatchInfo(entry.getPropertyName(), - (SnippetMatchProto) snippetMatchProtoIterator.next(), document)); - } - } - return matchList; - } - } - - @Override - public String toString() { - return mSearchResultProto.toString(); - } -} diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java b/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java deleted file mode 100644 index c276ae1fe45e..000000000000 --- a/apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import android.annotation.IntDef; -import android.annotation.NonNull; - -import com.google.android.icing.proto.ResultSpecProto; -import com.google.android.icing.proto.ScoringSpecProto; -import com.google.android.icing.proto.SearchSpecProto; -import com.google.android.icing.proto.TermMatchType; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - - -/** - * This class represents the specification logic for AppSearch. It can be used to set the type of - * search, like prefix or exact only or apply filters to search for a specific schema type only etc. - * @hide - */ -// TODO(sidchhabra) : AddResultSpec fields for Snippets etc. -public final class SearchSpec { - - private final SearchSpecProto mSearchSpecProto; - private final ResultSpecProto mResultSpecProto; - private final ScoringSpecProto mScoringSpecProto; - - private SearchSpec(@NonNull SearchSpecProto searchSpecProto, - @NonNull ResultSpecProto resultSpecProto, @NonNull ScoringSpecProto scoringSpecProto) { - mSearchSpecProto = searchSpecProto; - mResultSpecProto = resultSpecProto; - mScoringSpecProto = scoringSpecProto; - } - - /** Creates a new {@link SearchSpec.Builder}. */ - @NonNull - public static SearchSpec.Builder newBuilder() { - return new SearchSpec.Builder(); - } - - /** @hide */ - @NonNull - SearchSpecProto getSearchSpecProto() { - return mSearchSpecProto; - } - - /** @hide */ - @NonNull - ResultSpecProto getResultSpecProto() { - return mResultSpecProto; - } - - /** @hide */ - @NonNull - ScoringSpecProto getScoringSpecProto() { - return mScoringSpecProto; - } - - /** Term Match Type for the query. */ - // NOTE: The integer values of these constants must match the proto enum constants in - // {@link com.google.android.icing.proto.SearchSpecProto.termMatchType} - @IntDef(prefix = {"TERM_MATCH_TYPE_"}, value = { - TERM_MATCH_TYPE_EXACT_ONLY, - TERM_MATCH_TYPE_PREFIX - }) - @Retention(RetentionPolicy.SOURCE) - public @interface TermMatchTypeCode {} - - /** - * Query terms will only match exact tokens in the index. - * <p>Ex. A query term "foo" will only match indexed token "foo", and not "foot" or "football". - */ - public static final int TERM_MATCH_TYPE_EXACT_ONLY = 1; - /** - * Query terms will match indexed tokens when the query term is a prefix of the token. - * <p>Ex. A query term "foo" will match indexed tokens like "foo", "foot", and "football". - */ - public static final int TERM_MATCH_TYPE_PREFIX = 2; - - /** Ranking Strategy for query result.*/ - // NOTE: The integer values of these constants must match the proto enum constants in - // {@link ScoringSpecProto.RankingStrategy.Code } - @IntDef(prefix = {"RANKING_STRATEGY_"}, value = { - RANKING_STRATEGY_NONE, - RANKING_STRATEGY_DOCUMENT_SCORE, - RANKING_STRATEGY_CREATION_TIMESTAMP - }) - @Retention(RetentionPolicy.SOURCE) - public @interface RankingStrategyCode {} - - /** No Ranking, results are returned in arbitrary order.*/ - public static final int RANKING_STRATEGY_NONE = 0; - /** Ranked by app-provided document scores. */ - public static final int RANKING_STRATEGY_DOCUMENT_SCORE = 1; - /** Ranked by document creation timestamps. */ - public static final int RANKING_STRATEGY_CREATION_TIMESTAMP = 2; - - /** Order for query result.*/ - // NOTE: The integer values of these constants must match the proto enum constants in - // {@link ScoringSpecProto.Order.Code } - @IntDef(prefix = {"ORDER_"}, value = { - ORDER_DESCENDING, - ORDER_ASCENDING - }) - @Retention(RetentionPolicy.SOURCE) - public @interface OrderCode {} - - /** Search results will be returned in a descending order. */ - public static final int ORDER_DESCENDING = 0; - /** Search results will be returned in an ascending order. */ - public static final int ORDER_ASCENDING = 1; - - /** Builder for {@link SearchSpec objects}. */ - public static final class Builder { - - private final SearchSpecProto.Builder mSearchSpecBuilder = SearchSpecProto.newBuilder(); - private final ResultSpecProto.Builder mResultSpecBuilder = ResultSpecProto.newBuilder(); - private final ScoringSpecProto.Builder mScoringSpecBuilder = ScoringSpecProto.newBuilder(); - private final ResultSpecProto.SnippetSpecProto.Builder mSnippetSpecBuilder = - ResultSpecProto.SnippetSpecProto.newBuilder(); - - private Builder() { - } - - /** - * Indicates how the query terms should match {@link TermMatchTypeCode} in the index. - */ - @NonNull - public Builder setTermMatchType(@TermMatchTypeCode int termMatchTypeCode) { - TermMatchType.Code termMatchTypeCodeProto = - TermMatchType.Code.forNumber(termMatchTypeCode); - if (termMatchTypeCodeProto == null) { - throw new IllegalArgumentException("Invalid term match type: " - + termMatchTypeCode); - } - mSearchSpecBuilder.setTermMatchType(termMatchTypeCodeProto); - return this; - } - - /** - * Adds a Schema type filter to {@link SearchSpec} Entry. Only search for documents that - * have the specified schema types. - * <p>If unset, the query will search over all schema types. - */ - @NonNull - public Builder setSchemaTypes(@NonNull String... schemaTypes) { - for (String schemaType : schemaTypes) { - mSearchSpecBuilder.addSchemaTypeFilters(schemaType); - } - return this; - } - - /** Sets the maximum number of results to retrieve from the query */ - @NonNull - public SearchSpec.Builder setNumToRetrieve(int numToRetrieve) { - mResultSpecBuilder.setNumToRetrieve(numToRetrieve); - return this; - } - - /** Sets ranking strategy for AppSearch results.*/ - @NonNull - public Builder setRankingStrategy(@RankingStrategyCode int rankingStrategy) { - ScoringSpecProto.RankingStrategy.Code rankingStrategyCodeProto = - ScoringSpecProto.RankingStrategy.Code.forNumber(rankingStrategy); - if (rankingStrategyCodeProto == null) { - throw new IllegalArgumentException("Invalid result ranking strategy: " - + rankingStrategyCodeProto); - } - mScoringSpecBuilder.setRankBy(rankingStrategyCodeProto); - return this; - } - - /** - * Indicates the order of returned search results, the default is DESC, meaning that results - * with higher scores come first. - * <p>This order field will be ignored if RankingStrategy = {@code RANKING_STRATEGY_NONE}. - */ - @NonNull - public Builder setOrder(@OrderCode int order) { - ScoringSpecProto.Order.Code orderCodeProto = - ScoringSpecProto.Order.Code.forNumber(order); - if (orderCodeProto == null) { - throw new IllegalArgumentException("Invalid result ranking order: " - + orderCodeProto); - } - mScoringSpecBuilder.setOrderBy(orderCodeProto); - return this; - } - - /** - * Only the first {@code numToSnippet} documents based on the ranking strategy - * will have snippet information provided. - * <p>If set to 0 (default), snippeting is disabled and - * {@link SearchResults.Result#getMatchInfo} will return {@code null} for that result. - */ - @NonNull - public SearchSpec.Builder setNumToSnippet(int numToSnippet) { - mSnippetSpecBuilder.setNumToSnippet(numToSnippet); - return this; - } - - /** - * Only the first {@code numMatchesPerProperty} matches for a every property of - * {@link AppSearchDocument} will contain snippet information. - * <p>If set to 0, snippeting is disabled and {@link SearchResults.Result#getMatchInfo} - * will return {@code null} for that result. - */ - @NonNull - public SearchSpec.Builder setNumMatchesPerProperty(int numMatchesPerProperty) { - mSnippetSpecBuilder.setNumMatchesPerProperty(numMatchesPerProperty); - return this; - } - - /** - * Sets {@code maxSnippetSize}, the maximum snippet size. Snippet windows start at - * {@code maxSnippetSize/2} bytes before the middle of the matching token and end at - * {@code maxSnippetSize/2} bytes after the middle of the matching token. It respects - * token boundaries, therefore the returned window may be smaller than requested. - * <p> Setting {@code maxSnippetSize} to 0 will disable windowing and an empty string will - * be returned. If matches enabled is also set to false, then snippeting is disabled. - * <p>Ex. {@code maxSnippetSize} = 16. "foo bar baz bat rat" with a query of "baz" will - * return a window of "bar baz bat" which is only 11 bytes long. - */ - @NonNull - public SearchSpec.Builder setMaxSnippetSize(int maxSnippetSize) { - mSnippetSpecBuilder.setMaxWindowBytes(maxSnippetSize); - return this; - } - - /** - * Constructs a new {@link SearchSpec} from the contents of this builder. - * - * <p>After calling this method, the builder must no longer be used. - */ - @NonNull - public SearchSpec build() { - if (mSearchSpecBuilder.getTermMatchType() == TermMatchType.Code.UNKNOWN) { - throw new IllegalSearchSpecException("Missing termMatchType field."); - } - mResultSpecBuilder.setSnippetSpec(mSnippetSpecBuilder); - return new SearchSpec(mSearchSpecBuilder.build(), mResultSpecBuilder.build(), - mScoringSpecBuilder.build()); - } - } -} diff --git a/apex/appsearch/service/Android.bp b/apex/appsearch/service/Android.bp deleted file mode 100644 index 04f385e8c6f6..000000000000 --- a/apex/appsearch/service/Android.bp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2019 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -java_library { - name: "service-appsearch", - installable: true, - srcs: ["java/**/*.java"], - libs: [ - "framework", - "framework-appsearch", - "services.core", - ], - apex_available: ["com.android.appsearch"], -} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java deleted file mode 100644 index 6293ee7059e5..000000000000 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.server.appsearch; - -import android.annotation.NonNull; -import android.app.appsearch.AppSearchBatchResult; -import android.app.appsearch.IAppSearchManager; -import android.content.Context; -import android.os.Binder; -import android.os.UserHandle; - -import com.android.internal.infra.AndroidFuture; -import com.android.internal.util.Preconditions; -import com.android.server.SystemService; -import com.android.server.appsearch.impl.AppSearchImpl; -import com.android.server.appsearch.impl.FakeIcing; -import com.android.server.appsearch.impl.ImplInstanceManager; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.SchemaProto; -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.SearchSpecProto; -import com.google.android.icing.protobuf.InvalidProtocolBufferException; - -import java.util.List; - -/** - * TODO(b/142567528): add comments when implement this class - */ -public class AppSearchManagerService extends SystemService { - - public AppSearchManagerService(Context context) { - super(context); - mFakeIcing = new FakeIcing(); - } - - private final FakeIcing mFakeIcing; - - @Override - public void onStart() { - publishBinderService(Context.APP_SEARCH_SERVICE, new Stub()); - } - - private class Stub extends IAppSearchManager.Stub { - @Override - public void setSchema(byte[] schemaBytes, boolean forceOverride, AndroidFuture callback) { - Preconditions.checkNotNull(schemaBytes); - Preconditions.checkNotNull(callback); - int callingUid = Binder.getCallingUidOrThrow(); - int callingUserId = UserHandle.getUserId(callingUid); - long callingIdentity = Binder.clearCallingIdentity(); - try { - SchemaProto schema = SchemaProto.parseFrom(schemaBytes); - AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); - impl.setSchema(callingUid, schema, forceOverride); - callback.complete(null); - } catch (Throwable t) { - callback.completeExceptionally(t); - } finally { - Binder.restoreCallingIdentity(callingIdentity); - } - } - - @Override - public void putDocuments( - List documentsBytes, AndroidFuture<AppSearchBatchResult> callback) { - Preconditions.checkNotNull(documentsBytes); - Preconditions.checkNotNull(callback); - int callingUid = Binder.getCallingUidOrThrow(); - int callingUserId = UserHandle.getUserId(callingUid); - long callingIdentity = Binder.clearCallingIdentity(); - try { - AppSearchImpl impl = ImplInstanceManager.getInstance(getContext(), callingUserId); - AppSearchBatchResult.Builder<String, Void> resultBuilder = - AppSearchBatchResult.newBuilder(); - for (int i = 0; i < documentsBytes.size(); i++) { - byte[] documentBytes = (byte[]) documentsBytes.get(i); - DocumentProto document = DocumentProto.parseFrom(documentBytes); - try { - impl.putDocument(callingUid, document); - resultBuilder.setSuccess(document.getUri(), /*value=*/ null); - } catch (Throwable t) { - resultBuilder.setFailure(document.getUri(), t); - } - } - callback.complete(resultBuilder.build()); - } catch (Throwable t) { - callback.completeExceptionally(t); - } finally { - Binder.restoreCallingIdentity(callingIdentity); - } - } - // TODO(sidchhabra):Init FakeIcing properly. - // TODO(sidchhabra): Do this in a threadpool. - @Override - public void query(@NonNull byte[] searchSpec, @NonNull byte[] resultSpec, - @NonNull byte[] scoringSpec, AndroidFuture callback) { - Preconditions.checkNotNull(searchSpec); - Preconditions.checkNotNull(resultSpec); - Preconditions.checkNotNull(scoringSpec); - SearchSpecProto searchSpecProto = null; - try { - searchSpecProto = SearchSpecProto.parseFrom(searchSpec); - } catch (InvalidProtocolBufferException e) { - throw new RuntimeException(e); - } - SearchResultProto searchResults = - mFakeIcing.query(searchSpecProto.getQuery()); - callback.complete(searchResults.toByteArray()); - } - } -} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING b/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING deleted file mode 100644 index ca5b8841ea49..000000000000 --- a/apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING +++ /dev/null @@ -1,23 +0,0 @@ -{ - "presubmit": [ - { - "name": "CtsAppSearchTestCases" - }, - { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.appsearch" - } - ] - }, - { - "name": "FrameworksCoreTests", - "options": [ - { - "include-filter": "android.app.appsearch" - } - ] - } - ] -} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java deleted file mode 100644 index 04b4b1427328..000000000000 --- a/apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.appsearch.impl; - -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.content.Context; - -import com.android.internal.annotations.VisibleForTesting; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyConfigProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.proto.SchemaProto; -import com.google.android.icing.proto.SchemaTypeConfigProto; - -/** - * Manages interaction with {@link FakeIcing} and other components to implement AppSearch - * functionality. - */ -public final class AppSearchImpl { - private final Context mContext; - private final @UserIdInt int mUserId; - private final FakeIcing mFakeIcing = new FakeIcing(); - - AppSearchImpl(@NonNull Context context, @UserIdInt int userId) { - mContext = context; - mUserId = userId; - } - - /** - * Updates the AppSearch schema for this app. - * - * @param callingUid The uid of the app calling AppSearch. - * @param origSchema The schema to set for this app. - * @param forceOverride Whether to force-apply the schema even if it is incompatible. Documents - * which do not comply with the new schema will be deleted. - */ - public void setSchema(int callingUid, @NonNull SchemaProto origSchema, boolean forceOverride) { - // Rewrite schema type names to include the calling app's package and uid. - String typePrefix = getTypePrefix(callingUid); - SchemaProto.Builder schemaBuilder = origSchema.toBuilder(); - rewriteSchemaTypes(typePrefix, schemaBuilder); - - // TODO(b/145635424): Save in schema type map - // TODO(b/145635424): Apply the schema to Icing and report results - } - - /** - * Rewrites all types mentioned in the given {@code schemaBuilder} to prepend - * {@code typePrefix}. - * - * @param typePrefix The prefix to add - * @param schemaBuilder The schema to mutate - */ - @VisibleForTesting - void rewriteSchemaTypes( - @NonNull String typePrefix, @NonNull SchemaProto.Builder schemaBuilder) { - for (int typeIdx = 0; typeIdx < schemaBuilder.getTypesCount(); typeIdx++) { - SchemaTypeConfigProto.Builder typeConfigBuilder = - schemaBuilder.getTypes(typeIdx).toBuilder(); - - // Rewrite SchemaProto.types.schema_type - String newSchemaType = typePrefix + typeConfigBuilder.getSchemaType(); - typeConfigBuilder.setSchemaType(newSchemaType); - - // Rewrite SchemaProto.types.properties.schema_type - for (int propertyIdx = 0; - propertyIdx < typeConfigBuilder.getPropertiesCount(); - propertyIdx++) { - PropertyConfigProto.Builder propertyConfigBuilder = - typeConfigBuilder.getProperties(propertyIdx).toBuilder(); - if (!propertyConfigBuilder.getSchemaType().isEmpty()) { - String newPropertySchemaType = - typePrefix + propertyConfigBuilder.getSchemaType(); - propertyConfigBuilder.setSchemaType(newPropertySchemaType); - typeConfigBuilder.setProperties(propertyIdx, propertyConfigBuilder); - } - } - - schemaBuilder.setTypes(typeIdx, typeConfigBuilder); - } - } - - /** - * Adds a document to the AppSearch index. - * - * @param callingUid The uid of the app calling AppSearch. - * @param origDocument The document to index. - */ - public void putDocument(int callingUid, @NonNull DocumentProto origDocument) { - // Rewrite the type names to include the app's prefix - String typePrefix = getTypePrefix(callingUid); - DocumentProto.Builder documentBuilder = origDocument.toBuilder(); - rewriteDocumentTypes(typePrefix, documentBuilder); - mFakeIcing.put(documentBuilder.build()); - } - - /** - * Rewrites all types mentioned anywhere in {@code documentBuilder} to prepend - * {@code typePrefix}. - * - * @param typePrefix The prefix to add - * @param documentBuilder The document to mutate - */ - @VisibleForTesting - void rewriteDocumentTypes( - @NonNull String typePrefix, - @NonNull DocumentProto.Builder documentBuilder) { - // Rewrite the type name to include the app's prefix - String newSchema = typePrefix + documentBuilder.getSchema(); - documentBuilder.setSchema(newSchema); - - // Add namespace. If we ever allow users to set their own namespaces, this will have - // to change to prepend the prefix instead of setting the whole namespace. We will also have - // to store the namespaces in a map similar to the type map so we can rewrite queries with - // empty namespaces. - documentBuilder.setNamespace(typePrefix); - - // Recurse into derived documents - for (int propertyIdx = 0; - propertyIdx < documentBuilder.getPropertiesCount(); - propertyIdx++) { - int documentCount = documentBuilder.getProperties(propertyIdx).getDocumentValuesCount(); - if (documentCount > 0) { - PropertyProto.Builder propertyBuilder = - documentBuilder.getProperties(propertyIdx).toBuilder(); - for (int documentIdx = 0; documentIdx < documentCount; documentIdx++) { - DocumentProto.Builder derivedDocumentBuilder = - propertyBuilder.getDocumentValues(documentIdx).toBuilder(); - rewriteDocumentTypes(typePrefix, derivedDocumentBuilder); - propertyBuilder.setDocumentValues(documentIdx, derivedDocumentBuilder); - } - documentBuilder.setProperties(propertyIdx, propertyBuilder); - } - } - } - - /** - * Returns a type prefix in a format like {@code com.example.package@1000/} or - * {@code com.example.sharedname:5678@1000/}. - */ - @NonNull - private String getTypePrefix(int callingUid) { - // For regular apps, this call will return the package name. If callingUid is an - // android:sharedUserId, this value may be another type of name and have a :uid suffix. - String callingUidName = mContext.getPackageManager().getNameForUid(callingUid); - if (callingUidName == null) { - // Not sure how this is possible --- maybe app was uninstalled? - throw new IllegalStateException("Failed to look up package name for uid " + callingUid); - } - return callingUidName + "@" + mUserId + "/"; - } -} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java deleted file mode 100644 index d07ef4bc3bf5..000000000000 --- a/apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.appsearch.impl; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.util.ArrayMap; -import android.util.ArraySet; -import android.util.SparseArray; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.StatusProto; - -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Fake in-memory implementation of the Icing key-value store and reverse index. - * <p> - * Currently, only queries by single exact term are supported. There is no support for persistence, - * namespaces, i18n tokenization, or schema. - */ -public class FakeIcing { - private final AtomicInteger mNextDocId = new AtomicInteger(); - private final Map<String, Integer> mUriToDocIdMap = new ArrayMap<>(); - /** Array of Documents where index into the array is the docId. */ - private final SparseArray<DocumentProto> mDocStore = new SparseArray<>(); - /** Map of term to posting-list (the set of DocIds containing that term). */ - private final Map<String, Set<Integer>> mIndex = new ArrayMap<>(); - - /** - * Inserts a document into the index. - * - * @param document The document to insert. - */ - public void put(@NonNull DocumentProto document) { - String uri = document.getUri(); - - // Update mDocIdMap - Integer docId = mUriToDocIdMap.get(uri); - if (docId != null) { - // Delete the old doc - mDocStore.remove(docId); - } - - // Allocate a new docId - docId = mNextDocId.getAndIncrement(); - mUriToDocIdMap.put(uri, docId); - - // Update mDocStore - mDocStore.put(docId, document); - - // Update mIndex - indexDocument(docId, document); - } - - /** - * Retrieves a document from the index. - * - * @param uri The URI of the document to retrieve. - * @return The body of the document, or {@code null} if no such document exists. - */ - @Nullable - public DocumentProto get(@NonNull String uri) { - Integer docId = mUriToDocIdMap.get(uri); - if (docId == null) { - return null; - } - return mDocStore.get(docId); - } - - /** - * Returns documents containing the given term. - * - * @param term A single exact term to look up in the index. - * @return A {@link SearchResultProto} containing the matching documents, which may have no - * results if no documents match. - */ - @NonNull - public SearchResultProto query(@NonNull String term) { - String normTerm = normalizeString(term); - Set<Integer> docIds = mIndex.get(normTerm); - SearchResultProto.Builder results = SearchResultProto.newBuilder() - .setStatus(StatusProto.newBuilder().setCode(StatusProto.Code.OK)); - if (docIds == null || docIds.isEmpty()) { - return results.build(); - } - - for (int docId : docIds) { - DocumentProto document = mDocStore.get(docId); - if (document != null) { - results.addResults( - SearchResultProto.ResultProto.newBuilder().setDocument(document)); - } - } - return results.build(); - } - - /** - * Deletes a document by its URI. - * - * @param uri The URI of the document to be deleted. - */ - public void delete(@NonNull String uri) { - // Update mDocIdMap - Integer docId = mUriToDocIdMap.get(uri); - if (docId != null) { - // Delete the old doc - mDocStore.remove(docId); - mUriToDocIdMap.remove(uri); - } - } - - private void indexDocument(int docId, DocumentProto document) { - for (PropertyProto property : document.getPropertiesList()) { - for (String stringValue : property.getStringValuesList()) { - String[] words = normalizeString(stringValue).split("\\s+"); - for (String word : words) { - indexTerm(docId, word); - } - } - for (Long longValue : property.getInt64ValuesList()) { - indexTerm(docId, longValue.toString()); - } - for (Double doubleValue : property.getDoubleValuesList()) { - indexTerm(docId, doubleValue.toString()); - } - for (Boolean booleanValue : property.getBooleanValuesList()) { - indexTerm(docId, booleanValue.toString()); - } - // Intentionally skipping bytes values - for (DocumentProto documentValue : property.getDocumentValuesList()) { - indexDocument(docId, documentValue); - } - } - } - - private void indexTerm(int docId, String term) { - Set<Integer> postingList = mIndex.get(term); - if (postingList == null) { - postingList = new ArraySet<>(); - mIndex.put(term, postingList); - } - postingList.add(docId); - } - - /** Strips out punctuation and converts to lowercase. */ - private static String normalizeString(String input) { - return input.replaceAll("\\p{P}", "").toLowerCase(Locale.getDefault()); - } -} diff --git a/apex/appsearch/service/java/com/android/server/appsearch/impl/ImplInstanceManager.java b/apex/appsearch/service/java/com/android/server/appsearch/impl/ImplInstanceManager.java deleted file mode 100644 index 395e30e89dc0..000000000000 --- a/apex/appsearch/service/java/com/android/server/appsearch/impl/ImplInstanceManager.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.appsearch.impl; - -import android.annotation.NonNull; -import android.annotation.UserIdInt; -import android.content.Context; -import android.util.SparseArray; - -/** - * Manages the lifecycle of instances of {@link AppSearchImpl}. - * - * <p>These instances are managed per unique device-user. - */ -public final class ImplInstanceManager { - private static final SparseArray<AppSearchImpl> sInstances = new SparseArray<>(); - - /** - * Gets an instance of AppSearchImpl for the given user. - * - * <p>If no AppSearchImpl instance exists for this user, Icing will be initialized and one will - * be created. - * - * @param context The Android context - * @param userId The multi-user userId of the device user calling AppSearch - * @return An initialized {@link AppSearchImpl} for this user - */ - @NonNull - public static AppSearchImpl getInstance(@NonNull Context context, @UserIdInt int userId) { - AppSearchImpl instance = sInstances.get(userId); - if (instance == null) { - synchronized (ImplInstanceManager.class) { - instance = sInstances.get(userId); - if (instance == null) { - instance = new AppSearchImpl(context, userId); - sInstances.put(userId, instance); - } - } - } - return instance; - } -} diff --git a/api/system-current.txt b/api/system-current.txt index f84b4158da08..b92014fac157 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -921,14 +921,6 @@ package android.app.admin { } -package android.app.appsearch { - - public class AppSearchManagerFrameworkInitializer { - method public static void initialize(); - } - -} - package android.app.assist { public static class AssistStructure.ViewNode { diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4369680e7781..bec1896f31bd 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -23,7 +23,6 @@ import android.annotation.SystemApi; import android.app.ContextImpl.ServiceInitializationState; import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; -import android.app.appsearch.AppSearchManagerFrameworkInitializer; import android.app.blob.BlobStoreManagerFrameworkInitializer; import android.app.contentsuggestions.ContentSuggestionsManager; import android.app.contentsuggestions.IContentSuggestionsManager; @@ -1342,7 +1341,6 @@ public final class SystemServiceRegistry { JobSchedulerFrameworkInitializer.registerServiceWrappers(); BlobStoreManagerFrameworkInitializer.initialize(); TelephonyFrameworkInitializer.registerServiceWrappers(); - AppSearchManagerFrameworkInitializer.initialize(); WifiFrameworkInitializer.registerServiceWrappers(); StatsFrameworkInitializer.registerServiceWrappers(); } finally { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index c6e84b7e46b0..5f78cb8197f2 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5108,16 +5108,6 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.app.appsearch.AppSearchManager} for - * indexing and querying app data managed by the system. - * - * @see #getSystemService(String) - * @hide - */ - public static final String APP_SEARCH_SERVICE = "app_search"; - - /** - * Use with {@link #getSystemService(String)} to retrieve an * {@link android.content.integrity.AppIntegrityManager}. * @hide */ diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp index cfd3c0915002..c72668f84fb1 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -33,7 +33,6 @@ // Static whitelist of open paths that the zygote is allowed to keep open. static const char* kPathWhitelist[] = { - "/apex/com.android.appsearch/javalib/framework-appsearch.jar", "/apex/com.android.conscrypt/javalib/conscrypt.jar", "/apex/com.android.ipsec/javalib/ike.jar", "/apex/com.android.media/javalib/updatable-media.jar", diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index eb760b9c45cf..1485df05d525 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -56,7 +56,6 @@ android_test { // TODO(b/149928788): Remove this when statsd tests move into the statsd dir. "framework-statsd", "framework", - "icing-java-proto-lite", "ext", "framework-res", ], diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java deleted file mode 100644 index 4a4f13676cb3..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import static com.google.common.truth.Truth.assertThat; - -import static org.testng.Assert.assertThrows; - -import androidx.test.filters.SmallTest; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.protobuf.ByteString; - -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; - -@SmallTest -public class AppSearchDocumentTest { - private static final byte[] sByteArray1 = new byte[]{(byte) 1, (byte) 2, (byte) 3}; - private static final byte[] sByteArray2 = new byte[]{(byte) 4, (byte) 5, (byte) 6}; - private static final AppSearchDocument sDocumentProperties1 = new AppSearchDocument - .Builder("sDocumentProperties1", "sDocumentPropertiesSchemaType1") - .build(); - private static final AppSearchDocument sDocumentProperties2 = new AppSearchDocument - .Builder("sDocumentProperties2", "sDocumentPropertiesSchemaType2") - .build(); - - @Test - public void testDocumentEquals_Identical() { - AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setTtlMillis(1L) - .setProperty("longKey1", 1L, 2L, 3L) - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("booleanKey1", true, false, true) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .build(); - AppSearchDocument document2 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setTtlMillis(1L) - .setProperty("longKey1", 1L, 2L, 3L) - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("booleanKey1", true, false, true) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .build(); - assertThat(document1).isEqualTo(document2); - assertThat(document1.hashCode()).isEqualTo(document2.hashCode()); - } - - @Test - public void testDocumentEquals_DifferentOrder() { - AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("longKey1", 1L, 2L, 3L) - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("booleanKey1", true, false, true) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .build(); - - // Create second document with same parameter but different order. - AppSearchDocument document2 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("booleanKey1", true, false, true) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("longKey1", 1L, 2L, 3L) - .build(); - assertThat(document1).isEqualTo(document2); - assertThat(document1.hashCode()).isEqualTo(document2.hashCode()); - } - - @Test - public void testDocumentEquals_Failure() { - AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("longKey1", 1L, 2L, 3L) - .build(); - - // Create second document with same order but different value. - AppSearchDocument document2 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("longKey1", 1L, 2L, 4L) // Different - .build(); - assertThat(document1).isNotEqualTo(document2); - assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode()); - } - - @Test - public void testDocumentEquals_Failure_RepeatedFieldOrder() { - AppSearchDocument document1 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("booleanKey1", true, false, true) - .build(); - - // Create second document with same order but different value. - AppSearchDocument document2 = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("booleanKey1", true, true, false) // Different - .build(); - assertThat(document1).isNotEqualTo(document2); - assertThat(document1.hashCode()).isNotEqualTo(document2.hashCode()); - } - - @Test - public void testDocumentGetSingleValue() { - AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setScore(1) - .setTtlMillis(1L) - .setProperty("longKey1", 1L) - .setProperty("doubleKey1", 1.0) - .setProperty("booleanKey1", true) - .setProperty("stringKey1", "test-value1") - .setProperty("byteKey1", sByteArray1) - .setProperty("documentKey1", sDocumentProperties1) - .build(); - assertThat(document.getUri()).isEqualTo("uri1"); - assertThat(document.getTtlMillis()).isEqualTo(1L); - assertThat(document.getSchemaType()).isEqualTo("schemaType1"); - assertThat(document.getCreationTimestampMillis()).isEqualTo(5); - assertThat(document.getScore()).isEqualTo(1); - assertThat(document.getPropertyLong("longKey1")).isEqualTo(1L); - assertThat(document.getPropertyDouble("doubleKey1")).isEqualTo(1.0); - assertThat(document.getPropertyBoolean("booleanKey1")).isTrue(); - assertThat(document.getPropertyString("stringKey1")).isEqualTo("test-value1"); - assertThat(document.getPropertyBytes("byteKey1")) - .asList().containsExactly((byte) 1, (byte) 2, (byte) 3); - assertThat(document.getPropertyDocument("documentKey1")).isEqualTo(sDocumentProperties1); - } - - @Test - public void testDocumentGetArrayValues() { - AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setProperty("longKey1", 1L, 2L, 3L) - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("booleanKey1", true, false, true) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .build(); - - assertThat(document.getUri()).isEqualTo("uri1"); - assertThat(document.getSchemaType()).isEqualTo("schemaType1"); - assertThat(document.getPropertyLongArray("longKey1")).asList().containsExactly(1L, 2L, 3L); - assertThat(document.getPropertyDoubleArray("doubleKey1")).usingExactEquality() - .containsExactly(1.0, 2.0, 3.0); - assertThat(document.getPropertyBooleanArray("booleanKey1")).asList() - .containsExactly(true, false, true); - assertThat(document.getPropertyStringArray("stringKey1")).asList() - .containsExactly("test-value1", "test-value2", "test-value3"); - assertThat(document.getPropertyBytesArray("byteKey1")).asList() - .containsExactly(sByteArray1, sByteArray2); - assertThat(document.getPropertyDocumentArray("documentKey1")).asList() - .containsExactly(sDocumentProperties1, sDocumentProperties2); - } - - @Test - public void testDocumentGetValues_DifferentTypes() { - AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") - .setScore(1) - .setProperty("longKey1", 1L) - .setProperty("booleanKey1", true, false, true) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .build(); - - // Get a value for a key that doesn't exist - assertThat(document.getPropertyDouble("doubleKey1")).isNull(); - assertThat(document.getPropertyDoubleArray("doubleKey1")).isNull(); - - // Get a value with a single element as an array and as a single value - assertThat(document.getPropertyLong("longKey1")).isEqualTo(1L); - assertThat(document.getPropertyLongArray("longKey1")).asList().containsExactly(1L); - - // Get a value with multiple elements as an array and as a single value - assertThat(document.getPropertyString("stringKey1")).isEqualTo("test-value1"); - assertThat(document.getPropertyStringArray("stringKey1")).asList() - .containsExactly("test-value1", "test-value2", "test-value3"); - - // Get a value of the wrong type - assertThat(document.getPropertyDouble("longKey1")).isNull(); - assertThat(document.getPropertyDoubleArray("longKey1")).isNull(); - } - - @Test - public void testDocumentInvalid() { - AppSearchDocument.Builder builder = new AppSearchDocument.Builder("uri1", "schemaType1"); - assertThrows( - IllegalArgumentException.class, () -> builder.setProperty("test", new boolean[]{})); - } - - @Test - public void testDocumentProtoPopulation() { - AppSearchDocument document = new AppSearchDocument.Builder("uri1", "schemaType1") - .setCreationTimestampMillis(5L) - .setScore(1) - .setTtlMillis(1L) - .setProperty("longKey1", 1L) - .setProperty("doubleKey1", 1.0) - .setProperty("booleanKey1", true) - .setProperty("stringKey1", "test-value1") - .setProperty("byteKey1", sByteArray1) - .setProperty("documentKey1", sDocumentProperties1) - .build(); - - // Create the Document proto. Need to sort the property order by key. - DocumentProto.Builder documentProtoBuilder = DocumentProto.newBuilder() - .setUri("uri1") - .setSchema("schemaType1") - .setCreationTimestampMs(5L) - .setScore(1) - .setTtlMs(1L); - HashMap<String, PropertyProto.Builder> propertyProtoMap = new HashMap<>(); - propertyProtoMap.put("longKey1", - PropertyProto.newBuilder().setName("longKey1").addInt64Values(1L)); - propertyProtoMap.put("doubleKey1", - PropertyProto.newBuilder().setName("doubleKey1").addDoubleValues(1.0)); - propertyProtoMap.put("booleanKey1", - PropertyProto.newBuilder().setName("booleanKey1").addBooleanValues(true)); - propertyProtoMap.put("stringKey1", - PropertyProto.newBuilder().setName("stringKey1").addStringValues("test-value1")); - propertyProtoMap.put("byteKey1", - PropertyProto.newBuilder().setName("byteKey1").addBytesValues( - ByteString.copyFrom(sByteArray1))); - propertyProtoMap.put("documentKey1", - PropertyProto.newBuilder().setName("documentKey1") - .addDocumentValues(sDocumentProperties1.getProto())); - List<String> sortedKey = new ArrayList<>(propertyProtoMap.keySet()); - Collections.sort(sortedKey); - for (String key : sortedKey) { - documentProtoBuilder.addProperties(propertyProtoMap.get(key)); - } - assertThat(document.getProto()).isEqualTo(documentProtoBuilder.build()); - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchEmailTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchEmailTest.java deleted file mode 100644 index 6aa16cc1e323..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/AppSearchEmailTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import static com.google.common.truth.Truth.assertThat; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -@SmallTest -public class AppSearchEmailTest { - - @Test - public void testBuildEmailAndGetValue() { - AppSearchEmail email = new AppSearchEmail.Builder("uri") - .setFrom("FakeFromAddress") - .setCc("CC1", "CC2") - // Score and Property are mixed into the middle to make sure DocumentBuilder's - // methods can be interleaved with EmailBuilder's methods. - .setScore(1) - .setProperty("propertyKey", "propertyValue1", "propertyValue2") - .setSubject("subject") - .setBody("EmailBody") - .build(); - - assertThat(email.getUri()).isEqualTo("uri"); - assertThat(email.getFrom()).isEqualTo("FakeFromAddress"); - assertThat(email.getTo()).isNull(); - assertThat(email.getCc()).asList().containsExactly("CC1", "CC2"); - assertThat(email.getBcc()).isNull(); - assertThat(email.getScore()).isEqualTo(1); - assertThat(email.getPropertyString("propertyKey")).isEqualTo("propertyValue1"); - assertThat(email.getPropertyStringArray("propertyKey")).asList().containsExactly( - "propertyValue1", "propertyValue2"); - assertThat(email.getSubject()).isEqualTo("subject"); - assertThat(email.getBody()).isEqualTo("EmailBody"); - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java b/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java deleted file mode 100644 index 08ec2d0b1067..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import static com.google.common.truth.Truth.assertThat; - -import static org.testng.Assert.assertThrows; -import static org.testng.Assert.expectThrows; - -import android.app.appsearch.AppSearchSchema.PropertyConfig; - -import androidx.test.filters.SmallTest; - -import com.google.android.icing.proto.IndexingConfig.TokenizerType; -import com.google.android.icing.proto.PropertyConfigProto; -import com.google.android.icing.proto.SchemaTypeConfigProto; -import com.google.android.icing.proto.TermMatchType; - -import org.junit.Test; - -@SmallTest -public class AppSearchSchemaTest { - @Test - public void testGetProto_Email() { - AppSearchSchema emailSchema = AppSearchSchema.newBuilder("Email") - .addProperty(AppSearchSchema.newPropertyBuilder("subject") - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .build() - ).addProperty(AppSearchSchema.newPropertyBuilder("body") - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .build() - ).build(); - - SchemaTypeConfigProto expectedEmailProto = SchemaTypeConfigProto.newBuilder() - .setSchemaType("Email") - .addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("subject") - .setDataType(PropertyConfigProto.DataType.Code.STRING) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setIndexingConfig( - com.google.android.icing.proto.IndexingConfig.newBuilder() - .setTokenizerType(TokenizerType.Code.PLAIN) - .setTermMatchType(TermMatchType.Code.PREFIX) - ) - ).addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("body") - .setDataType(PropertyConfigProto.DataType.Code.STRING) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setIndexingConfig( - com.google.android.icing.proto.IndexingConfig.newBuilder() - .setTokenizerType(TokenizerType.Code.PLAIN) - .setTermMatchType(TermMatchType.Code.PREFIX) - ) - ).build(); - - assertThat(emailSchema.getProto()).isEqualTo(expectedEmailProto); - } - - @Test - public void testGetProto_MusicRecording() { - AppSearchSchema musicRecordingSchema = AppSearchSchema.newBuilder("MusicRecording") - .addProperty(AppSearchSchema.newPropertyBuilder("artist") - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_REPEATED) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .build() - ).addProperty(AppSearchSchema.newPropertyBuilder("pubDate") - .setDataType(PropertyConfig.DATA_TYPE_INT64) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setIndexingType(PropertyConfig.INDEXING_TYPE_NONE) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_NONE) - .build() - ).build(); - - SchemaTypeConfigProto expectedMusicRecordingProto = SchemaTypeConfigProto.newBuilder() - .setSchemaType("MusicRecording") - .addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("artist") - .setDataType(PropertyConfigProto.DataType.Code.STRING) - .setCardinality(PropertyConfigProto.Cardinality.Code.REPEATED) - .setIndexingConfig( - com.google.android.icing.proto.IndexingConfig.newBuilder() - .setTokenizerType(TokenizerType.Code.PLAIN) - .setTermMatchType(TermMatchType.Code.PREFIX) - ) - ).addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("pubDate") - .setDataType(PropertyConfigProto.DataType.Code.INT64) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setIndexingConfig( - com.google.android.icing.proto.IndexingConfig.newBuilder() - .setTokenizerType(TokenizerType.Code.NONE) - .setTermMatchType(TermMatchType.Code.UNKNOWN) - ) - ).build(); - - assertThat(musicRecordingSchema.getProto()).isEqualTo(expectedMusicRecordingProto); - } - - @Test - public void testInvalidEnums() { - PropertyConfig.Builder builder = AppSearchSchema.newPropertyBuilder("test"); - assertThrows(IllegalArgumentException.class, () -> builder.setDataType(99)); - assertThrows(IllegalArgumentException.class, () -> builder.setCardinality(99)); - } - - @Test - public void testMissingFields() { - PropertyConfig.Builder builder = AppSearchSchema.newPropertyBuilder("test"); - Exception e = expectThrows(IllegalSchemaException.class, builder::build); - assertThat(e).hasMessageThat().contains("Missing field: dataType"); - - builder.setDataType(PropertyConfig.DATA_TYPE_DOCUMENT); - e = expectThrows(IllegalSchemaException.class, builder::build); - assertThat(e).hasMessageThat().contains("Missing field: schemaType"); - - builder.setSchemaType("TestType"); - e = expectThrows(IllegalSchemaException.class, builder::build); - assertThat(e).hasMessageThat().contains("Missing field: cardinality"); - - builder.setCardinality(PropertyConfig.CARDINALITY_REPEATED); - builder.build(); - } - - @Test - public void testDuplicateProperties() { - AppSearchSchema.Builder builder = AppSearchSchema.newBuilder("Email") - .addProperty(AppSearchSchema.newPropertyBuilder("subject") - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .build() - ).addProperty(AppSearchSchema.newPropertyBuilder("subject") - .setDataType(PropertyConfig.DATA_TYPE_STRING) - .setCardinality(PropertyConfig.CARDINALITY_OPTIONAL) - .setIndexingType(PropertyConfig.INDEXING_TYPE_PREFIXES) - .setTokenizerType(PropertyConfig.TOKENIZER_TYPE_PLAIN) - .build() - ); - - Exception e = expectThrows(IllegalSchemaException.class, builder::build); - assertThat(e).hasMessageThat().contains("Property defined more than once: subject"); - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/SearchResultsTest.java b/core/tests/coretests/src/android/app/appsearch/SearchResultsTest.java deleted file mode 100644 index 21259cc81758..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/SearchResultsTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import static com.google.common.truth.Truth.assertThat; - -import static org.testng.Assert.assertThrows; - -import androidx.test.filters.SmallTest; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.SearchResultProto; - -import org.junit.Test; - -@SmallTest -public class SearchResultsTest { - - @Test - public void testSearchResultsEqual() { - final String uri = "testUri"; - final String schemaType = "testSchema"; - SearchResultProto.ResultProto result1 = SearchResultProto.ResultProto.newBuilder() - .setDocument(DocumentProto.newBuilder() - .setUri(uri) - .setSchema(schemaType) - .build()) - .build(); - SearchResultProto searchResults1 = SearchResultProto.newBuilder() - .addResults(result1) - .build(); - SearchResults res1 = new SearchResults(searchResults1); - SearchResultProto.ResultProto result2 = SearchResultProto.ResultProto.newBuilder() - .setDocument(DocumentProto.newBuilder() - .setUri(uri) - .setSchema(schemaType) - .build()) - .build(); - SearchResultProto searchResults2 = SearchResultProto.newBuilder() - .addResults(result2) - .build(); - SearchResults res2 = new SearchResults(searchResults2); - assertThat(res1.toString()).isEqualTo(res2.toString()); - } - - @Test - public void buildSearchSpecWithoutTermMatchType() { - assertThrows(RuntimeException.class, () -> SearchSpec.newBuilder() - .setSchemaTypes("testSchemaType") - .build()); - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/SnippetTest.java b/core/tests/coretests/src/android/app/appsearch/SnippetTest.java deleted file mode 100644 index 3103708f985d..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/SnippetTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch; - -import static com.google.common.truth.Truth.assertThat; - -import androidx.test.filters.SmallTest; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.SnippetMatchProto; -import com.google.android.icing.proto.SnippetProto; - -import org.junit.Test; - -@SmallTest -public class SnippetTest { - - // TODO(sidchhabra): Add tests for Double and Long Snippets. - @Test - public void testSingleStringSnippet() { - - final String propertyKeyString = "content"; - final String propertyValueString = "A commonly used fake word is foo.\n" - + " Another nonsense word that’s used a lot\n" - + " is bar.\n"; - final String uri = "uri1"; - final String schemaType = "schema1"; - final String searchWord = "foo"; - final String exactMatch = "foo"; - final String window = "is foo"; - - // Building the SearchResult received from query. - PropertyProto property = PropertyProto.newBuilder() - .setName(propertyKeyString) - .addStringValues(propertyValueString) - .build(); - DocumentProto documentProto = DocumentProto.newBuilder() - .setUri(uri) - .setSchema(schemaType) - .addProperties(property) - .build(); - SnippetProto snippetProto = SnippetProto.newBuilder() - .addEntries(SnippetProto.EntryProto.newBuilder() - .setPropertyName(propertyKeyString) - .addSnippetMatches(SnippetMatchProto.newBuilder() - .setValuesIndex(0) - .setExactMatchPosition(29) - .setExactMatchBytes(3) - .setWindowPosition(26) - .setWindowBytes(6) - .build()) - .build()) - .build(); - SearchResultProto.ResultProto resultProto = SearchResultProto.ResultProto.newBuilder() - .setDocument(documentProto) - .setSnippet(snippetProto) - .build(); - SearchResultProto searchResultProto = SearchResultProto.newBuilder() - .addResults(resultProto) - .build(); - SearchResults searchResults = new SearchResults(searchResultProto); - - // Making ResultReader and getting Snippet values. - while (searchResults.hasNext()) { - SearchResults.Result result = searchResults.next(); - MatchInfo match = result.getMatchInfo().get(0); - assertThat(match.getPropertyPath()).isEqualTo(propertyKeyString); - assertThat(match.getFullText()).isEqualTo(propertyValueString); - assertThat(match.getExactMatch()).isEqualTo(exactMatch); - assertThat(match.getSnippet()).isEqualTo(window); - } - } - - // TODO(sidchhabra): Add tests for Double and Long Snippets. - @Test - public void testNoSnippets() { - - final String propertyKeyString = "content"; - final String propertyValueString = "A commonly used fake word is foo.\n" - + " Another nonsense word that’s used a lot\n" - + " is bar.\n"; - final String uri = "uri1"; - final String schemaType = "schema1"; - final String searchWord = "foo"; - final String exactMatch = "foo"; - final String window = "is foo"; - - // Building the SearchResult received from query. - PropertyProto property = PropertyProto.newBuilder() - .setName(propertyKeyString) - .addStringValues(propertyValueString) - .build(); - DocumentProto documentProto = DocumentProto.newBuilder() - .setUri(uri) - .setSchema(schemaType) - .addProperties(property) - .build(); - SearchResultProto.ResultProto resultProto = SearchResultProto.ResultProto.newBuilder() - .setDocument(documentProto) - .build(); - SearchResultProto searchResultProto = SearchResultProto.newBuilder() - .addResults(resultProto) - .build(); - SearchResults searchResults = new SearchResults(searchResultProto); - - while (searchResults.hasNext()) { - SearchResults.Result result = searchResults.next(); - assertThat(result.getMatchInfo()).isEqualTo(null); - } - } - - @Test - public void testMultipleStringSnippet() { - final String searchWord = "Test"; - - // Building the SearchResult received from query. - PropertyProto property1 = PropertyProto.newBuilder() - .setName("sender.name") - .addStringValues("Test Name Jr.") - .build(); - PropertyProto property2 = PropertyProto.newBuilder() - .setName("sender.email") - .addStringValues("TestNameJr@gmail.com") - .build(); - DocumentProto documentProto = DocumentProto.newBuilder() - .setUri("uri1") - .setSchema("schema1") - .addProperties(property1) - .addProperties(property2) - .build(); - SnippetProto snippetProto = SnippetProto.newBuilder() - .addEntries( - SnippetProto.EntryProto.newBuilder() - .setPropertyName("sender.name") - .addSnippetMatches( - SnippetMatchProto.newBuilder() - .setValuesIndex(0) - .setExactMatchPosition(0) - .setExactMatchBytes(4) - .setWindowPosition(0) - .setWindowBytes(9) - .build()) - .build()) - .addEntries( - SnippetProto.EntryProto.newBuilder() - .setPropertyName("sender.email") - .addSnippetMatches( - SnippetMatchProto.newBuilder() - .setValuesIndex(0) - .setExactMatchPosition(0) - .setExactMatchBytes(20) - .setWindowPosition(0) - .setWindowBytes(20) - .build()) - .build() - ) - .build(); - SearchResultProto.ResultProto resultProto = SearchResultProto.ResultProto.newBuilder() - .setDocument(documentProto) - .setSnippet(snippetProto) - .build(); - SearchResultProto searchResultProto = SearchResultProto.newBuilder() - .addResults(resultProto) - .build(); - SearchResults searchResults = new SearchResults(searchResultProto); - - // Making ResultReader and getting Snippet values. - while (searchResults.hasNext()) { - SearchResults.Result result = searchResults.next(); - - MatchInfo match1 = result.getMatchInfo().get(0); - assertThat(match1.getPropertyPath()).isEqualTo("sender.name"); - assertThat(match1.getFullText()).isEqualTo("Test Name Jr."); - assertThat(match1.getExactMatch()).isEqualTo("Test"); - assertThat(match1.getSnippet()).isEqualTo("Test Name"); - - MatchInfo match2 = result.getMatchInfo().get(1); - assertThat(match2.getPropertyPath()).isEqualTo("sender.email"); - assertThat(match2.getFullText()).isEqualTo("TestNameJr@gmail.com"); - assertThat(match2.getExactMatch()).isEqualTo("TestNameJr@gmail.com"); - assertThat(match2.getSnippet()).isEqualTo("TestNameJr@gmail.com"); - } - } -} diff --git a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java b/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java deleted file mode 100644 index b29483c2e3b3..000000000000 --- a/core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app.appsearch.impl; - -import static com.google.common.truth.Truth.assertThat; - -import android.annotation.NonNull; -import android.app.appsearch.AppSearchDocument; - -import androidx.test.filters.SmallTest; - -import org.junit.Test; - -/** - * Tests that {@link AppSearchDocument} and {@link AppSearchDocument.Builder} are extendable by - * developers. - * - * <p>This class is intentionally in a different package than {@link AppSearchDocument} to make sure - * there are no package-private methods required for external developers to add custom types. - */ -@SmallTest -public class CustomerDocumentTest { - - private static byte[] sByteArray1 = new byte[]{(byte) 1, (byte) 2, (byte) 3}; - private static byte[] sByteArray2 = new byte[]{(byte) 4, (byte) 5, (byte) 6}; - private static AppSearchDocument sDocumentProperties1 = new AppSearchDocument - .Builder("sDocumentProperties1", "sDocumentPropertiesSchemaType1") - .build(); - private static AppSearchDocument sDocumentProperties2 = new AppSearchDocument - .Builder("sDocumentProperties2", "sDocumentPropertiesSchemaType2") - .build(); - - @Test - public void testBuildCustomerDocument() { - CustomerDocument customerDocument = new CustomerDocument.Builder("uri1") - .setScore(1) - .setCreationTimestampMillis(0) - .setProperty("longKey1", 1L, 2L, 3L) - .setProperty("doubleKey1", 1.0, 2.0, 3.0) - .setProperty("booleanKey1", true, false, true) - .setProperty("stringKey1", "test-value1", "test-value2", "test-value3") - .setProperty("byteKey1", sByteArray1, sByteArray2) - .setProperty("documentKey1", sDocumentProperties1, sDocumentProperties2) - .build(); - - assertThat(customerDocument.getUri()).isEqualTo("uri1"); - assertThat(customerDocument.getSchemaType()).isEqualTo("customerDocument"); - assertThat(customerDocument.getScore()).isEqualTo(1); - assertThat(customerDocument.getCreationTimestampMillis()).isEqualTo(0L); - assertThat(customerDocument.getPropertyLongArray("longKey1")).asList() - .containsExactly(1L, 2L, 3L); - assertThat(customerDocument.getPropertyDoubleArray("doubleKey1")).usingExactEquality() - .containsExactly(1.0, 2.0, 3.0); - assertThat(customerDocument.getPropertyBooleanArray("booleanKey1")).asList() - .containsExactly(true, false, true); - assertThat(customerDocument.getPropertyStringArray("stringKey1")).asList() - .containsExactly("test-value1", "test-value2", "test-value3"); - assertThat(customerDocument.getPropertyBytesArray("byteKey1")).asList() - .containsExactly(sByteArray1, sByteArray2); - assertThat(customerDocument.getPropertyDocumentArray("documentKey1")).asList() - .containsExactly(sDocumentProperties1, sDocumentProperties2); - } - - /** - * An example document type for test purposes, defined outside of - * {@link android.app.appsearch.AppSearch} (the way an external developer would define it). - */ - private static class CustomerDocument extends AppSearchDocument { - private CustomerDocument(AppSearchDocument document) { - super(document); - } - - public static class Builder extends AppSearchDocument.Builder<CustomerDocument.Builder> { - private Builder(@NonNull String uri) { - super(uri, "customerDocument"); - } - - @Override - public CustomerDocument build() { - return new CustomerDocument(super.build()); - } - } - } -} diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index ff8c20940c73..0902fdb9c28f 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -295,8 +295,6 @@ public final class SystemServer { "com.android.server.DeviceIdleController"; private static final String BLOB_STORE_MANAGER_SERVICE_CLASS = "com.android.server.blob.BlobStoreManagerService"; - private static final String APP_SEARCH_MANAGER_SERVICE_CLASS = - "com.android.server.appsearch.AppSearchManagerService"; private static final String TETHERING_CONNECTOR_CLASS = "android.net.ITetheringConnector"; @@ -2168,10 +2166,6 @@ public final class SystemServer { mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); t.traceEnd(); - t.traceBegin("AppSearchManagerService"); - mSystemServiceManager.startService(APP_SEARCH_MANAGER_SERVICE_CLASS); - t.traceEnd(); - ConcurrentUtils.waitForFutureNoInterrupt(mBlobStoreServiceStart, START_BLOB_STORE_SERVICE); diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index d148c21b7d6e..449e75cd11a0 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -43,7 +43,6 @@ android_test { "platformprotosnano", "hamcrest-library", "servicestests-utils", - "service-appsearch", "service-jobscheduler", "service-permission", // TODO: remove once Android migrates to JUnit 4.12, diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java deleted file mode 100644 index 34ade818f062..000000000000 --- a/services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.server.appsearch.impl; - -import static com.google.common.truth.Truth.assertThat; - -import static org.testng.Assert.expectThrows; - -import android.annotation.UserIdInt; -import android.content.Context; -import android.os.UserHandle; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import com.google.android.icing.proto.IndexingConfig; -import com.google.android.icing.proto.PropertyConfigProto; -import com.google.android.icing.proto.SchemaProto; -import com.google.android.icing.proto.SchemaTypeConfigProto; -import com.google.android.icing.proto.TermMatchType; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -public class AppSearchImplTest { - private final Context mContext = InstrumentationRegistry.getContext(); - private final @UserIdInt int mUserId = UserHandle.getCallingUserId(); - - @Test - public void testRewriteSchemaTypes() { - SchemaProto inSchema = SchemaProto.newBuilder() - .addTypes(SchemaTypeConfigProto.newBuilder() - .setSchemaType("TestType") - .addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("subject") - .setDataType(PropertyConfigProto.DataType.Code.STRING) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setIndexingConfig( - IndexingConfig.newBuilder() - .setTokenizerType( - IndexingConfig.TokenizerType.Code.PLAIN) - .setTermMatchType(TermMatchType.Code.PREFIX) - .build() - ).build() - ).addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("link") - .setDataType(PropertyConfigProto.DataType.Code.DOCUMENT) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setSchemaType("RefType") - .build() - ).build() - ).build(); - - SchemaProto expectedSchema = SchemaProto.newBuilder() - .addTypes(SchemaTypeConfigProto.newBuilder() - .setSchemaType("com.android.server.appsearch.impl@42:TestType") - .addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("subject") - .setDataType(PropertyConfigProto.DataType.Code.STRING) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setIndexingConfig( - IndexingConfig.newBuilder() - .setTokenizerType( - IndexingConfig.TokenizerType.Code.PLAIN) - .setTermMatchType(TermMatchType.Code.PREFIX) - .build() - ).build() - ).addProperties(PropertyConfigProto.newBuilder() - .setPropertyName("link") - .setDataType(PropertyConfigProto.DataType.Code.DOCUMENT) - .setCardinality(PropertyConfigProto.Cardinality.Code.OPTIONAL) - .setSchemaType("com.android.server.appsearch.impl@42:RefType") - .build() - ).build() - ).build(); - - AppSearchImpl impl = new AppSearchImpl(mContext, mUserId); - SchemaProto.Builder actualSchema = inSchema.toBuilder(); - impl.rewriteSchemaTypes("com.android.server.appsearch.impl@42:", actualSchema); - - assertThat(actualSchema.build()).isEqualTo(expectedSchema); - } - - @Test - public void testPackageNotFound() { - AppSearchImpl impl = new AppSearchImpl(mContext, mUserId); - IllegalStateException e = expectThrows( - IllegalStateException.class, - () -> impl.setSchema( - /*callingUid=*/Integer.MAX_VALUE, - SchemaProto.getDefaultInstance(), - /*forceOverride=*/false)); - assertThat(e).hasMessageThat().contains("Failed to look up package name"); - } -} diff --git a/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java b/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java deleted file mode 100644 index 07b655652fac..000000000000 --- a/services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.server.appsearch.impl; - -import static com.google.common.truth.Truth.assertThat; - -import androidx.test.runner.AndroidJUnit4; - -import com.google.android.icing.proto.DocumentProto; -import com.google.android.icing.proto.PropertyProto; -import com.google.android.icing.proto.SearchResultProto; -import com.google.android.icing.proto.StatusProto; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.ArrayList; -import java.util.List; - -@RunWith(AndroidJUnit4.class) -public class FakeIcingTest { - @Test - public void query() { - FakeIcing icing = new FakeIcing(); - icing.put(createDoc("uri:cat", "The cat said meow")); - icing.put(createDoc("uri:dog", "The dog said woof")); - - assertThat(queryGetUris(icing, "meow")).containsExactly("uri:cat"); - assertThat(queryGetUris(icing, "said")).containsExactly("uri:cat", "uri:dog"); - assertThat(queryGetUris(icing, "fred")).isEmpty(); - } - - @Test - public void queryNorm() { - FakeIcing icing = new FakeIcing(); - icing.put(createDoc("uri:cat", "The cat said meow")); - icing.put(createDoc("uri:dog", "The dog said woof")); - - assertThat(queryGetUris(icing, "the")).containsExactly("uri:cat", "uri:dog"); - assertThat(queryGetUris(icing, "The")).containsExactly("uri:cat", "uri:dog"); - assertThat(queryGetUris(icing, "tHe")).containsExactly("uri:cat", "uri:dog"); - } - - @Test - public void get() { - DocumentProto cat = createDoc("uri:cat", "The cat said meow"); - FakeIcing icing = new FakeIcing(); - icing.put(cat); - assertThat(icing.get("uri:cat")).isEqualTo(cat); - } - - @Test - public void replace() { - DocumentProto cat = createDoc("uri:cat", "The cat said meow"); - DocumentProto dog = createDoc("uri:dog", "The dog said woof"); - - FakeIcing icing = new FakeIcing(); - icing.put(cat); - icing.put(dog); - - assertThat(queryGetUris(icing, "meow")).containsExactly("uri:cat"); - assertThat(queryGetUris(icing, "said")).containsExactly("uri:cat", "uri:dog"); - assertThat(icing.get("uri:cat")).isEqualTo(cat); - - // Replace - DocumentProto cat2 = createDoc("uri:cat", "The cat said purr"); - DocumentProto bird = createDoc("uri:bird", "The cat said tweet"); - icing.put(cat2); - icing.put(bird); - - assertThat(queryGetUris(icing, "meow")).isEmpty(); - assertThat(queryGetUris(icing, "said")).containsExactly("uri:cat", "uri:dog", "uri:bird"); - assertThat(icing.get("uri:cat")).isEqualTo(cat2); - } - - @Test - public void delete() { - DocumentProto cat = createDoc("uri:cat", "The cat said meow"); - DocumentProto dog = createDoc("uri:dog", "The dog said woof"); - - FakeIcing icing = new FakeIcing(); - icing.put(cat); - icing.put(dog); - - assertThat(queryGetUris(icing, "meow")).containsExactly("uri:cat"); - assertThat(queryGetUris(icing, "said")).containsExactly("uri:cat", "uri:dog"); - assertThat(icing.get("uri:cat")).isEqualTo(cat); - - // Delete - icing.delete("uri:cat"); - icing.delete("uri:notreal"); - - assertThat(queryGetUris(icing, "meow")).isEmpty(); - assertThat(queryGetUris(icing, "said")).containsExactly("uri:dog"); - assertThat(icing.get("uri:cat")).isNull(); - } - - private static DocumentProto createDoc(String uri, String body) { - return DocumentProto.newBuilder() - .setUri(uri) - .addProperties(PropertyProto.newBuilder().addStringValues(body)) - .build(); - } - - private static List<String> queryGetUris(FakeIcing icing, String term) { - List<String> uris = new ArrayList<>(); - SearchResultProto results = icing.query(term); - assertThat(results.getStatus().getCode()).isEqualTo(StatusProto.Code.OK); - for (SearchResultProto.ResultProto result : results.getResultsList()) { - uris.add(result.getDocument().getUri()); - } - return uris; - } -} |