summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp14
-rw-r--r--apex/appsearch/Android.bp37
-rw-r--r--apex/appsearch/apex_manifest.json4
-rw-r--r--apex/appsearch/com.android.appsearch.avbpubkeybin1032 -> 0 bytes
-rw-r--r--apex/appsearch/com.android.appsearch.pem51
-rw-r--r--apex/appsearch/com.android.appsearch.pk8bin2373 -> 0 bytes
-rw-r--r--apex/appsearch/com.android.appsearch.x509.pem35
-rw-r--r--apex/appsearch/framework/Android.bp83
-rw-r--r--apex/appsearch/framework/java/android/app/TEST_MAPPING7
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchBatchResult.java150
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchDocument.java724
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchEmail.java255
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchManager.java293
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchManagerFrameworkInitializer.java43
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/AppSearchSchema.java369
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IAppSearchManager.aidl60
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IllegalSchemaException.java36
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/IllegalSearchSpecException.java36
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/MatchInfo.java182
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/SearchResults.java128
-rw-r--r--apex/appsearch/framework/java/android/app/appsearch/SearchSpec.java260
-rw-r--r--apex/appsearch/service/Android.bp24
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java125
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/TEST_MAPPING23
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/impl/AppSearchImpl.java168
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/impl/FakeIcing.java169
-rw-r--r--apex/appsearch/service/java/com/android/server/appsearch/impl/ImplInstanceManager.java56
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java10
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java9
-rw-r--r--apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java16
-rw-r--r--apex/statsd/framework/Android.bp26
-rw-r--r--apex/statsd/framework/test/AndroidManifest.xml26
-rw-r--r--apex/statsd/framework/test/TEST_MAPPING7
-rw-r--r--apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java (renamed from core/tests/coretests/src/android/app/PullAtomMetadataTest.java)0
-rw-r--r--apex/statsd/framework/test/src/android/util/StatsEventTest.java (renamed from core/tests/coretests/src/android/util/StatsEventTest.java)0
-rw-r--r--api/current.txt9
-rwxr-xr-xapi/system-current.txt12
-rw-r--r--core/java/android/app/AppOpsManager.java29
-rw-r--r--core/java/android/app/ApplicationExitInfo.java174
-rw-r--r--core/java/android/app/SystemServiceRegistry.java2
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/os/BatteryStatsManager.java14
-rw-r--r--core/java/android/os/UpdateEngine.java35
-rw-r--r--core/java/android/os/connectivity/WifiBatteryStats.java4
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java51
-rw-r--r--core/jni/Android.bp10
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/fd_utils.cpp1
-rw-r--r--core/proto/android/app/appexit_enums.proto240
-rw-r--r--core/proto/android/app/appexitinfo.proto146
-rw-r--r--core/tests/coretests/Android.bp3
-rw-r--r--core/tests/coretests/src/android/app/appsearch/AppSearchDocumentTest.java262
-rw-r--r--core/tests/coretests/src/android/app/appsearch/AppSearchEmailTest.java53
-rw-r--r--core/tests/coretests/src/android/app/appsearch/AppSearchSchemaTest.java166
-rw-r--r--core/tests/coretests/src/android/app/appsearch/SearchResultsTest.java66
-rw-r--r--core/tests/coretests/src/android/app/appsearch/SnippetTest.java200
-rw-r--r--core/tests/coretests/src/android/app/appsearch/impl/CustomerDocumentTest.java98
-rw-r--r--keystore/java/android/security/keystore/KeyGenParameterSpec.java11
-rw-r--r--keystore/java/android/security/keystore/KeyProtection.java11
-rw-r--r--libs/hwui/RenderNode.cpp2
-rw-r--r--libs/hwui/RenderNode.h3
-rw-r--r--libs/hwui/jni/FontFamily.cpp4
-rw-r--r--libs/hwui/jni/fonts/Font.cpp4
-rw-r--r--libs/hwui/pipeline/skia/ReorderBarrierDrawables.h2
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp3
-rw-r--r--libs/hwui/renderthread/VulkanManager.cpp2
-rw-r--r--libs/hwui/tests/unit/FatVectorTests.cpp2
-rw-r--r--libs/hwui/utils/FatVector.h96
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java63
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java60
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java14
-rw-r--r--services/core/java/com/android/server/am/AppExitInfoTracker.java1
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java6
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java34
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java8
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java21
-rw-r--r--services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java5
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/tests/servicestests/Android.bp1
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/impl/AppSearchImplTest.java109
-rw-r--r--services/tests/servicestests/src/com/android/server/appsearch/impl/FakeIcingTest.java127
-rw-r--r--services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java146
-rw-r--r--tools/stats_log_api_gen/Android.bp2
-rw-r--r--tools/stats_log_api_gen/Collation.cpp10
-rw-r--r--tools/stats_log_api_gen/java_writer.cpp6
-rw-r--r--tools/stats_log_api_gen/java_writer_q.cpp64
-rw-r--r--tools/stats_log_api_gen/java_writer_q.h4
-rw-r--r--tools/stats_log_api_gen/main.cpp523
-rw-r--r--tools/stats_log_api_gen/native_writer.cpp22
-rw-r--r--tools/stats_log_api_gen/native_writer_q.cpp276
-rw-r--r--tools/stats_log_api_gen/native_writer_q.h49
-rw-r--r--tools/stats_log_api_gen/test.proto31
-rw-r--r--tools/stats_log_api_gen/test_collation.cpp5
-rw-r--r--tools/stats_log_api_gen/utils.cpp12
-rw-r--r--tools/stats_log_api_gen/utils.h2
103 files changed, 1065 insertions, 5737 deletions
diff --git a/Android.bp b/Android.bp
index d75a311a36ef..fb14f86bdae4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -271,7 +271,6 @@ filegroup {
// etc.
":framework-javastream-protos",
- ":framework-statslog-gen", // StatsLogInternal.java
":statslog-framework-java-gen", // FrameworkStatsLog.java
// telephony annotations
@@ -282,7 +281,6 @@ filegroup {
filegroup {
name: "framework-updatable-sources",
srcs: [
- ":framework-appsearch-sources",
":framework-sdkextensions-sources",
":framework-statsd-sources",
":framework-tethering-srcs",
@@ -468,7 +466,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",
@@ -494,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/packages/Tethering/tests/unit",
@@ -516,7 +512,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 +536,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 +556,6 @@ java_library {
libs: [
"app-compat-annotations",
"ext",
- "icing-java-proto-lite",
"unsupportedappusage",
],
@@ -617,13 +610,6 @@ java_library {
}
genrule {
- name: "framework-statslog-gen",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --worksource",
- out: ["android/util/StatsLogInternal.java"],
-}
-
-genrule {
name: "statslog-framework-java-gen",
tools: ["stats-log-api-gen"],
cmd: "$(location stats-log-api-gen) --java $(out) --module framework" +
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
deleted file mode 100644
index 4e5acae9c1e4..000000000000
--- a/apex/appsearch/com.android.appsearch.avbpubkey
+++ /dev/null
Binary files differ
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
deleted file mode 100644
index 77e98b20877b..000000000000
--- a/apex/appsearch/com.android.appsearch.pk8
+++ /dev/null
Binary files differ
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}&lt;{@link Void}&gt;. 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}&lt;byte[]&gt; of serialized DocumentProtos.
- * @param callback
- * {@link AndroidFuture}&lt;{@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;&gt;.
- * If the call fails to start, {@code callback} will be completed exceptionally. Otherwise,
- * {@code callback} will be completed with an
- * {@link AppSearchBatchResult}&lt;{@link String}, {@link Void}&gt;
- * 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/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index 05c661127eab..49adaa8efd4b 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -939,6 +939,12 @@ public class BlobStoreManagerService extends SystemService {
}
}
+ void runIdleMaintenance() {
+ synchronized (mBlobsLock) {
+ handleIdleMaintenanceLocked();
+ }
+ }
+
@GuardedBy("mBlobsLock")
private void dumpSessionsLocked(IndentingPrintWriter fout, DumpArgs dumpArgs) {
for (int i = 0, userCount = mSessions.size(); i < userCount; ++i) {
@@ -1408,9 +1414,7 @@ public class BlobStoreManagerService extends SystemService {
private class LocalService extends BlobStoreManagerInternal {
@Override
public void onIdleMaintenance() {
- synchronized (mBlobsLock) {
- handleIdleMaintenanceLocked();
- }
+ runIdleMaintenance();
}
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java
index d58294b8b941..72af323e9d5f 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerShellCommand.java
@@ -44,6 +44,8 @@ class BlobStoreManagerShellCommand extends ShellCommand {
return runClearAllBlobs(pw);
case "delete-blob":
return runDeleteBlob(pw);
+ case "idle-maintenance":
+ return runIdleMaintenance(pw);
default:
return handleDefaultCommands(cmd);
}
@@ -84,6 +86,11 @@ class BlobStoreManagerShellCommand extends ShellCommand {
return 0;
}
+ private int runIdleMaintenance(PrintWriter pw) {
+ mService.runIdleMaintenance();
+ return 0;
+ }
+
@Override
public void onHelp() {
final PrintWriter pw = getOutPrintWriter();
@@ -112,6 +119,8 @@ class BlobStoreManagerShellCommand extends ShellCommand {
pw.println(" --expiry: Expiry time of the blob to delete, in milliseconds.");
pw.println(" --label: Label of the blob to delete.");
pw.println(" --tag: Tag of the blob to delete.");
+ pw.println("idle-maintenance");
+ pw.println(" Run idle maintenance which takes care of removing stale data.");
pw.println();
}
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
index cc4044ed46b9..62701e52781d 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java
@@ -347,12 +347,12 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
@Override
public void close() {
- closeSession(STATE_CLOSED);
+ closeSession(STATE_CLOSED, false /* sendCallback */);
}
@Override
public void abandon() {
- closeSession(STATE_ABANDONED);
+ closeSession(STATE_ABANDONED, true /* sendCallback */);
}
@Override
@@ -360,11 +360,11 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
synchronized (mSessionLock) {
mBlobCommitCallback = callback;
- closeSession(STATE_COMMITTED);
+ closeSession(STATE_COMMITTED, true /* sendCallback */);
}
}
- private void closeSession(int state) {
+ private void closeSession(int state, boolean sendCallback) {
assertCallerIsOwner();
synchronized (mSessionLock) {
if (mState != STATE_OPENED) {
@@ -381,7 +381,9 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
mState = state;
revokeAllFdsLocked();
- mListener.onStateChanged(this);
+ if (sendCallback) {
+ mListener.onStateChanged(this);
+ }
}
}
@@ -457,6 +459,10 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
return "<abandoned>";
case STATE_COMMITTED:
return "<committed>";
+ case STATE_VERIFIED_VALID:
+ return "<verified_valid>";
+ case STATE_VERIFIED_INVALID:
+ return "<verified_invalid>";
default:
Slog.wtf(TAG, "Unknown state: " + state);
return "<unknown>";
diff --git a/apex/statsd/framework/Android.bp b/apex/statsd/framework/Android.bp
index 1bd770a1ab99..8185bb036b22 100644
--- a/apex/statsd/framework/Android.bp
+++ b/apex/statsd/framework/Android.bp
@@ -43,6 +43,7 @@ filegroup {
],
visibility: [
"//frameworks/base", // For the "global" stubs.
+ "//frameworks/base/apex/statsd:__subpackages__",
],
}
@@ -74,8 +75,6 @@ java_library {
hostdex: true, // for hiddenapi check
visibility: [
"//frameworks/base/apex/statsd:__subpackages__",
- // TODO(b/149928788): Remove when tests are moved.
- "//frameworks/base/core/tests/coretests:__pkg__",
],
apex_available: [
"com.android.os.statsd",
@@ -164,3 +163,26 @@ java_library {
"//frameworks/opt/net/wifi/service" // wifi service
]
}
+
+android_test {
+ name: "FrameworkStatsdTest",
+ platform_apis: true,
+ srcs: [
+ // TODO(b/147705194): Use framework-statsd as a lib dependency instead.
+ ":framework-statsd-sources",
+ "test/**/*.java",
+ ],
+ manifest: "test/AndroidManifest.xml",
+ static_libs: [
+ "androidx.test.rules",
+ "truth-prebuilt",
+ ],
+ libs: [
+ "android.test.runner.stubs",
+ "android.test.base.stubs",
+ ],
+ test_suites: [
+ "device-tests",
+ ],
+}
+
diff --git a/apex/statsd/framework/test/AndroidManifest.xml b/apex/statsd/framework/test/AndroidManifest.xml
new file mode 100644
index 000000000000..8f89d2332b12
--- /dev/null
+++ b/apex/statsd/framework/test/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.os.statsd.framework.test"
+ >
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.os.statsd.framework.test"
+ android:label="Framework Statsd Tests" />
+
+</manifest>
diff --git a/apex/statsd/framework/test/TEST_MAPPING b/apex/statsd/framework/test/TEST_MAPPING
new file mode 100644
index 000000000000..f38795819189
--- /dev/null
+++ b/apex/statsd/framework/test/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit" : [
+ {
+ "name" : "FrameworkStatsdTest"
+ }
+ ]
+}
diff --git a/core/tests/coretests/src/android/app/PullAtomMetadataTest.java b/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
index 0ae613400b18..0ae613400b18 100644
--- a/core/tests/coretests/src/android/app/PullAtomMetadataTest.java
+++ b/apex/statsd/framework/test/src/android/app/PullAtomMetadataTest.java
diff --git a/core/tests/coretests/src/android/util/StatsEventTest.java b/apex/statsd/framework/test/src/android/util/StatsEventTest.java
index ac25e2734ac9..ac25e2734ac9 100644
--- a/core/tests/coretests/src/android/util/StatsEventTest.java
+++ b/apex/statsd/framework/test/src/android/util/StatsEventTest.java
diff --git a/api/current.txt b/api/current.txt
index 02b87342329c..563665fb519a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4572,14 +4572,17 @@ package android.app {
field public static final int REASON_ANR = 6; // 0x6
field public static final int REASON_CRASH = 4; // 0x4
field public static final int REASON_CRASH_NATIVE = 5; // 0x5
+ field public static final int REASON_DEPENDENCY_DIED = 12; // 0xc
field public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9; // 0x9
field public static final int REASON_EXIT_SELF = 1; // 0x1
field public static final int REASON_INITIALIZATION_FAILURE = 7; // 0x7
field public static final int REASON_LOW_MEMORY = 3; // 0x3
- field public static final int REASON_OTHER = 10; // 0xa
+ field public static final int REASON_OTHER = 13; // 0xd
field public static final int REASON_PERMISSION_CHANGE = 8; // 0x8
field public static final int REASON_SIGNALED = 2; // 0x2
field public static final int REASON_UNKNOWN = 0; // 0x0
+ field public static final int REASON_USER_REQUESTED = 10; // 0xa
+ field public static final int REASON_USER_STOPPED = 11; // 0xb
}
public final class AsyncNotedAppOp implements android.os.Parcelable {
@@ -42784,7 +42787,7 @@ package android.security.keystore {
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean);
- method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationParameters(@IntRange(from=0xffffffff) int, int);
+ method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationParameters(@IntRange(from=0) int, int);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidWhileOnBody(boolean);
method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int);
@@ -42902,7 +42905,7 @@ package android.security.keystore {
method @NonNull public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
method @NonNull public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
method @NonNull public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean);
- method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationParameters(@IntRange(from=0xffffffff) int, int);
+ method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationParameters(@IntRange(from=0) int, int);
method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
method @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
method @Deprecated @NonNull public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(@IntRange(from=0xffffffff) int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 71877089aec4..c51fab44cbf3 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 {
@@ -8140,8 +8132,8 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStartedFromSource(@NonNull android.os.WorkSource, @IntRange(from=0) int);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiBatchedScanStoppedFromSource(@NonNull android.os.WorkSource);
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastDisabled(int);
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastEnabled(int);
+ method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastDisabled(@NonNull android.os.WorkSource);
+ method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiMulticastEnabled(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOff();
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiOn();
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void reportWifiRssiChanged(@IntRange(from=0xffffff81, to=0) int);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index a53fc3508001..2399e374540d 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -16,10 +16,6 @@
package android.app;
-import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT;
-import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
-import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
-
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
@@ -74,6 +70,7 @@ import com.android.internal.os.RuntimeInit;
import com.android.internal.os.ZygoteInit;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DataClass;
+import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.Parcelling;
import com.android.internal.util.Preconditions;
@@ -666,15 +663,31 @@ public class AppOpsManager {
}
}
+ // These constants are redefined here to work around a metalava limitation/bug where
+ // @IntDef is not able to see @hide symbols when they are hidden via package hiding:
+ // frameworks/base/core/java/com/android/internal/package.html
+
+ /** @hide */
+ public static final int SAMPLING_STRATEGY_DEFAULT =
+ FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT;
+
+ /** @hide */
+ public static final int SAMPLING_STRATEGY_UNIFORM =
+ FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
+
+ /** @hide */
+ public static final int SAMPLING_STRATEGY_RARELY_USED =
+ FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
+
/**
* Strategies used for message sampling
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"RUNTIME_APP_OPS_ACCESS__SAMPLING_STRATEGY__"}, value = {
- RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT,
- RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM,
- RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED
+ @IntDef(prefix = {"SAMPLING_STRATEGY_"}, value = {
+ SAMPLING_STRATEGY_DEFAULT,
+ SAMPLING_STRATEGY_UNIFORM,
+ SAMPLING_STRATEGY_RARELY_USED
})
public @interface SamplingStrategy {}
diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java
index c55453e94960..5df3257f2444 100644
--- a/core/java/android/app/ApplicationExitInfo.java
+++ b/core/java/android/app/ApplicationExitInfo.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -121,11 +122,30 @@ public final class ApplicationExitInfo implements Parcelable {
public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9;
/**
- * Application process was killed by the system for various other reasons,
- * for example, the application package got disabled by the user;
- * {@link #getDescription} will specify the cause given by the system.
+ * Application process was killed because of the user request, for example,
+ * user clicked the "Force stop" button of the application in the Settings,
+ * or removed the application away from Recents.
*/
- public static final int REASON_OTHER = 10;
+ public static final int REASON_USER_REQUESTED = 10;
+
+ /**
+ * Application process was killed, because the user it is running as on devices
+ * with mutlple users, was stopped.
+ */
+ public static final int REASON_USER_STOPPED = 11;
+
+ /**
+ * Application process was killed because its dependency was going away, for example,
+ * a stable content provider connection's client will be killed if the provider is killed.
+ */
+ public static final int REASON_DEPENDENCY_DIED = 12;
+
+ /**
+ * Application process was killed by the system for various other reasons which are
+ * not by problems in apps and not actionable by apps, for example, the system just
+ * finished updates; {@link #getDescription} will specify the cause given by the system.
+ */
+ public static final int REASON_OTHER = 13;
/**
* Application process kills subreason is unknown.
@@ -202,6 +222,105 @@ public final class ApplicationExitInfo implements Parcelable {
public static final int SUBREASON_EXCESSIVE_CPU = 7;
/**
+ * System update has done (so the system update process should be killed);
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_SYSTEM_UPDATE_DONE = 8;
+
+ /**
+ * Kill all foreground services, for now it only occurs when enabling the quiet
+ * mode for the managed profile;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_KILL_ALL_FG = 9;
+
+ /**
+ * All background processes except certain ones were killed, for now it only occurs
+ * when the density of the default display is changed;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_KILL_ALL_BG_EXCEPT = 10;
+
+ /**
+ * The process associated with the UID was explicitly killed, for example,
+ * it could be because of platform compatibility overrides;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_KILL_UID = 11;
+
+ /**
+ * The process was explicitly killed with its PID, typically because of
+ * the low memory for surfaces;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_KILL_PID = 12;
+
+ /**
+ * The start of the process was invalid;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_INVALID_START = 13;
+
+ /**
+ * The process was killed because it's in an invalid state, typically
+ * it's triggered from SHELL;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_INVALID_STATE = 14;
+
+ /**
+ * The process was killed when it's imperceptible to user, because it was
+ * in a bad state;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_IMPERCEPTIBLE = 15;
+
+ /**
+ * The process was killed because it's being moved out from LRU list;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_REMOVE_LRU = 16;
+
+ /**
+ * The process was killed because it's isolated and was in a cached state;
+ * this would be set only when the reason is {@link #REASON_OTHER}.
+ *
+ * For internal use only.
+ * @hide
+ */
+ public static final int SUBREASON_ISOLATED_NOT_NEEDED = 17;
+
+ // If there is any OEM code which involves additional app kill reasons, it should
+ // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
+
+ /**
* @see {@link #getPid}
*/
private int mPid;
@@ -254,7 +373,7 @@ public final class ApplicationExitInfo implements Parcelable {
/**
* @see {@link #getTimestamp}
*/
- private long mTimestamp;
+ private @CurrentTimeMillisLong long mTimestamp;
/**
* @see {@link #getDescription}
@@ -293,6 +412,9 @@ public final class ApplicationExitInfo implements Parcelable {
REASON_INITIALIZATION_FAILURE,
REASON_PERMISSION_CHANGE,
REASON_EXCESSIVE_RESOURCE_USAGE,
+ REASON_USER_REQUESTED,
+ REASON_USER_STOPPED,
+ REASON_DEPENDENCY_DIED,
REASON_OTHER,
})
@Retention(RetentionPolicy.SOURCE)
@@ -308,6 +430,16 @@ public final class ApplicationExitInfo implements Parcelable {
SUBREASON_LARGE_CACHED,
SUBREASON_MEMORY_PRESSURE,
SUBREASON_EXCESSIVE_CPU,
+ SUBREASON_SYSTEM_UPDATE_DONE,
+ SUBREASON_KILL_ALL_FG,
+ SUBREASON_KILL_ALL_BG_EXCEPT,
+ SUBREASON_KILL_UID,
+ SUBREASON_KILL_PID,
+ SUBREASON_INVALID_START,
+ SUBREASON_INVALID_STATE,
+ SUBREASON_IMPERCEPTIBLE,
+ SUBREASON_REMOVE_LRU,
+ SUBREASON_ISOLATED_NOT_NEEDED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SubReason {}
@@ -403,7 +535,7 @@ public final class ApplicationExitInfo implements Parcelable {
* The timestamp of the process's death, in milliseconds since the epoch,
* as returned by {@link System#currentTimeMillis System.currentTimeMillis()}.
*/
- public long getTimestamp() {
+ public @CurrentTimeMillisLong long getTimestamp() {
return mTimestamp;
}
@@ -564,7 +696,7 @@ public final class ApplicationExitInfo implements Parcelable {
*
* @hide
*/
- public void setTimestamp(final long timestamp) {
+ public void setTimestamp(final @CurrentTimeMillisLong long timestamp) {
mTimestamp = timestamp;
}
@@ -656,6 +788,8 @@ public final class ApplicationExitInfo implements Parcelable {
mRss = other.mRss;
mTimestamp = other.mTimestamp;
mDescription = other.mDescription;
+ mPackageName = other.mPackageName;
+ mPackageList = other.mPackageList;
}
private ApplicationExitInfo(@NonNull Parcel in) {
@@ -748,6 +882,12 @@ public final class ApplicationExitInfo implements Parcelable {
return "PERMISSION CHANGE";
case REASON_EXCESSIVE_RESOURCE_USAGE:
return "EXCESSIVE RESOURCE USAGE";
+ case REASON_USER_REQUESTED:
+ return "USER REQUESTED";
+ case REASON_USER_STOPPED:
+ return "USER STOPPED";
+ case REASON_DEPENDENCY_DIED:
+ return "DEPENDENCY DIED";
case REASON_OTHER:
return "OTHER KILLS BY SYSTEM";
default:
@@ -772,6 +912,26 @@ public final class ApplicationExitInfo implements Parcelable {
return "MEMORY PRESSURE";
case SUBREASON_EXCESSIVE_CPU:
return "EXCESSIVE CPU USAGE";
+ case SUBREASON_SYSTEM_UPDATE_DONE:
+ return "SYSTEM UPDATE_DONE";
+ case SUBREASON_KILL_ALL_FG:
+ return "KILL ALL FG";
+ case SUBREASON_KILL_ALL_BG_EXCEPT:
+ return "KILL ALL BG EXCEPT";
+ case SUBREASON_KILL_UID:
+ return "KILL UID";
+ case SUBREASON_KILL_PID:
+ return "KILL PID";
+ case SUBREASON_INVALID_START:
+ return "INVALID START";
+ case SUBREASON_INVALID_STATE:
+ return "INVALID STATE";
+ case SUBREASON_IMPERCEPTIBLE:
+ return "IMPERCEPTIBLE";
+ case SUBREASON_REMOVE_LRU:
+ return "REMOVE LRU";
+ case SUBREASON_ISOLATED_NOT_NEEDED:
+ return "ISOLATED NOT NEEDED";
default:
return "UNKNOWN";
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index be07b3725bde..a3bcc9cee39b 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;
@@ -1343,7 +1342,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 a8f7610ecaf0..aba86e9f1054 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5109,16 +5109,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/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java
index f2e16b46422f..a9585c62866b 100644
--- a/core/java/android/os/BatteryStatsManager.java
+++ b/core/java/android/os/BatteryStatsManager.java
@@ -350,12 +350,13 @@ public final class BatteryStatsManager {
/**
* Indicates that an app has acquired the wifi multicast lock.
*
- * @param uid UID of the app that acquired the wifi lock (to be used for battery blaming).
+ * @param ws Worksource with the uid of the app that acquired the wifi lock (to be used for
+ * battery blaming).
*/
@RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public void reportWifiMulticastEnabled(int uid) {
+ public void reportWifiMulticastEnabled(@NonNull WorkSource ws) {
try {
- mBatteryStats.noteWifiMulticastEnabled(uid);
+ mBatteryStats.noteWifiMulticastEnabled(ws.getAttributionUid());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -364,12 +365,13 @@ public final class BatteryStatsManager {
/**
* Indicates that an app has released the wifi multicast lock.
*
- * @param uid UID of the app that released the wifi lock (to be used for battery blaming).
+ * @param ws Worksource with the uid of the app that released the wifi lock (to be used for
+ * battery blaming).
*/
@RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
- public void reportWifiMulticastDisabled(int uid) {
+ public void reportWifiMulticastDisabled(@NonNull WorkSource ws) {
try {
- mBatteryStats.noteWifiMulticastDisabled(uid);
+ mBatteryStats.noteWifiMulticastDisabled(ws.getAttributionUid());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 223f92054f79..de274c082c80 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -559,6 +559,37 @@ public class UpdateEngine {
}
}
+ private static class CleanupAppliedPayloadCallback extends IUpdateEngineCallback.Stub {
+ private int mErrorCode = ErrorCodeConstants.ERROR;
+ private boolean mCompleted = false;
+ private Object mLock = new Object();
+ private int getResult() {
+ synchronized (mLock) {
+ while (!mCompleted) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException ex) {
+ // do nothing, just wait again.
+ }
+ }
+ return mErrorCode;
+ }
+ }
+
+ @Override
+ public void onStatusUpdate(int status, float percent) {
+ }
+
+ @Override
+ public void onPayloadApplicationComplete(int errorCode) {
+ synchronized (mLock) {
+ mErrorCode = errorCode;
+ mCompleted = true;
+ mLock.notifyAll();
+ }
+ }
+ }
+
/**
* Cleanup files used by the previous update and free up space after the
* device has been booted successfully into the new build.
@@ -590,8 +621,10 @@ public class UpdateEngine {
@WorkerThread
@ErrorCode
public int cleanupAppliedPayload() {
+ CleanupAppliedPayloadCallback callback = new CleanupAppliedPayloadCallback();
try {
- return mUpdateEngine.cleanupSuccessfulUpdate();
+ mUpdateEngine.cleanupSuccessfulUpdate(callback);
+ return callback.getResult();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/connectivity/WifiBatteryStats.java b/core/java/android/os/connectivity/WifiBatteryStats.java
index 3c30f6343405..7e6ebcfc61db 100644
--- a/core/java/android/os/connectivity/WifiBatteryStats.java
+++ b/core/java/android/os/connectivity/WifiBatteryStats.java
@@ -215,7 +215,7 @@ public final class WifiBatteryStats implements Parcelable {
* Returns the number of bytes transmitted over wifi within
* {@link #getLoggingDurationMillis()}.
*
- * @return Number of packets received.
+ * @return Number of bytes transmitted.
*/
public long getNumBytesTx() {
return mNumBytesTx;
@@ -225,7 +225,7 @@ public final class WifiBatteryStats implements Parcelable {
* Returns the number of packets received over wifi within
* {@link #getLoggingDurationMillis()}.
*
- * @return Number of bytes transmitted.
+ * @return Number of packets received.
*/
public long getNumPacketsRx() {
return mNumPacketsRx;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index f745e4376896..6ab61850480d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -854,6 +854,11 @@ public class ResolverActivity extends Activity implements
private void setAlwaysButtonEnabled(boolean hasValidSelection, int checkedPos,
boolean filtered) {
+ if (mMultiProfilePagerAdapter.getCurrentUserHandle() != getUser()) {
+ // Never allow the inactive profile to always open an app.
+ mAlwaysButton.setEnabled(false);
+ return;
+ }
boolean enabled = false;
ResolveInfo ri = null;
if (hasValidSelection) {
@@ -877,19 +882,21 @@ public class ResolverActivity extends Activity implements
}
}
- ActivityInfo activityInfo = ri.activityInfo;
+ if (ri != null) {
+ ActivityInfo activityInfo = ri.activityInfo;
- boolean hasRecordPermission =
- mPm.checkPermission(android.Manifest.permission.RECORD_AUDIO,
- activityInfo.packageName)
- == android.content.pm.PackageManager.PERMISSION_GRANTED;
+ boolean hasRecordPermission =
+ mPm.checkPermission(android.Manifest.permission.RECORD_AUDIO,
+ activityInfo.packageName)
+ == android.content.pm.PackageManager.PERMISSION_GRANTED;
- if (!hasRecordPermission) {
- // OK, we know the record permission, is this a capture device
- boolean hasAudioCapture =
- getIntent().getBooleanExtra(
- ResolverActivity.EXTRA_IS_AUDIO_CAPTURE_DEVICE, false);
- enabled = !hasAudioCapture;
+ if (!hasRecordPermission) {
+ // OK, we know the record permission, is this a capture device
+ boolean hasAudioCapture =
+ getIntent().getBooleanExtra(
+ ResolverActivity.EXTRA_IS_AUDIO_CAPTURE_DEVICE, false);
+ enabled = !hasAudioCapture;
+ }
}
mAlwaysButton.setEnabled(enabled);
}
@@ -1567,10 +1574,26 @@ public class ResolverActivity extends Activity implements
viewPager.setVisibility(View.VISIBLE);
tabHost.setCurrentTab(mMultiProfilePagerAdapter.getCurrentPage());
- mMultiProfilePagerAdapter.setOnProfileSelectedListener(tabHost::setCurrentTab);
+ mMultiProfilePagerAdapter.setOnProfileSelectedListener(
+ index -> {
+ tabHost.setCurrentTab(index);
+ resetButtonBar();
+ resetCheckedItem();
+ });
findViewById(R.id.resolver_tab_divider).setVisibility(View.VISIBLE);
}
+ private void resetCheckedItem() {
+ if (!isIntentPicker()) {
+ return;
+ }
+ mLastSelected = ListView.INVALID_POSITION;
+ ListView inactiveListView = (ListView) mMultiProfilePagerAdapter.getInactiveAdapterView();
+ if (inactiveListView.getCheckedItemCount() > 0) {
+ inactiveListView.setItemChecked(inactiveListView.getCheckedItemPosition(), false);
+ }
+ }
+
private void resetTabsHeaderStyle(TabWidget tabWidget) {
for (int i = 0; i < tabWidget.getChildCount(); i++) {
TextView title = tabWidget.getChildAt(i).findViewById(android.R.id.title);
@@ -1677,6 +1700,10 @@ public class ResolverActivity extends Activity implements
}
private void resetAlwaysOrOnceButtonBar() {
+ // Disable both buttons initially
+ setAlwaysButtonEnabled(false, ListView.INVALID_POSITION, false);
+ mOnceButton.setEnabled(false);
+
int filteredPosition = mMultiProfilePagerAdapter.getActiveListAdapter()
.getFilteredPosition();
if (useLayoutWithDefault() && filteredPosition != ListView.INVALID_POSITION) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index ade2c7d86faf..9ddaa981c382 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -1,13 +1,4 @@
-genrule {
- name: "android_util_StatsLogInternal.cpp",
- tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp",
- out: [
- "android_util_StatsLogInternal.cpp",
- ],
-}
-
cc_library_shared {
name: "libandroid_runtime",
host_supported: true,
@@ -277,7 +268,6 @@ cc_library_shared {
// our headers include libnativewindow's public headers
"libnativewindow",
],
- generated_sources: ["android_util_StatsLogInternal.cpp"],
header_libs: ["bionic_libc_platform_headers"],
},
host: {
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c41398c97ca0..ba7aef7c208e 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -108,7 +108,6 @@ namespace android {
extern int register_android_app_admin_SecurityLog(JNIEnv* env);
extern int register_android_content_AssetManager(JNIEnv* env);
extern int register_android_util_EventLog(JNIEnv* env);
-extern int register_android_util_StatsLogInternal(JNIEnv* env);
extern int register_android_util_Log(JNIEnv* env);
extern int register_android_util_MemoryIntArray(JNIEnv* env);
extern int register_android_content_StringBlock(JNIEnv* env);
@@ -1435,7 +1434,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_MemoryIntArray),
- REG_JNI(register_android_util_StatsLogInternal),
REG_JNI(register_android_app_admin_SecurityLog),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
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/proto/android/app/appexit_enums.proto b/core/proto/android/app/appexit_enums.proto
new file mode 100644
index 000000000000..491e1dc203b5
--- /dev/null
+++ b/core/proto/android/app/appexit_enums.proto
@@ -0,0 +1,240 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package android.app;
+
+/**
+ * The reason code that why app process is killed.
+ */
+enum AppExitReasonCode {
+ /**
+ * Application process died due to unknown reason.
+ */
+ REASON_UNKNOWN = 0;
+
+ /**
+ * Application process exit normally by itself, for example,
+ * via {@link android.os.Process#exit}; {@link #status} will specify the exit code.
+ *
+ * <p>Applications should normally not do this, as the system has a better knowledge
+ * in terms of process management.</p>
+ */
+ REASON_EXIT_SELF = 1;
+
+ /**
+ * Application process died due to the result of an OS signal; for example,
+ * {@link android.os.Process#SIGNAL_KILL}; {@link #status} will specify the signum.
+ */
+ REASON_SIGNALED = 2;
+
+ /**
+ * Application process was killed by the system low memory killer, meaning the system was
+ * under memory pressure at the time of kill.
+ */
+ REASON_LOW_MEMORY = 3;
+
+ /**
+ * Application process died because of an unhandled exception in Java code.
+ */
+ REASON_CRASH = 4;
+
+ /**
+ * Application process died because it's crashed due to a native code crash.
+ */
+ REASON_CRASH_NATIVE = 5;
+
+ /**
+ * Application process was killed due to being unresponsive (ANR).
+ */
+ REASON_ANR = 6;
+
+ /**
+ * Application process was killed because it took too long to attach to the system
+ * during the start.
+ */
+ REASON_INITIALIZATION_FAILURE = 7;
+
+ /**
+ * Application process was killed because of initialization failure,
+ * for example, it took too long to attach to the system during the start,
+ * or there was an error during initialization.
+ */
+ REASON_PERMISSION_CHANGE = 8;
+
+ /**
+ * Application process was killed by the activity manager due to excessive resource usage.
+ */
+ REASON_EXCESSIVE_RESOURCE_USAGE = 9;
+
+ /**
+ * Application process was killed because of the user request, for example,
+ * user clicked the "Force stop" button of the application in the Settings,
+ * or swiped away the application from Recents.
+ */
+ REASON_USER_REQUESTED = 10;
+
+ /**
+ * Application process was killed, because the user they are running as on devices
+ * with mutlple users, was stopped.
+ */
+ REASON_USER_STOPPED = 11;
+
+ /**
+ * Application process was killed because its dependency was going away, for example,
+ * a stable content provider connection's client will be killed if the provider is killed.
+ */
+ REASON_DEPENDENCY_DIED = 12;
+
+ /**
+ * Application process was killed by the system for various other reasons,
+ * for example, the application package got disabled by the user;
+ * {@link #description} will specify the cause given by the system.
+ */
+ REASON_OTHER = 13;
+}
+
+/**
+ * The supplemental reason code that why app process is killed
+ */
+enum AppExitSubReasonCode {
+ /**
+ * Application process kills subReason is unknown.
+ */
+ SUBREASON_UNKNOWN = 0;
+
+ /**
+ * Application process was killed because user quit it on the "wait for debugger" dialog.
+ */
+ SUBREASON_WAIT_FOR_DEBUGGER = 1;
+
+ /**
+ * Application process was killed by the activity manager because there were too many cached
+ * processes.
+ */
+ SUBREASON_TOO_MANY_CACHED = 2;
+
+ /**
+ * Application process was killed by the activity manager because there were too many empty
+ * processes.
+ */
+ SUBREASON_TOO_MANY_EMPTY = 3;
+
+ /**
+ * Application process was killed by the activity manager because there were too many cached
+ * processes and this process had been in empty state for a long time.
+ */
+ SUBREASON_TRIM_EMPTY = 4;
+
+ /**
+ * Application process was killed by the activity manager because system was on
+ * memory pressure and this process took large amount of cached memory.
+ */
+ SUBREASON_LARGE_CACHED = 5;
+
+ /**
+ * Application process was killed by the activity manager because the system was on
+ * low memory pressure for a significant amount of time since last idle.
+ */
+ SUBREASON_MEMORY_PRESSURE = 6;
+
+ /**
+ * Application process was killed by the activity manager due to excessive CPU usage.
+ */
+ SUBREASON_EXCESSIVE_CPU = 7;
+
+ /**
+ * System update has done (so the system update process should be killed).
+ */
+ SUBREASON_SYSTEM_UPDATE_DONE = 8;
+
+ /**
+ * Kill all foreground services, for now it only occurs when enabling the quiet
+ * mode for the managed profile.
+ */
+ SUBREASON_KILL_ALL_FG = 9;
+
+ /**
+ * All background processes except certain ones were killed, for now it only occurs
+ * when the density of the default display is changed.
+ */
+ SUBREASON_KILL_ALL_BG_EXCEPT = 10;
+
+ /**
+ * The process associated with the UID was explicitly killed, for example,
+ * it could be because of permission changes.
+ */
+ SUBREASON_KILL_UID = 11;
+
+ /**
+ * The process was explicitly killed with its PID, typically because of
+ * the low memory for surfaces.
+ */
+ SUBREASON_KILL_PID = 12;
+
+ /**
+ * The start of the process was invalid.
+ */
+ SUBREASON_INVALID_START = 13;
+
+ /**
+ * The process was killed because it's in an invalid state, typically
+ * it's triggered from SHELL.
+ */
+ SUBREASON_INVALID_STATE = 14;
+
+ /**
+ * The process was killed when it's imperceptible to user, because it was
+ * in a bad state.
+ */
+ SUBREASON_IMPERCEPTIBLE = 15;
+
+ /**
+ * The process was killed because it's being moved out from LRU list.
+ */
+ SUBREASON_REMOVE_LRU = 16;
+
+ /**
+ * The process was killed because it's isolated and was in a cached state.
+ */
+ SUBREASON_ISOLATED_NOT_NEEDED = 17;
+}
+
+/**
+ * The relative importance level that the system places on a process.
+ * Keep sync with the definitions in
+ * {@link android.app.ActivityManager.RunningAppProcessInfo}
+ */
+enum Importance {
+ option allow_alias = true;
+
+ IMPORTANCE_FOREGROUND = 100;
+ IMPORTANCE_FOREGROUND_SERVICE = 125;
+ IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
+ IMPORTANCE_VISIBLE = 200;
+ IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
+ IMPORTANCE_PERCEPTIBLE = 230;
+ IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
+ IMPORTANCE_SERVICE = 300;
+ IMPORTANCE_TOP_SLEEPING = 325;
+ IMPORTANCE_CANT_SAVE_STATE = 350;
+ IMPORTANCE_CACHED = 400;
+ IMPORTANCE_BACKGROUND = 400;
+ IMPORTANCE_EMPTY = 500;
+ IMPORTANCE_GONE = 1000;
+}
diff --git a/core/proto/android/app/appexitinfo.proto b/core/proto/android/app/appexitinfo.proto
index 6a4922000805..66173f60bfd5 100644
--- a/core/proto/android/app/appexitinfo.proto
+++ b/core/proto/android/app/appexitinfo.proto
@@ -20,6 +20,7 @@ option java_multiple_files = true;
package android.app;
import "frameworks/base/core/proto/android/privacy.proto";
+import "frameworks/base/core/proto/android/app/appexit_enums.proto";
/**
* An android.app.ApplicationExitInfo object.
@@ -33,150 +34,9 @@ message ApplicationExitInfoProto {
optional int32 defining_uid = 4;
optional string process_name = 5;
optional int32 connection_group = 6;
-
- enum ReasonCode {
- /**
- * Application process died due to unknown reason.
- */
- REASON_UNKNOWN = 0;
-
- /**
- * Application process exit normally by itself, for example,
- * via {@link android.os.Process#exit}; {@link #status} will specify the exit code.
- *
- * <p>Applications should normally not do this, as the system has a better knowledge
- * in terms of process management.</p>
- */
- REASON_EXIT_SELF = 1;
-
- /**
- * Application process died due to the result of an OS signal; for example,
- * {@link android.os.Process#SIGNAL_KILL}; {@link #status} will specify the signum.
- */
- REASON_SIGNALED = 2;
-
- /**
- * Application process was killed by the system low memory killer, meaning the system was
- * under memory pressure at the time of kill.
- */
- REASON_LOW_MEMORY = 3;
-
- /**
- * Application process died because of an unhandled exception in Java code.
- */
- REASON_CRASH = 4;
-
- /**
- * Application process died because it's crashed due to a native code crash.
- */
- REASON_CRASH_NATIVE = 5;
-
- /**
- * Application process was killed due to being unresponsive (ANR).
- */
- REASON_ANR = 6;
-
- /**
- * Application process was killed because it took too long to attach to the system
- * during the start.
- */
- REASON_INITIALIZATION_FAILURE = 7;
-
- /**
- * Application process was killed because of initialization failure,
- * for example, it took too long to attach to the system during the start,
- * or there was an error during initialization.
- */
- REASON_PERMISSION_CHANGE = 8;
-
- /**
- * Application process was killed by the activity manager due to excessive resource usage.
- */
- REASON_EXCESSIVE_RESOURCE_USAGE = 9;
-
- /**
- * Application process was killed by the system for various other reasons,
- * for example, the application package got disabled by the user;
- * {@link #description} will specify the cause given by the system.
- */
- REASON_OTHER = 10;
-
- }
- optional ReasonCode reason = 7;
-
- enum SubReason {
- /**
- * Application process kills subReason is unknown.
- */
- SUBREASON_UNKNOWN = 0;
-
- /**
- * Application process was killed because user quit it on the "wait for debugger" dialog.
- */
- SUBREASON_WAIT_FOR_DEBUGGER = 1;
-
- /**
- * Application process was killed by the activity manager because there were too many cached
- * processes.
- */
- SUBREASON_TOO_MANY_CACHED = 2;
-
- /**
- * Application process was killed by the activity manager because there were too many empty
- * processes.
- */
- SUBREASON_TOO_MANY_EMPTY = 3;
-
- /**
- * Application process was killed by the activity manager because there were too many cached
- * processes and this process had been in empty state for a long time.
- */
- SUBREASON_TRIM_EMPTY = 4;
-
- /**
- * Application process was killed by the activity manager because system was on
- * memory pressure and this process took large amount of cached memory.
- */
- SUBREASON_LARGE_CACHED = 5;
-
- /**
- * Application process was killed by the activity manager because the system was on
- * low memory pressure for a significant amount of time since last idle.
- */
- SUBREASON_MEMORY_PRESSURE = 6;
-
- /**
- * Application process was killed by the activity manager due to excessive CPU usage.
- */
- SUBREASON_EXCESSIVE_CPU = 7;
- }
-
- optional SubReason sub_reason = 8;
-
+ optional AppExitReasonCode reason = 7;
+ optional AppExitSubReasonCode sub_reason = 8;
optional int32 status = 9;
-
- enum Importance {
- option allow_alias = true;
- /**
- * Keep sync with the definitions in
- * {@link android.app.ActivityManager.RunningAppProcessInfo}
- */
- IMPORTANCE_FOREGROUND = 100;
- IMPORTANCE_FOREGROUND_SERVICE = 125;
- IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
- IMPORTANCE_VISIBLE = 200;
- IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
- IMPORTANCE_PERCEPTIBLE = 230;
- IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
- IMPORTANCE_SERVICE = 300;
- IMPORTANCE_TOP_SLEEPING = 325;
- IMPORTANCE_CANT_SAVE_STATE = 350;
- IMPORTANCE_CACHED = 400;
- IMPORTANCE_BACKGROUND = 400;
- IMPORTANCE_EMPTY = 500;
- IMPORTANCE_GONE = 1000;
- }
-
optional Importance importance = 10;
optional int64 pss = 11;
optional int64 rss = 12;
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index eb760b9c45cf..8d51a6000086 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -53,10 +53,7 @@ android_test {
"android.test.base",
"android.test.mock",
"framework-atb-backward-compatibility",
- // 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/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index d683041fbfdc..d9d2eea3536e 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -1264,8 +1264,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* successfully.
*
* @param timeout duration in seconds or {@code 0} if user authentication must take place
- * for every use of the key. {@code -1} is also accepted for legacy purposes. It is
- * functionally the same as {@code 0}.
+ * for every use of the key.
* @param type set of authentication types which can authorize use of the key. See
* {@link KeyProperties}.{@code AUTH} flags.
*
@@ -1275,12 +1274,10 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
* @see KeyguardManager
*/
@NonNull
- public Builder setUserAuthenticationParameters(@IntRange(from = -1) int timeout,
+ public Builder setUserAuthenticationParameters(@IntRange(from = 0) int timeout,
@KeyProperties.AuthEnum int type) {
- if (timeout < -1) {
- throw new IllegalArgumentException("timeout must be -1 or larger");
- } else if (timeout == -1) {
- timeout = 0;
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout must be 0 or larger");
}
mUserAuthenticationValidityDurationSeconds = timeout;
mUserAuthenticationType = type;
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index e230b7c3708b..8120a93e30e9 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -894,8 +894,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* successfully.
*
* @param timeout duration in seconds or {@code 0} if user authentication must take place
- * for every use of the key. {@code -1} is also accepted for legacy purposes. It is
- * functionally the same as {@code 0}.
+ * for every use of the key.
* @param type set of authentication types which can authorize use of the key. See
* {@link KeyProperties}.{@code AUTH} flags.
*
@@ -905,12 +904,10 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
* @see KeyguardManager
*/
@NonNull
- public Builder setUserAuthenticationParameters(@IntRange(from = -1) int timeout,
+ public Builder setUserAuthenticationParameters(@IntRange(from = 0) int timeout,
@KeyProperties.AuthEnum int type) {
- if (timeout < -1) {
- throw new IllegalArgumentException("timeout must be -1 or larger");
- } else if (timeout == -1) {
- timeout = 0;
+ if (timeout < 0) {
+ throw new IllegalArgumentException("timeout must be 0 or larger");
}
mUserAuthenticationValidityDurationSeconds = timeout;
mUserAuthenticationType = type;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 31e45558139d..6761435a8171 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -27,6 +27,7 @@
#include "DamageAccumulator.h"
#include "pipeline/skia/SkiaDisplayList.h"
#endif
+#include "utils/FatVector.h"
#include "utils/MathUtils.h"
#include "utils/StringUtils.h"
#include "utils/TraceUtils.h"
@@ -36,7 +37,6 @@
#include <atomic>
#include <sstream>
#include <string>
-#include <ui/FatVector.h>
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index c0ec2174bb35..d55e5b0ce836 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -27,8 +27,6 @@
#include <androidfw/ResourceTypes.h>
-#include <ui/FatVector.h>
-
#include "AnimatorManager.h"
#include "CanvasTransform.h"
#include "Debug.h"
@@ -37,6 +35,7 @@
#include "RenderProperties.h"
#include "pipeline/skia/SkiaDisplayList.h"
#include "pipeline/skia/SkiaLayer.h"
+#include "utils/FatVector.h"
#include <vector>
diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp
index a2fef1e19328..0ce04a2437b9 100644
--- a/libs/hwui/jni/FontFamily.cpp
+++ b/libs/hwui/jni/FontFamily.cpp
@@ -29,9 +29,9 @@
#include <hwui/MinikinSkia.h>
#include <hwui/Typeface.h>
+#include <utils/FatVector.h>
#include <minikin/FontFamily.h>
#include <minikin/LocaleList.h>
-#include <ui/FatVector.h>
#include <memory>
@@ -104,7 +104,7 @@ static jlong FontFamily_getFamilyReleaseFunc(CRITICAL_JNI_PARAMS) {
static bool addSkTypeface(NativeFamilyBuilder* builder, sk_sp<SkData>&& data, int ttcIndex,
jint weight, jint italic) {
- FatVector<SkFontArguments::Axis, 2> skiaAxes;
+ uirenderer::FatVector<SkFontArguments::Axis, 2> skiaAxes;
for (const auto& axis : builder->axes) {
skiaAxes.emplace_back(SkFontArguments::Axis{axis.axisTag, axis.value});
}
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index 5714cd1d0390..7e8f8d8d173c 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -28,8 +28,8 @@
#include <hwui/MinikinSkia.h>
#include <hwui/Typeface.h>
+#include <utils/FatVector.h>
#include <minikin/FontFamily.h>
-#include <ui/FatVector.h>
#include <memory>
@@ -93,7 +93,7 @@ static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jo
sk_sp<SkData> data(SkData::MakeWithProc(fontPtr, fontSize,
release_global_ref, reinterpret_cast<void*>(fontRef)));
- FatVector<SkFontArguments::Axis, 2> skiaAxes;
+ uirenderer::FatVector<SkFontArguments::Axis, 2> skiaAxes;
for (const auto& axis : builder->axes) {
skiaAxes.emplace_back(SkFontArguments::Axis{axis.axisTag, axis.value});
}
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
index d669f84c5ee2..cfc0f9b258da 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -21,7 +21,7 @@
#include <SkCanvas.h>
#include <SkDrawable.h>
-#include <ui/FatVector.h>
+#include <utils/FatVector.h>
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 206b58f62ea7..cae3e3b5188c 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -27,6 +27,7 @@
#include "pipeline/skia/SkiaOpenGLPipeline.h"
#include "pipeline/skia/SkiaVulkanPipeline.h"
#include "renderstate/RenderState.h"
+#include "utils/FatVector.h"
#include "utils/TimeUtils.h"
#include "utils/TraceUtils.h"
@@ -39,8 +40,6 @@
#include <utils/Mutex.h>
#include <thread>
-#include <ui/FatVector.h>
-
namespace android {
namespace uirenderer {
namespace renderthread {
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index ba70afc8b8d2..a5355fc3499d 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -23,13 +23,13 @@
#include <GrContext.h>
#include <GrTypes.h>
#include <android/sync.h>
-#include <ui/FatVector.h>
#include <vk/GrVkExtensions.h>
#include <vk/GrVkTypes.h>
#include "Properties.h"
#include "RenderThread.h"
#include "renderstate/RenderState.h"
+#include "utils/FatVector.h"
#include "utils/TraceUtils.h"
namespace android {
diff --git a/libs/hwui/tests/unit/FatVectorTests.cpp b/libs/hwui/tests/unit/FatVectorTests.cpp
index 6585a6249b44..8523e6c9e973 100644
--- a/libs/hwui/tests/unit/FatVectorTests.cpp
+++ b/libs/hwui/tests/unit/FatVectorTests.cpp
@@ -15,7 +15,7 @@
*/
#include <gtest/gtest.h>
-#include <ui/FatVector.h>
+#include <utils/FatVector.h>
#include <tests/common/TestUtils.h>
diff --git a/libs/hwui/utils/FatVector.h b/libs/hwui/utils/FatVector.h
new file mode 100644
index 000000000000..49f1984b779f
--- /dev/null
+++ b/libs/hwui/utils/FatVector.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015, 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.
+ */
+
+#ifndef ANDROID_FAT_VECTOR_H
+#define ANDROID_FAT_VECTOR_H
+
+#include "utils/Macros.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <type_traits>
+
+#include <vector>
+
+namespace android {
+namespace uirenderer {
+
+template <typename T, size_t SIZE>
+class InlineStdAllocator {
+public:
+ struct Allocation {
+ PREVENT_COPY_AND_ASSIGN(Allocation);
+
+ public:
+ Allocation(){};
+ // char array instead of T array, so memory is uninitialized, with no destructors run
+ char array[sizeof(T) * SIZE];
+ bool inUse = false;
+ };
+
+ typedef T value_type; // needed to implement std::allocator
+ typedef T* pointer; // needed to implement std::allocator
+
+ explicit InlineStdAllocator(Allocation& allocation) : mAllocation(allocation) {}
+ InlineStdAllocator(const InlineStdAllocator& other) : mAllocation(other.mAllocation) {}
+ ~InlineStdAllocator() {}
+
+ T* allocate(size_t num, const void* = 0) {
+ if (!mAllocation.inUse && num <= SIZE) {
+ mAllocation.inUse = true;
+ return (T*)mAllocation.array;
+ } else {
+ return (T*)malloc(num * sizeof(T));
+ }
+ }
+
+ void deallocate(pointer p, size_t num) {
+ if (p == (T*)mAllocation.array) {
+ mAllocation.inUse = false;
+ } else {
+ // 'free' instead of delete here - destruction handled separately
+ free(p);
+ }
+ }
+ Allocation& mAllocation;
+};
+
+/**
+ * std::vector with SIZE elements preallocated into an internal buffer.
+ *
+ * Useful for avoiding the cost of malloc in cases where only SIZE or
+ * fewer elements are needed in the common case.
+ */
+template <typename T, size_t SIZE>
+class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
+public:
+ FatVector()
+ : std::vector<T, InlineStdAllocator<T, SIZE>>(
+ InlineStdAllocator<T, SIZE>(mAllocation)) {
+ this->reserve(SIZE);
+ }
+
+ explicit FatVector(size_t capacity) : FatVector() { this->resize(capacity); }
+
+private:
+ typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
+};
+
+} // namespace uirenderer
+} // namespace android
+
+#endif // ANDROID_FAT_VECTOR_H
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 256c5d51c421..5077e18b06e4 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -81,11 +81,6 @@ public class AssistManager {
void onGestureCompletion(float velocity);
/**
- * Called with the Bundle from VoiceInteractionSessionListener.onSetUiHints.
- */
- void processBundle(Bundle hints);
-
- /**
* Hides any SysUI for the assistant, but _does not_ close the assistant itself.
*/
void hide();
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
index f201a6fb1137..68242f0a0ac2 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DefaultUiController.java
@@ -26,7 +26,6 @@ import android.content.Context;
import android.graphics.PixelFormat;
import android.metrics.LogMaker;
import android.os.Build;
-import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -94,11 +93,6 @@ public class DefaultUiController implements AssistManager.UiController {
}
@Override // AssistManager.UiController
- public void processBundle(Bundle bundle) {
- Log.e(TAG, "Bundle received but handling is not implemented; ignoring");
- }
-
- @Override // AssistManager.UiController
public void onInvocationProgress(int type, float progress) {
boolean invocationWasInProgress = mInvocationInProgress;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
index 1ae3d4f482f4..fb348f483c46 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java
@@ -42,6 +42,8 @@ import android.view.WindowManagerGlobal;
import java.io.PrintWriter;
+import javax.inject.Inject;
+
/**
* Handles bounds calculation for PIP on Phone and other form factors, it keeps tracking variant
* state changes originated from Window Manager and is the source of truth for PiP window bounds.
@@ -81,9 +83,10 @@ public class PipBoundsHandler {
private boolean mIsShelfShowing;
private int mShelfHeight;
- public PipBoundsHandler(Context context) {
+ @Inject
+ public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm) {
mContext = context;
- mSnapAlgorithm = new PipSnapAlgorithm(context);
+ mSnapAlgorithm = pipSnapAlgorithm;
mWindowManager = WindowManagerGlobal.getWindowManagerService();
reloadResources();
// Initialize the aspect ratio to the default aspect ratio. Don't do this in reload
diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
index 6bd28c5e7221..6df6b5ae76cc 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java
@@ -25,6 +25,8 @@ import android.util.Size;
import java.io.PrintWriter;
+import javax.inject.Inject;
+
/**
* Calculates the snap targets and the snap position for the PIP given a position and a velocity.
* All bounds are relative to the display top/left.
@@ -39,6 +41,7 @@ public class PipSnapAlgorithm {
private int mOrientation = Configuration.ORIENTATION_UNDEFINED;
+ @Inject
public PipSnapAlgorithm(Context context) {
Resources res = context.getResources();
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 8ada3c393222..4b97d134761e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -41,6 +41,7 @@ import com.android.systemui.UiOffloadThread;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.pip.BasePipManager;
import com.android.systemui.pip.PipBoundsHandler;
+import com.android.systemui.pip.PipSnapAlgorithm;
import com.android.systemui.pip.PipTaskOrganizer;
import com.android.systemui.shared.recents.IPinnedStackAnimationListener;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -205,7 +206,9 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
DisplayController displayController,
FloatingContentCoordinator floatingContentCoordinator,
- DeviceConfigProxy deviceConfig) {
+ DeviceConfigProxy deviceConfig,
+ PipBoundsHandler pipBoundsHandler,
+ PipSnapAlgorithm pipSnapAlgorithm) {
mContext = context;
mActivityManager = ActivityManager.getService();
@@ -218,7 +221,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
final IActivityTaskManager activityTaskManager = ActivityTaskManager.getService();
- mPipBoundsHandler = new PipBoundsHandler(context);
+ mPipBoundsHandler = pipBoundsHandler;
mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mInputConsumerController = InputConsumerController.getPipInputConsumer();
@@ -227,7 +230,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
mInputConsumerController);
mTouchHandler = new PipTouchHandler(context, mActivityManager, activityTaskManager,
mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer,
- floatingContentCoordinator, deviceConfig);
+ floatingContentCoordinator, deviceConfig, pipSnapAlgorithm);
mAppOpsListener = new PipAppOpsListener(context, mActivityManager,
mTouchHandler.getMotionHelper());
displayController.addDisplayChangingController(mRotationController);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index c3212b8b8078..90db91a7a29e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -166,7 +166,8 @@ public class PipTouchHandler {
PipBoundsHandler pipBoundsHandler,
PipTaskOrganizer pipTaskOrganizer,
FloatingContentCoordinator floatingContentCoordinator,
- DeviceConfigProxy deviceConfig) {
+ DeviceConfigProxy deviceConfig,
+ PipSnapAlgorithm pipSnapAlgorithm) {
// Initialize the Pip input consumer
mContext = context;
mActivityManager = activityManager;
@@ -174,7 +175,7 @@ public class PipTouchHandler {
mMenuController = menuController;
mMenuController.addListener(new PipMenuListener());
mDismissViewController = new PipDismissViewController(context);
- mSnapAlgorithm = new PipSnapAlgorithm(mContext);
+ mSnapAlgorithm = pipSnapAlgorithm;
mFlingAnimationUtils = new FlingAnimationUtils(context.getResources().getDisplayMetrics(),
2.5f);
mGesture = new DefaultPipTouchGesture();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index f28c3f6e71ec..ca44f6b364a7 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -228,13 +228,14 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
}
@Inject
- public PipManager(Context context, BroadcastDispatcher broadcastDispatcher) {
+ public PipManager(Context context, BroadcastDispatcher broadcastDispatcher,
+ PipBoundsHandler pipBoundsHandler) {
if (mInitialized) {
return;
}
mInitialized = true;
mContext = context;
- mPipBoundsHandler = new PipBoundsHandler(context);
+ mPipBoundsHandler = pipBoundsHandler;
mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler);
mPipTaskOrganizer.registerPipTransitionCallback(this);
mActivityTaskManager = ActivityTaskManager.getService();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
index 3b00684786b8..b12db2b44e3d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java
@@ -58,7 +58,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
initializeMockResources();
- mPipBoundsHandler = new PipBoundsHandler(mContext);
+ mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext));
mPipBoundsHandler.onDisplayInfoChanged(mDefaultDisplayInfo);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
index 2c9fd2c64291..5d0349dbbb60 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationEntryManagerInflationTest.java
@@ -64,6 +64,7 @@ import com.android.systemui.statusbar.notification.collection.inflation.Notifica
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
+import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.notification.row.dagger.ExpandableNotificationRowComponent;
import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -76,6 +77,7 @@ import com.android.systemui.util.time.FakeSystemClock;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
@@ -84,12 +86,11 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
-import java.util.concurrent.CountDownLatch;
-
/**
* Functional tests for notification inflation from {@link NotificationEntryManager}.
*/
@SmallTest
+@Ignore("Flaking")
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
public class NotificationEntryManagerInflationTest extends SysuiTestCase {
@@ -131,7 +132,6 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
private NotificationEntryManager mEntryManager;
private NotificationRowBinderImpl mRowBinder;
private Handler mHandler;
- private CountDownLatch mCountDownLatch;
@Before
public void setUp() {
@@ -305,7 +305,9 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
NotificationEntry entry = entryCaptor.getValue();
- waitForInflation();
+ // Wait for inflation
+ // row inflation, system notification, remote views, contracted view
+ waitForMessages(4);
// THEN the notification has its row inflated
assertNotNull(entry.getRow());
@@ -332,7 +334,7 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
NotificationEntry.class);
verify(mEntryListener).onPendingEntryAdded(entryCaptor.capture());
NotificationEntry entry = entryCaptor.getValue();
- waitForInflation();
+ waitForMessages(4);
Mockito.reset(mEntryListener);
Mockito.reset(mPresenter);
@@ -340,7 +342,9 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
// WHEN the notification is updated
mEntryManager.updateNotification(mSbn, mRankingMap);
- waitForInflation();
+ // Wait for inflation
+ // remote views, contracted view
+ waitForMessages(2);
// THEN the notification has its row and inflated
assertNotNull(entry.getRow());
@@ -353,31 +357,32 @@ public class NotificationEntryManagerInflationTest extends SysuiTestCase {
verify(mPresenter).updateNotificationViews();
}
- private void waitForInflation() {
+ /**
+ * Wait for a certain number of messages to finish before continuing, timing out if they never
+ * occur.
+ *
+ * As part of the inflation pipeline, the main thread is forced to deal with several callbacks
+ * due to the nature of the API used (generally because they're {@link android.os.AsyncTask}
+ * callbacks). In order, these are
+ *
+ * 1) Callback after row inflation. See {@link RowInflaterTask}.
+ * 2) Callback checking if row is system notification. See
+ * {@link ExpandableNotificationRow#setEntry}
+ * 3) Callback after remote views are created. See
+ * {@link NotificationContentInflater.AsyncInflationTask}.
+ * 4-6) Callback after each content view is inflated/rebound from remote view. See
+ * {@link NotificationContentInflater#applyRemoteView} and {@link InflationFlag}.
+ *
+ * Depending on the test, only some of these will be necessary. For example, generally, not
+ * every content view is inflated or the row may not be inflated if one already exists.
+ *
+ * Currently, the burden is on the developer to figure these out until we have a much more
+ * test-friendly way of executing inflation logic (i.e. pass in an executor).
+ */
+ private void waitForMessages(int numMessages) {
mHandler.postDelayed(TIMEOUT_RUNNABLE, TIMEOUT_TIME);
- final CountDownLatch latch = new CountDownLatch(1);
- NotificationEntryListener inflationListener = new NotificationEntryListener() {
- @Override
- public void onEntryInflated(NotificationEntry entry) {
- latch.countDown();
- }
-
- @Override
- public void onEntryReinflated(NotificationEntry entry) {
- latch.countDown();
- }
-
- @Override
- public void onInflationError(StatusBarNotification notification, Exception exception) {
- latch.countDown();
- }
- };
- mEntryManager.addNotificationEntryListener(inflationListener);
- while (latch.getCount() != 0) {
- TestableLooper.get(this).processMessages(1);
- }
+ TestableLooper.get(this).processMessages(numMessages);
mHandler.removeCallbacks(TIMEOUT_RUNNABLE);
- mEntryManager.removeNotificationEntryListener(inflationListener);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index fbcb0102eb47..9058ac451455 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -81,6 +81,8 @@ import static android.os.Process.removeAllProcessGroups;
import static android.os.Process.sendSignal;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;
+import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
+import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
@@ -4243,7 +4245,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
synchronized (this) {
mProcessList.killPackageProcessesLocked(packageName, appId, targetUserId,
- ProcessList.SERVICE_ADJ, "kill background");
+ ProcessList.SERVICE_ADJ, ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN, "kill background");
}
}
} finally {
@@ -4269,7 +4272,10 @@ public class ActivityManagerService extends IActivityManager.Stub
// because this method is also used to simulate low memory.
mAllowLowerMemLevel = true;
mProcessList.killPackageProcessesLocked(null /* packageName */, -1 /* appId */,
- UserHandle.USER_ALL, ProcessList.CACHED_APP_MIN_ADJ, "kill all background");
+ UserHandle.USER_ALL, ProcessList.CACHED_APP_MIN_ADJ,
+ ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
+ "kill all background");
doLowMemReportIfNeededLocked(null);
}
@@ -4757,6 +4763,9 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,
ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,
evenPersistent, true /* setRemoved */,
+ packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
+ : ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
packageName == null ? ("stop user " + userId) : ("stop " + packageName));
didSomething |=
@@ -4820,7 +4829,10 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this")
private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
cleanupAppInLaunchingProvidersLocked(app, true);
- mProcessList.removeProcessLocked(app, false, true, "timeout publishing content providers");
+ mProcessList.removeProcessLocked(app, false, true,
+ ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
+ "timeout publishing content providers");
}
@GuardedBy("this")
@@ -4925,7 +4937,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (pid > 0 && pid != MY_PID) {
killProcessQuiet(pid);
//TODO: killProcessGroup(app.info.uid, pid);
- mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
+ mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
ApplicationExitInfo.SUBREASON_UNKNOWN, "attach failed");
} else {
try {
@@ -9054,7 +9066,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
int adj = proc.setAdj;
if (adj >= worstType && !proc.killedByAm) {
- proc.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
+ proc.kill(reason, ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_KILL_PID, true);
killed = true;
}
}
@@ -9068,10 +9081,17 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
final long identity = Binder.clearCallingIdentity();
try {
+ boolean permissionChange = KILL_APP_REASON_PERMISSIONS_REVOKED.equals(reason)
+ || KILL_APP_REASON_GIDS_CHANGED.equals(reason);
mProcessList.killPackageProcessesLocked(null /* packageName */, appId, userId,
ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */,
true /* callerWillRestart */, true /* doit */, true /* evenPersistent */,
- false /* setRemoved */, reason != null ? reason : "kill uid");
+ false /* setRemoved */,
+ permissionChange ? ApplicationExitInfo.REASON_PERMISSION_CHANGE
+ : ApplicationExitInfo.REASON_OTHER,
+ permissionChange ? ApplicationExitInfo.SUBREASON_UNKNOWN
+ : ApplicationExitInfo.SUBREASON_KILL_UID,
+ reason != null ? reason : "kill uid");
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -9396,7 +9416,10 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
- mProcessList.removeProcessLocked(proc, true, false, "system update done");
+ mProcessList.removeProcessLocked(proc, true, false,
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_SYSTEM_UPDATE_DONE,
+ "system update done");
}
}
@@ -14400,7 +14423,8 @@ public class ActivityManagerService extends IActivityManager.Stub
+ cpr.name.flattenToShortString()
+ " in dying proc " + (proc != null ? proc.processName : "??")
+ " (adj " + (proc != null ? proc.setAdj : "??") + ")",
- ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.REASON_DEPENDENCY_DIED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
true);
}
} else if (capp.thread != null && conn.provider.provider != null) {
@@ -15892,7 +15916,10 @@ public class ActivityManagerService extends IActivityManager.Stub
-1);
mProcessList.killPackageProcessesLocked(ssp,
UserHandle.getAppId(extraUid),
- userId, ProcessList.INVALID_ADJ, "change " + ssp);
+ userId, ProcessList.INVALID_ADJ,
+ ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
+ "change " + ssp);
}
cleanupDisabledPackageComponentsLocked(ssp, userId,
intent.getStringArrayExtra(
@@ -18622,7 +18649,10 @@ public class ActivityManagerService extends IActivityManager.Stub
final int N = procs.size();
for (int i = 0; i < N; i++) {
- mProcessList.removeProcessLocked(procs.get(i), false, true, "kill all fg");
+ mProcessList.removeProcessLocked(procs.get(i), false, true,
+ ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_KILL_ALL_FG,
+ "kill all fg");
}
}
}
@@ -18844,7 +18874,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final ProcessRecord pr = (ProcessRecord) wpc.mOwner;
if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
&& pr.curReceivers.isEmpty()) {
- pr.kill("remove task", ApplicationExitInfo.REASON_OTHER, true);
+ pr.kill("remove task", ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN, true);
} else {
// We delay killing processes that are not in the background or running a
// receiver.
@@ -18861,7 +18892,7 @@ public class ActivityManagerService extends IActivityManager.Stub
true /* keepIfLarge */);
if (proc != null) {
mProcessList.removeProcessLocked(proc, false /* callerWillRestart */,
- true /* allowRestart */, reason);
+ true /* allowRestart */, ApplicationExitInfo.REASON_OTHER, reason);
}
}
}
@@ -19547,7 +19578,10 @@ public class ActivityManagerService extends IActivityManager.Stub
try {
synchronized(this) {
mProcessList.killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid),
- userId, ProcessList.FOREGROUND_APP_ADJ, "dep: " + packageName);
+ userId, ProcessList.FOREGROUND_APP_ADJ,
+ ApplicationExitInfo.REASON_DEPENDENCY_DIED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN,
+ "dep: " + packageName);
}
} finally {
Binder.restoreCallingIdentity(callingId);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 789f7199948d..b1fc0296518b 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -395,7 +395,7 @@ class AppErrors {
() -> {
synchronized (mService) {
killAppImmediateLocked(p, ApplicationExitInfo.REASON_OTHER,
- ApplicationExitInfo.SUBREASON_UNKNOWN,
+ ApplicationExitInfo.SUBREASON_INVALID_STATE,
"forced", "killed for invalid state");
}
},
@@ -510,8 +510,8 @@ class AppErrors {
stopReportingCrashesLocked(r);
}
if (res == AppErrorDialog.RESTART) {
- mService.mProcessList.removeProcessLocked(r, false, true, "crash",
- ApplicationExitInfo.REASON_CRASH);
+ mService.mProcessList.removeProcessLocked(r, false, true,
+ ApplicationExitInfo.REASON_CRASH, "crash");
if (taskId != INVALID_TASK_ID) {
try {
mService.startActivityFromRecents(taskId,
@@ -529,8 +529,8 @@ class AppErrors {
// Kill it with fire!
mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
if (!r.isPersistent()) {
- mService.mProcessList.removeProcessLocked(r, false, false, "crash",
- ApplicationExitInfo.REASON_CRASH);
+ mService.mProcessList.removeProcessLocked(r, false, false,
+ ApplicationExitInfo.REASON_CRASH, "crash");
mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
}
} finally {
@@ -747,8 +747,8 @@ class AppErrors {
// Don't let services in this process be restarted and potentially
// annoy the user repeatedly. Unless it is persistent, since those
// processes run critical code.
- mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash",
- ApplicationExitInfo.REASON_CRASH);
+ mService.mProcessList.removeProcessLocked(app, false, tryAgain,
+ ApplicationExitInfo.REASON_CRASH, "crash");
mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
if (!showBackground) {
return false;
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index cba6b92bf440..a09aa64476c1 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -348,6 +348,7 @@ public final class AppExitInfoTracker {
} else {
// always override the existing info since we are now more informational.
info.setReason(raw.getReason());
+ info.setSubReason(raw.getSubReason());
info.setStatus(0);
info.setTimestamp(System.currentTimeMillis());
info.setDescription(raw.getDescription());
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index e7b467adf487..aa37b4accc40 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -840,7 +840,8 @@ public final class OomAdjuster {
// definition not re-use the same process again, and it is
// good to avoid having whatever code was running in them
// left sitting around after no longer needed.
- app.kill("isolated not needed", ApplicationExitInfo.REASON_OTHER, true);
+ app.kill("isolated not needed", ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
} else {
// Keeping this process, update its uid.
updateAppUidRecLocked(app);
@@ -2166,7 +2167,8 @@ public final class OomAdjuster {
}
if (app.waitingToKill != null && app.curReceivers.isEmpty()
&& app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
- app.kill(app.waitingToKill, ApplicationExitInfo.REASON_OTHER, true);
+ app.kill(app.waitingToKill, ApplicationExitInfo.REASON_USER_REQUESTED,
+ ApplicationExitInfo.SUBREASON_UNKNOWN, true);
success = false;
} else {
int processGroup;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 3a5447edfdf0..a9d18e05e350 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2378,7 +2378,7 @@ public final class ProcessList {
killProcessQuiet(pid);
Process.killProcessGroup(app.uid, app.pid);
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
- ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
+ ApplicationExitInfo.SUBREASON_INVALID_START, reason);
return false;
}
mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
@@ -2463,7 +2463,7 @@ public final class ProcessList {
killProcessQuiet(app.pid);
ProcessList.killProcessGroup(app.uid, app.pid);
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
- ApplicationExitInfo.SUBREASON_UNKNOWN, "hasn't been killed");
+ ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
} else {
app.pendingStart = false;
}
@@ -2481,10 +2481,11 @@ public final class ProcessList {
@GuardedBy("mService")
boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
- String reason) {
+ int reasonCode, int subReason, String reason) {
return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
- false /* evenPersistent */, false /* setRemoved */, reason);
+ false /* evenPersistent */, false /* setRemoved */, reasonCode,
+ subReason, reason);
}
@GuardedBy("mService")
@@ -2517,7 +2518,8 @@ public final class ProcessList {
@GuardedBy("mService")
final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
- boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
+ boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode,
+ int subReason, String reason) {
ArrayList<ProcessRecord> procs = new ArrayList<>();
// Remove all processes this package may have touched: all with the
@@ -2589,7 +2591,8 @@ public final class ProcessList {
int N = procs.size();
for (int i=0; i<N; i++) {
- removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
+ removeProcessLocked(procs.get(i), callerWillRestart, allowRestart,
+ reasonCode, subReason, reason);
}
killAppZygotesLocked(packageName, appId, userId, false /* force */);
mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
@@ -2598,13 +2601,14 @@ public final class ProcessList {
@GuardedBy("mService")
boolean removeProcessLocked(ProcessRecord app,
- boolean callerWillRestart, boolean allowRestart, String reason) {
- return removeProcessLocked(app, callerWillRestart, allowRestart, reason,
- ApplicationExitInfo.REASON_OTHER);
+ boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
+ return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
+ ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
}
- boolean removeProcessLocked(ProcessRecord app,
- boolean callerWillRestart, boolean allowRestart, String reason, int reasonCode) {
+ @GuardedBy("mService")
+ boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
+ boolean allowRestart, int reasonCode, int subReason, String reason) {
final String name = app.processName;
final int uid = app.uid;
if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
@@ -2640,7 +2644,7 @@ public final class ProcessList {
needRestart = true;
}
}
- app.kill(reason, reasonCode, true);
+ app.kill(reason, reasonCode, subReason, true);
mService.handleAppDiedLocked(app, willRestart, allowRestart);
if (willRestart) {
removeLruProcessLocked(app);
@@ -2838,7 +2842,8 @@ public final class ProcessList {
final int N = procs.size();
for (int i = 0; i < N; i++) {
- removeProcessLocked(procs.get(i), false, true, "kill all background except");
+ removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
}
}
@@ -4004,7 +4009,8 @@ public final class ProcessList {
return false;
}
- app.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
+ app.kill(reason, ApplicationExitInfo.REASON_OTHER,
+ ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
if (!app.isolated) {
mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 85f36aab0be7..45c3aebe8bd5 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -40,6 +40,8 @@ import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OpEventProxyInfo;
+import static android.app.AppOpsManager.SAMPLING_STRATEGY_RARELY_USED;
+import static android.app.AppOpsManager.SAMPLING_STRATEGY_UNIFORM;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
@@ -60,8 +62,6 @@ import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.content.Intent.EXTRA_REPLACING;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP;
-import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
-import static android.util.StatsLogInternal.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
import static com.android.server.appop.AppOpsService.ModeCallback.ALL_OPS;
@@ -5683,7 +5683,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (mRarelyUsedPackages.contains(packageName)) {
mRarelyUsedPackages.remove(packageName);
if (ThreadLocalRandom.current().nextFloat() < 0.5f) {
- mSamplingStrategy = RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
+ mSamplingStrategy = SAMPLING_STRATEGY_RARELY_USED;
resampleAppOpForPackageLocked(packageName);
}
}
@@ -5692,7 +5692,7 @@ public class AppOpsService extends IAppOpsService.Stub {
/** Resamples package and appop to watch from the list provided. */
private void resamplePackageAndAppOpLocked(@NonNull List<String> packageNames) {
if (!packageNames.isEmpty()) {
- mSamplingStrategy = RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
+ mSamplingStrategy = SAMPLING_STRATEGY_UNIFORM;
resampleAppOpForPackageLocked(packageNames.get(
ThreadLocalRandom.current().nextInt(packageNames.size())));
}
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
index 49a2901d4f9f..1292f6c121b4 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
@@ -203,15 +203,18 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
checkPreemptPermissions();
// Input validation (always valid).
- synchronized (this) {
- // State validation (always valid).
-
- // From here on, every exception isn't client's fault.
- try {
- mDelegate.setExternalCaptureState(active);
- } catch (Exception e) {
- throw handleException(e);
- }
+ // State validation (always valid).
+
+ // Normally, we would acquire a lock here. However, we do not access any state here so it
+ // is safe to not lock. This call is typically done from a different context than all the
+ // other calls and may result in a deadlock if we lock here (between the audio server and
+ // the system server).
+
+ // From here on, every exception isn't client's fault.
+ try {
+ mDelegate.setExternalCaptureState(active);
+ } catch (Exception e) {
+ throw handleException(e);
}
}
diff --git a/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java b/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
index cddcabe80f33..06c2354c7a7d 100644
--- a/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
+++ b/services/core/java/com/android/server/tv/TvRemoteProviderWatcher.java
@@ -30,6 +30,8 @@ import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.Collections;
@@ -140,7 +142,8 @@ final class TvRemoteProviderWatcher {
}
}
- private boolean verifyServiceTrusted(ServiceInfo serviceInfo) {
+ @VisibleForTesting
+ boolean verifyServiceTrusted(ServiceInfo serviceInfo) {
if (serviceInfo.permission == null || !serviceInfo.permission.equals(
Manifest.permission.BIND_TV_REMOTE_SERVICE)) {
// If the service does not require this permission then any app could
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 107b0a1c2da8..b019e9dd03ba 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -294,8 +294,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";
@@ -2178,10 +2176,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;
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java b/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java
new file mode 100644
index 000000000000..0a2bb620eb11
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/tv/TvRemoteProviderWatcherTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.tv;
+
+import static org.hamcrest.Matchers.not;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.when;
+import static org.mockito.hamcrest.MockitoHamcrest.argThat;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.os.Looper;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+public class TvRemoteProviderWatcherTest {
+ private static final String TV_REMOTE_SERVICE_PACKAGE_NAME =
+ "com.google.android.tv.remote.service";
+
+ @Mock
+ Context mMockContext;
+ @Mock
+ PackageManager mMockPackageManager;
+ @Mock
+ Resources mMockResources;
+
+ private TvRemoteProviderWatcher mTvRemoteProviderWatcher;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+
+ when(mMockResources.getString(com.android.internal.R.string.config_tvRemoteServicePackage))
+ .thenReturn(TV_REMOTE_SERVICE_PACKAGE_NAME);
+
+
+ when(mMockPackageManager.checkPermission(
+ argThat(not(Manifest.permission.TV_VIRTUAL_REMOTE_CONTROLLER)),
+ anyString())).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+
+ when(mMockPackageManager.checkPermission(
+ anyString(),
+ argThat(not(TV_REMOTE_SERVICE_PACKAGE_NAME)))).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+
+ when(mMockPackageManager.checkPermission(Manifest.permission.TV_VIRTUAL_REMOTE_CONTROLLER,
+ TV_REMOTE_SERVICE_PACKAGE_NAME)).thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ mTvRemoteProviderWatcher = new TvRemoteProviderWatcher(mMockContext, new Object());
+ }
+
+ @Test
+ public void tvServiceIsTrusted() {
+ assertTrue(mTvRemoteProviderWatcher.verifyServiceTrusted(createTvServiceInfo()));
+ }
+
+ @Test
+ public void permissionIsRequired() {
+ ServiceInfo serviceInfo = createTvServiceInfo();
+ serviceInfo.permission = null;
+
+ assertFalse(mTvRemoteProviderWatcher.verifyServiceTrusted(serviceInfo));
+ }
+
+ @Test
+ public void permissionMustBeBindRemote() {
+ ServiceInfo serviceInfo = createTvServiceInfo();
+ serviceInfo.permission = Manifest.permission.BIND_TV_INPUT;
+ assertFalse(mTvRemoteProviderWatcher.verifyServiceTrusted(serviceInfo));
+ }
+
+ @Test
+ public void packageNameMustMatch() {
+ ServiceInfo serviceInfo = createTvServiceInfo();
+ serviceInfo.packageName = "some.random.package";
+ assertFalse(mTvRemoteProviderWatcher.verifyServiceTrusted(serviceInfo));
+ }
+
+ @Test
+ public void packageManagerPermissionIsRequired() {
+ reset(mMockPackageManager);
+ when(mMockPackageManager.checkPermission(anyString(), anyString())).thenReturn(
+ PackageManager.PERMISSION_DENIED);
+
+ assertFalse(mTvRemoteProviderWatcher.verifyServiceTrusted(createTvServiceInfo()));
+ }
+
+ @Test
+ public void whitelistingPackageNameIsRequired() {
+ reset(mMockResources);
+ when(mMockResources.getString(anyInt())).thenReturn("");
+
+ // Create a new watcher, as the resources are read in the constructor of the class
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ TvRemoteProviderWatcher watcher =
+ new TvRemoteProviderWatcher(mMockContext, new Object());
+ assertFalse(watcher.verifyServiceTrusted(createTvServiceInfo()));
+ }
+
+ private ServiceInfo createTvServiceInfo() {
+ ServiceInfo serviceInfo = new ServiceInfo();
+
+ serviceInfo.name = "ATV Remote Service";
+ serviceInfo.packageName = TV_REMOTE_SERVICE_PACKAGE_NAME;
+ serviceInfo.permission = Manifest.permission.BIND_TV_REMOTE_SERVICE;
+
+ return serviceInfo;
+ }
+}
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 843e82023afe..cbf6fe88e565 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -26,11 +26,9 @@ cc_binary_host {
"java_writer_q.cpp",
"main.cpp",
"native_writer.cpp",
- "native_writer_q.cpp",
"utils.cpp",
],
cflags: [
- //"-DSTATS_SCHEMA_LEGACY",
"-Wall",
"-Werror",
],
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 8bccd7150050..aa356f1c35d2 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -237,6 +237,16 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl,
errorCount++;
continue;
}
+
+ if (field->is_repeated() &&
+ !(javaType == JAVA_TYPE_ATTRIBUTION_CHAIN || javaType == JAVA_TYPE_KEY_VALUE_PAIR)) {
+ print_error(field,
+ "Repeated fields are not supported in atoms. Please make field %s not "
+ "repeated.\n",
+ field->name().c_str());
+ errorCount++;
+ continue;
+ }
}
// Check that if there's an attribution chain, it's at position 1.
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
index c29936b96c14..209d511c8a05 100644
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ b/tools/stats_log_api_gen/java_writer.cpp
@@ -59,9 +59,6 @@ static int write_java_methods(
}
// Print method signature.
- if (DEFAULT_MODULE_NAME == moduleName) {
- fprintf(out, " /** @hide */\n");
- }
fprintf(out, " public static void write(int code");
vector<java_type_t> signature = signature_to_modules_it->first;
int argIndex = 1;
@@ -273,9 +270,6 @@ int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attribut
fprintf(out, "\n");
fprintf(out, "/**\n");
fprintf(out, " * Utility class for logging statistics events.\n");
- if (DEFAULT_MODULE_NAME == moduleName) {
- fprintf(out, " * @hide\n");
- }
fprintf(out, " */\n");
fprintf(out, "public class %s {\n", javaClass.c_str());
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index 12c050d8ef8d..8f2112a03e46 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -609,69 +609,5 @@ int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
return errors;
}
-#if defined(STATS_SCHEMA_LEGACY)
-static void write_java_method(
- FILE* out,
- const string& method_name,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules,
- const AtomDecl &attributionDecl) {
-
- for (auto signature_to_modules_it = signatures_to_modules.begin();
- signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
- vector<java_type_t> signature = signature_to_modules_it->first;
- fprintf(out, " /** @hide */\n");
- fprintf(out, " public static native int %s(int code", method_name.c_str());
- int argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s[] %s",
- java_type_name(chainField.javaType), chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", android.util.SparseArray<Object> valueMap");
- } else {
- fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, "\n");
- }
-}
-
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
- const bool supportWorkSource) {
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
- fprintf(out, "package android.util;\n");
- fprintf(out, "\n");
- fprintf(out, "\n");
- fprintf(out, "/**\n");
- fprintf(out, " * API For logging statistics events.\n");
- fprintf(out, " * @hide\n");
- fprintf(out, " */\n");
- fprintf(out, "public class StatsLogInternal {\n");
- write_java_atom_codes(out, atoms, DEFAULT_MODULE_NAME);
-
- write_java_enum_values(out, atoms, DEFAULT_MODULE_NAME);
-
- // Print write methods
- fprintf(out, " // Write methods\n");
- write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
- write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
- attributionDecl);
- if (supportWorkSource) {
- write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
- }
-
- fprintf(out, "}\n");
-
- return 0;
-}
-#endif
-
} // namespace stats_log_api_gen
} // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index 7d734df1e118..6ccb225ce973 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -49,9 +49,5 @@ int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass,
const string& javaPackage, const bool supportWorkSource);
-#if defined(STATS_SCHEMA_LEGACY)
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
- const bool supportWorkSource);
-#endif
} // namespace stats_log_api_gen
} // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index ddbf22c7f12a..120c2a2caada 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -1,10 +1,7 @@
-
#include "Collation.h"
#include "atoms_info_writer.h"
-#if !defined(STATS_SCHEMA_LEGACY)
#include "java_writer.h"
-#endif
#include "java_writer_q.h"
#include "native_writer.h"
#include "utils.h"
@@ -28,463 +25,6 @@ namespace stats_log_api_gen {
using android::os::statsd::Atom;
-// Hide the JNI write helpers that are not used in the new schema.
-// TODO(b/145100015): Remove this and other JNI related functionality once StatsEvent migration is
-// complete.
-#if defined(STATS_SCHEMA_LEGACY)
-// JNI helpers.
-static const char*
-jni_type_name(java_type_t type)
-{
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "jboolean";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "jint";
- case JAVA_TYPE_LONG:
- return "jlong";
- case JAVA_TYPE_FLOAT:
- return "jfloat";
- case JAVA_TYPE_DOUBLE:
- return "jdouble";
- case JAVA_TYPE_STRING:
- return "jstring";
- case JAVA_TYPE_BYTE_ARRAY:
- return "jbyteArray";
- default:
- return "UNKNOWN";
- }
-}
-
-static const char*
-jni_array_type_name(java_type_t type)
-{
- switch (type) {
- case JAVA_TYPE_INT:
- return "jintArray";
- case JAVA_TYPE_FLOAT:
- return "jfloatArray";
- case JAVA_TYPE_STRING:
- return "jobjectArray";
- default:
- return "UNKNOWN";
- }
-}
-
-static string
-jni_function_name(const string& method_name, const vector<java_type_t>& signature)
-{
- string result("StatsLog_" + method_name);
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- switch (*arg) {
- case JAVA_TYPE_BOOLEAN:
- result += "_boolean";
- break;
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- result += "_int";
- break;
- case JAVA_TYPE_LONG:
- result += "_long";
- break;
- case JAVA_TYPE_FLOAT:
- result += "_float";
- break;
- case JAVA_TYPE_DOUBLE:
- result += "_double";
- break;
- case JAVA_TYPE_STRING:
- result += "_String";
- break;
- case JAVA_TYPE_ATTRIBUTION_CHAIN:
- result += "_AttributionChain";
- break;
- case JAVA_TYPE_KEY_VALUE_PAIR:
- result += "_KeyValuePairs";
- break;
- case JAVA_TYPE_BYTE_ARRAY:
- result += "_bytes";
- break;
- default:
- result += "_UNKNOWN";
- break;
- }
- }
- return result;
-}
-
-static const char*
-java_type_signature(java_type_t type)
-{
- switch (type) {
- case JAVA_TYPE_BOOLEAN:
- return "Z";
- case JAVA_TYPE_INT:
- case JAVA_TYPE_ENUM:
- return "I";
- case JAVA_TYPE_LONG:
- return "J";
- case JAVA_TYPE_FLOAT:
- return "F";
- case JAVA_TYPE_DOUBLE:
- return "D";
- case JAVA_TYPE_STRING:
- return "Ljava/lang/String;";
- case JAVA_TYPE_BYTE_ARRAY:
- return "[B";
- default:
- return "UNKNOWN";
- }
-}
-
-static string
-jni_function_signature(const vector<java_type_t>& signature, const AtomDecl &attributionDecl)
-{
- string result("(I");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- result += "[";
- result += java_type_signature(chainField.javaType);
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- result += "Landroid/util/SparseArray;";
- } else {
- result += java_type_signature(*arg);
- }
- }
- result += ")I";
- return result;
-}
-
-static void write_key_value_map_jni(FILE* out) {
- fprintf(out, " std::map<int, int32_t> int32_t_map;\n");
- fprintf(out, " std::map<int, int64_t> int64_t_map;\n");
- fprintf(out, " std::map<int, float> float_map;\n");
- fprintf(out, " std::map<int, char const*> string_map;\n\n");
-
- fprintf(out, " jclass jmap_class = env->FindClass(\"android/util/SparseArray\");\n");
-
- fprintf(out, " jmethodID jget_size_method = env->GetMethodID(jmap_class, \"size\", \"()I\");\n");
- fprintf(out, " jmethodID jget_key_method = env->GetMethodID(jmap_class, \"keyAt\", \"(I)I\");\n");
- fprintf(out, " jmethodID jget_value_method = env->GetMethodID(jmap_class, \"valueAt\", \"(I)Ljava/lang/Object;\");\n\n");
-
-
- fprintf(out, " std::vector<std::unique_ptr<ScopedUtfChars>> scoped_ufs;\n\n");
-
- fprintf(out, " jclass jint_class = env->FindClass(\"java/lang/Integer\");\n");
- fprintf(out, " jclass jlong_class = env->FindClass(\"java/lang/Long\");\n");
- fprintf(out, " jclass jfloat_class = env->FindClass(\"java/lang/Float\");\n");
- fprintf(out, " jclass jstring_class = env->FindClass(\"java/lang/String\");\n");
- fprintf(out, " jmethodID jget_int_method = env->GetMethodID(jint_class, \"intValue\", \"()I\");\n");
- fprintf(out, " jmethodID jget_long_method = env->GetMethodID(jlong_class, \"longValue\", \"()J\");\n");
- fprintf(out, " jmethodID jget_float_method = env->GetMethodID(jfloat_class, \"floatValue\", \"()F\");\n\n");
-
- fprintf(out, " jint jsize = env->CallIntMethod(value_map, jget_size_method);\n");
- fprintf(out, " for(int i = 0; i < jsize; i++) {\n");
- fprintf(out, " jint key = env->CallIntMethod(value_map, jget_key_method, i);\n");
- fprintf(out, " jobject jvalue_obj = env->CallObjectMethod(value_map, jget_value_method, i);\n");
- fprintf(out, " if (jvalue_obj == NULL) { continue; }\n");
- fprintf(out, " if (env->IsInstanceOf(jvalue_obj, jint_class)) {\n");
- fprintf(out, " int32_t_map[key] = env->CallIntMethod(jvalue_obj, jget_int_method);\n");
- fprintf(out, " } else if (env->IsInstanceOf(jvalue_obj, jlong_class)) {\n");
- fprintf(out, " int64_t_map[key] = env->CallLongMethod(jvalue_obj, jget_long_method);\n");
- fprintf(out, " } else if (env->IsInstanceOf(jvalue_obj, jfloat_class)) {\n");
- fprintf(out, " float_map[key] = env->CallFloatMethod(jvalue_obj, jget_float_method);\n");
- fprintf(out, " } else if (env->IsInstanceOf(jvalue_obj, jstring_class)) {\n");
- fprintf(out, " std::unique_ptr<ScopedUtfChars> utf(new ScopedUtfChars(env, (jstring)jvalue_obj));\n");
- fprintf(out, " if (utf->c_str() != NULL) { string_map[key] = utf->c_str(); }\n");
- fprintf(out, " scoped_ufs.push_back(std::move(utf));\n");
- fprintf(out, " }\n");
- fprintf(out, " }\n");
-}
-
-static int
-write_stats_log_jni_method(FILE* out, const string& java_method_name, const string& cpp_method_name,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules,
- const AtomDecl &attributionDecl) {
- // Print write methods
- for (auto signature_to_modules_it = signatures_to_modules.begin();
- signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
- vector<java_type_t> signature = signature_to_modules_it->first;
- int argIndex;
-
- fprintf(out, "static int\n");
- fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code",
- jni_function_name(java_method_name, signature).c_str());
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, ", %s %s", jni_array_type_name(chainField.javaType),
- chainField.name.c_str());
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", jobject value_map");
- } else {
- fprintf(out, ", %s arg%d", jni_type_name(*arg), argIndex);
- }
- argIndex++;
- }
- fprintf(out, ")\n");
-
- fprintf(out, "{\n");
-
- // Prepare strings
- argIndex = 1;
- bool hadStringOrChain = false;
- bool isKeyValuePairAtom = false;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_STRING) {
- hadStringOrChain = true;
- fprintf(out, " const char* str%d;\n", argIndex);
- fprintf(out, " if (arg%d != NULL) {\n", argIndex);
- fprintf(out, " str%d = env->GetStringUTFChars(arg%d, NULL);\n",
- argIndex, argIndex);
- fprintf(out, " } else {\n");
- fprintf(out, " str%d = NULL;\n", argIndex);
- fprintf(out, " }\n");
- } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- hadStringOrChain = true;
- fprintf(out, " jbyte* jbyte_array%d;\n", argIndex);
- fprintf(out, " const char* str%d;\n", argIndex);
- fprintf(out, " int str%d_length = 0;\n", argIndex);
- fprintf(out,
- " if (arg%d != NULL && env->GetArrayLength(arg%d) > "
- "0) {\n",
- argIndex, argIndex);
- fprintf(out,
- " jbyte_array%d = "
- "env->GetByteArrayElements(arg%d, NULL);\n",
- argIndex, argIndex);
- fprintf(out,
- " str%d_length = env->GetArrayLength(arg%d);\n",
- argIndex, argIndex);
- fprintf(out,
- " str%d = "
- "reinterpret_cast<char*>(env->GetByteArrayElements(arg%"
- "d, NULL));\n",
- argIndex, argIndex);
- fprintf(out, " } else {\n");
- fprintf(out, " jbyte_array%d = NULL;\n", argIndex);
- fprintf(out, " str%d = NULL;\n", argIndex);
- fprintf(out, " }\n");
-
- fprintf(out,
- " android::util::BytesField bytesField%d(str%d, "
- "str%d_length);",
- argIndex, argIndex, argIndex);
-
- } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- hadStringOrChain = true;
- for (auto chainField : attributionDecl.fields) {
- fprintf(out, " size_t %s_length = env->GetArrayLength(%s);\n",
- chainField.name.c_str(), chainField.name.c_str());
- if (chainField.name != attributionDecl.fields.front().name) {
- fprintf(out, " if (%s_length != %s_length) {\n",
- chainField.name.c_str(),
- attributionDecl.fields.front().name.c_str());
- fprintf(out, " return -EINVAL;\n");
- fprintf(out, " }\n");
- }
- if (chainField.javaType == JAVA_TYPE_INT) {
- fprintf(out, " jint* %s_array = env->GetIntArrayElements(%s, NULL);\n",
- chainField.name.c_str(), chainField.name.c_str());
- } else if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " std::vector<%s> %s_vec;\n",
- cpp_type_name(chainField.javaType), chainField.name.c_str());
- fprintf(out, " std::vector<ScopedUtfChars*> scoped_%s_vec;\n",
- chainField.name.c_str());
- fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n",
- chainField.name.c_str());
- fprintf(out, " jstring jstr = "
- "(jstring)env->GetObjectArrayElement(%s, i);\n",
- chainField.name.c_str());
- fprintf(out, " if (jstr == NULL) {\n");
- fprintf(out, " %s_vec.push_back(NULL);\n",
- chainField.name.c_str());
- fprintf(out, " } else {\n");
- fprintf(out, " ScopedUtfChars* scoped_%s = "
- "new ScopedUtfChars(env, jstr);\n",
- chainField.name.c_str());
- fprintf(out, " %s_vec.push_back(scoped_%s->c_str());\n",
- chainField.name.c_str(), chainField.name.c_str());
- fprintf(out, " scoped_%s_vec.push_back(scoped_%s);\n",
- chainField.name.c_str(), chainField.name.c_str());
- fprintf(out, " }\n");
- fprintf(out, " }\n");
- }
- fprintf(out, "\n");
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- isKeyValuePairAtom = true;
- }
- argIndex++;
- }
- // Emit this to quiet the unused parameter warning if there were no strings or attribution
- // chains.
- if (!hadStringOrChain && !isKeyValuePairAtom) {
- fprintf(out, " (void)env;\n");
- }
- if (isKeyValuePairAtom) {
- write_key_value_map_jni(out);
- }
-
- // stats_write call
- argIndex = 1;
- fprintf(out, "\n int ret = android::util::%s(code",
- cpp_method_name.c_str());
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_INT) {
- fprintf(out, ", (const %s*)%s_array, %s_length",
- cpp_type_name(chainField.javaType),
- chainField.name.c_str(), chainField.name.c_str());
- } else if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, ", %s_vec", chainField.name.c_str());
- }
- }
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, ", int32_t_map, int64_t_map, string_map, float_map");
- } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out, ", bytesField%d", argIndex);
- } else {
- const char* argName =
- (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
- fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);
- }
- argIndex++;
- }
- fprintf(out, ");\n");
- fprintf(out, "\n");
-
- // Clean up strings
- argIndex = 1;
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_STRING) {
- fprintf(out, " if (str%d != NULL) {\n", argIndex);
- fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n",
- argIndex, argIndex);
- fprintf(out, " }\n");
- } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out, " if (str%d != NULL) { \n", argIndex);
- fprintf(out,
- " env->ReleaseByteArrayElements(arg%d, "
- "jbyte_array%d, 0);\n",
- argIndex, argIndex);
- fprintf(out, " }\n");
- } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (auto chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_INT) {
- fprintf(out, " env->ReleaseIntArrayElements(%s, %s_array, 0);\n",
- chainField.name.c_str(), chainField.name.c_str());
- } else if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " for (size_t i = 0; i < scoped_%s_vec.size(); ++i) {\n",
- chainField.name.c_str());
- fprintf(out, " delete scoped_%s_vec[i];\n", chainField.name.c_str());
- fprintf(out, " }\n");
- }
- }
- }
- argIndex++;
- }
-
- fprintf(out, " return ret;\n");
-
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-
-
- return 0;
-}
-
-void write_jni_registration(FILE* out, const string& java_method_name,
- const map<vector<java_type_t>, set<string>>& signatures_to_modules,
- const AtomDecl &attributionDecl) {
- for (auto signature_to_modules_it = signatures_to_modules.begin();
- signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) {
- vector<java_type_t> signature = signature_to_modules_it->first;
- fprintf(out, " { \"%s\", \"%s\", (void*)%s },\n",
- java_method_name.c_str(),
- jni_function_signature(signature, attributionDecl).c_str(),
- jni_function_name(java_method_name, signature).c_str());
- }
-}
-#endif // JNI helpers.
-
-static int
-#if defined(STATS_SCHEMA_LEGACY)
-write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl)
-#else
-// Write empty JNI file that doesn't contain any JNI methods.
-// TODO(b/145100015): remove this function and all JNI autogen code once StatsEvent migration is
-// complete.
-write_stats_log_jni(FILE* out)
-#endif
-{
- // Print prelude
- fprintf(out, "// This file is autogenerated\n");
- fprintf(out, "\n");
-
-#if defined(STATS_SCHEMA_LEGACY)
- fprintf(out, "#include <statslog.h>\n");
- fprintf(out, "\n");
- fprintf(out, "#include <nativehelper/JNIHelp.h>\n");
- fprintf(out, "#include <nativehelper/ScopedUtfChars.h>\n");
- fprintf(out, "#include <utils/Vector.h>\n");
-#endif
- fprintf(out, "#include \"core_jni_helpers.h\"\n");
- fprintf(out, "#include \"jni.h\"\n");
- fprintf(out, "\n");
-#if defined(STATS_SCHEMA_LEGACY)
- fprintf(out, "#define UNUSED __attribute__((__unused__))\n");
- fprintf(out, "\n");
-#endif
-
- fprintf(out, "namespace android {\n");
- fprintf(out, "\n");
-
-#if defined(STATS_SCHEMA_LEGACY)
- write_stats_log_jni_method(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl);
- write_stats_log_jni_method(out, "write_non_chained", "stats_write_non_chained",
- atoms.non_chained_signatures_to_modules, attributionDecl);
-#endif
-
- // Print registration function table
- fprintf(out, "/*\n");
- fprintf(out, " * JNI registration.\n");
- fprintf(out, " */\n");
- fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n");
-#if defined(STATS_SCHEMA_LEGACY)
- write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl);
- write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
- attributionDecl);
-#endif
- fprintf(out, "};\n");
- fprintf(out, "\n");
-
- // Print registration function
- fprintf(out, "int register_android_util_StatsLogInternal(JNIEnv* env) {\n");
- fprintf(out, " return RegisterMethodsOrDie(\n");
- fprintf(out, " env,\n");
- fprintf(out, " \"android/util/StatsLogInternal\",\n");
- fprintf(out, " gRegisterMethods, NELEM(gRegisterMethods));\n");
- fprintf(out, "}\n");
-
- fprintf(out, "\n");
- fprintf(out, "} // namespace android\n");
- return 0;
-}
-
static void
print_usage()
{
@@ -498,7 +38,6 @@ print_usage()
fprintf(stderr, " --atomsInfoHeader FILENAME the cpp file to output for statsd metadata\n");
fprintf(stderr, " --help this message\n");
fprintf(stderr, " --java FILENAME the java file to output\n");
- fprintf(stderr, " --jni FILENAME the jni file to output\n");
fprintf(stderr, " --module NAME optional, module name to generate outputs for\n");
fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n");
fprintf(stderr, " comma separated namespace of the files\n");
@@ -526,16 +65,15 @@ run(int argc, char const*const* argv)
string cppFilename;
string headerFilename;
string javaFilename;
- string jniFilename;
string atomsInfoCppFilename;
string atomsInfoHeaderFilename;
+ string javaPackage;
+ string javaClass;
string moduleName = DEFAULT_MODULE_NAME;
string cppNamespace = DEFAULT_CPP_NAMESPACE;
string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT;
string atomsInfoCppHeaderImport = DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT;
- string javaPackage = DEFAULT_JAVA_PACKAGE;
- string javaClass = DEFAULT_JAVA_CLASS;
bool supportQ = false;
bool supportWorkSource = false;
bool compileQ = false;
@@ -566,13 +104,6 @@ run(int argc, char const*const* argv)
return 1;
}
javaFilename = argv[index];
- } else if (0 == strcmp("--jni", argv[index])) {
- index++;
- if (index >= argc) {
- print_usage();
- return 1;
- }
- jniFilename = argv[index];
} else if (0 == strcmp("--module", argv[index])) {
index++;
if (index >= argc) {
@@ -643,7 +174,6 @@ run(int argc, char const*const* argv)
if (cppFilename.size() == 0
&& headerFilename.size() == 0
&& javaFilename.size() == 0
- && jniFilename.size() == 0
&& atomsInfoHeaderFilename.size() == 0
&& atomsInfoCppFilename.size() == 0) {
print_usage();
@@ -738,27 +268,27 @@ run(int argc, char const*const* argv)
// Write the .java file
if (javaFilename.size() != 0) {
- FILE* out = fopen(javaFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
+ if (javaClass.size() == 0) {
+ fprintf(stderr, "Must supply --javaClass if supplying a Java filename");
return 1;
}
-#if defined(STATS_SCHEMA_LEGACY)
- if (moduleName == DEFAULT_MODULE_NAME) {
- errorCount = android::stats_log_api_gen::write_stats_log_java_q(
- out, atoms, attributionDecl, supportWorkSource);
- } else {
- errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
- out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
- supportWorkSource);
+ if (javaPackage.size() == 0) {
+ fprintf(stderr, "Must supply --javaPackage if supplying a Java filename");
+ return 1;
+ }
+ if (moduleName.size() == 0) {
+ fprintf(stderr, "Must supply --module if supplying a Java filename");
+ return 1;
}
-#else
- if (moduleName == DEFAULT_MODULE_NAME) {
- javaClass = "StatsLogInternal";
- javaPackage = "android.util";
+
+ FILE* out = fopen(javaFilename.c_str(), "w");
+ if (out == NULL) {
+ fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
+ return 1;
}
+
if (compileQ) {
errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
@@ -768,25 +298,6 @@ run(int argc, char const*const* argv)
out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ,
supportWorkSource);
}
-#endif
-
- fclose(out);
- }
-
- // Write the jni file
- if (jniFilename.size() != 0) {
- FILE* out = fopen(jniFilename.c_str(), "w");
- if (out == NULL) {
- fprintf(stderr, "Unable to open file for write: %s\n", jniFilename.c_str());
- return 1;
- }
-
-#if defined(STATS_SCHEMA_LEGACY)
- errorCount = android::stats_log_api_gen::write_stats_log_jni(
- out, atoms, attributionDecl);
-#else
- errorCount = android::stats_log_api_gen::write_stats_log_jni(out);
-#endif
fclose(out);
}
diff --git a/tools/stats_log_api_gen/native_writer.cpp b/tools/stats_log_api_gen/native_writer.cpp
index 285514df5ff3..da207d665e20 100644
--- a/tools/stats_log_api_gen/native_writer.cpp
+++ b/tools/stats_log_api_gen/native_writer.cpp
@@ -15,14 +15,11 @@
*/
#include "native_writer.h"
-#include "native_writer_q.h"
#include "utils.h"
namespace android {
namespace stats_log_api_gen {
-#if !defined(STATS_SCHEMA_LEGACY)
-
static int write_native_stats_write_methods(FILE* out, const Atoms& atoms,
const AtomDecl& attributionDecl, const string& moduleName, const bool supportQ) {
fprintf(out, "\n");
@@ -175,7 +172,6 @@ static void write_native_stats_write_non_chained_methods(FILE* out, const Atoms&
}
}
-#endif
static void write_native_method_header(
FILE* out,
@@ -191,12 +187,10 @@ static void write_native_method_header(
}
vector<java_type_t> signature = signature_to_modules_it->first;
-#if !defined(STATS_SCHEMA_LEGACY)
// Key value pairs not supported in native.
if (find(signature.begin(), signature.end(), JAVA_TYPE_KEY_VALUE_PAIR) != signature.end()) {
continue;
}
-#endif
write_native_method_signature(out, methodName, signature, attributionDecl, ";");
}
}
@@ -209,33 +203,17 @@ int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributi
fprintf(out, "\n");
fprintf(out, "#include <%s>\n", importHeader.c_str());
-#if defined(STATS_SCHEMA_LEGACY)
- (void)supportQ; // Workaround for unused parameter error.
- write_native_cpp_includes_q(out);
-#else
if (supportQ) {
fprintf(out, "#include <StatsEventCompat.h>\n");
} else {
fprintf(out, "#include <stats_event.h>\n");
}
-#endif
fprintf(out, "\n");
write_namespace(out, cppNamespace);
-#if defined(STATS_SCHEMA_LEGACY)
- write_native_stats_log_cpp_globals_q(out);
- write_native_get_timestamp_ns_q(out);
- write_native_try_stats_write_methods_q(out, atoms, attributionDecl, moduleName);
- write_native_stats_write_methods_q(out, "int stats_write", atoms, attributionDecl, moduleName,
- "try_stats_write");
- write_native_try_stats_write_non_chained_methods_q(out, atoms, attributionDecl, moduleName);
- write_native_stats_write_non_chained_methods_q(out, "int stats_write_non_chained", atoms,
- attributionDecl, moduleName, "try_stats_write_non_chained");
-#else
write_native_stats_write_methods(out, atoms, attributionDecl, moduleName, supportQ);
write_native_stats_write_non_chained_methods(out, atoms, attributionDecl, moduleName);
-#endif
// Print footer
fprintf(out, "\n");
diff --git a/tools/stats_log_api_gen/native_writer_q.cpp b/tools/stats_log_api_gen/native_writer_q.cpp
deleted file mode 100644
index 299873dad975..000000000000
--- a/tools/stats_log_api_gen/native_writer_q.cpp
+++ /dev/null
@@ -1,276 +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.
- */
-
-#include "native_writer_q.h"
-#include "utils.h"
-
-namespace android {
-namespace stats_log_api_gen {
-
-static void write_native_stats_write_body_q(FILE* out, const vector<java_type_t>& signature,
- const AtomDecl& attributionDecl, const string& indent, const string& tryMethodName) {
- fprintf(out, "%sint ret = 0;\n", indent.c_str());
-
- fprintf(out, "%sfor(int retry = 0; retry < 2; ++retry) {\n", indent.c_str());
- fprintf(out, "%s ret = ", indent.c_str());
- write_native_method_call(out, tryMethodName, signature, attributionDecl);
- fprintf(out, "%s if (ret >= 0) { break; }\n", indent.c_str());
-
- fprintf(out, "%s {\n", indent.c_str());
- fprintf(out, "%s std::lock_guard<std::mutex> lock(mLogdRetryMutex);\n", indent.c_str());
- fprintf(out, "%s if ((get_elapsed_realtime_ns() - lastRetryTimestampNs) <= "
- "kMinRetryIntervalNs) break;\n", indent.c_str());
- fprintf(out, "%s lastRetryTimestampNs = get_elapsed_realtime_ns();\n",
- indent.c_str());
- fprintf(out, "%s }\n", indent.c_str());
- fprintf(out, "%s std::this_thread::sleep_for(std::chrono::milliseconds(10));\n",
- indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "%sif (ret < 0) {\n", indent.c_str());
- fprintf(out, "%s note_log_drop(ret, code);\n", indent.c_str());
- fprintf(out, "%s}\n", indent.c_str());
- fprintf(out, "%sreturn ret;\n", indent.c_str());
-}
-
-void write_native_cpp_includes_q(FILE* out) {
- fprintf(out, "#include <mutex>\n");
- fprintf(out, "#include <chrono>\n");
- fprintf(out, "#include <thread>\n");
- fprintf(out, "#ifdef __ANDROID__\n");
- fprintf(out, "#include <cutils/properties.h>\n");
- fprintf(out, "#endif\n");
- fprintf(out, "#include <stats_event_list.h>\n");
- fprintf(out, "#include <log/log.h>\n");
- fprintf(out, "#include <time.h>\n");
-}
-
-void write_native_get_timestamp_ns_q(FILE* out) {
- fprintf(out, "\n");
- fprintf(out, "static int64_t get_elapsed_realtime_ns() {\n");
- fprintf(out, " struct timespec t;\n");
- fprintf(out, " t.tv_sec = t.tv_nsec = 0;\n");
- fprintf(out, " clock_gettime(CLOCK_BOOTTIME, &t);\n");
- fprintf(out, " return (int64_t)t.tv_sec * 1000000000LL + t.tv_nsec;\n");
- fprintf(out, "}\n");
-}
-
-void write_native_stats_log_cpp_globals_q(FILE* out) {
- fprintf(out, "// the single event tag id for all stats logs\n");
- fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
- fprintf(out, "#ifdef __ANDROID__\n");
- fprintf(out,
- "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
- fprintf(out, "#else\n");
- fprintf(out, "const static bool kStatsdEnabled = false;\n");
- fprintf(out, "#endif\n");
-
- fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
- fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
- fprintf(out, "static std::mutex mLogdRetryMutex;\n");
-}
-
-void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName) {
- fprintf(out, "\n");
- for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
- signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) {
- if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_to_modules_it->first;
-
- write_native_method_signature(out, "static int try_stats_write", signature,
- attributionDecl, " {");
-
- int argIndex = 1;
- fprintf(out, " if (kStatsdEnabled) {\n");
- fprintf(out, " stats_event_list event(kStatsEventTag);\n");
- fprintf(out, " event << get_elapsed_realtime_ns();\n\n");
- fprintf(out, " event << code;\n\n");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
- for (const auto &chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " if (%s_length != %s.size()) {\n",
- attributionDecl.fields.front().name.c_str(), chainField.name.c_str());
- fprintf(out, " return -EINVAL;\n");
- fprintf(out, " }\n");
- }
- }
- fprintf(out, "\n event.begin();\n");
- fprintf(out, " for (size_t i = 0; i < %s_length; ++i) {\n",
- attributionDecl.fields.front().name.c_str());
- fprintf(out, " event.begin();\n");
- for (const auto &chainField : attributionDecl.fields) {
- if (chainField.javaType == JAVA_TYPE_STRING) {
- fprintf(out, " if (%s[i] != NULL) {\n", chainField.name.c_str());
- fprintf(out, " event << %s[i];\n", chainField.name.c_str());
- fprintf(out, " } else {\n");
- fprintf(out, " event << \"\";\n");
- fprintf(out, " }\n");
- } else {
- fprintf(out, " event << %s[i];\n", chainField.name.c_str());
- }
- }
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
- fprintf(out, " event.end();\n\n");
- } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
- fprintf(out, " event.begin();\n\n");
- fprintf(out, " for (const auto& it : arg%d_1) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_2) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_3) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " for (const auto& it : arg%d_4) {\n", argIndex);
- fprintf(out, " event.begin();\n");
- fprintf(out, " event << it.first;\n");
- fprintf(out, " event << it.second;\n");
- fprintf(out, " event.end();\n");
- fprintf(out, " }\n");
-
- fprintf(out, " event.end();\n\n");
- } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out,
- " event.AppendCharArray(arg%d.arg, "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- } else {
- if (*arg == JAVA_TYPE_STRING) {
- fprintf(out, " if (arg%d == NULL) {\n", argIndex);
- fprintf(out, " arg%d = \"\";\n", argIndex);
- fprintf(out, " }\n");
- }
- fprintf(out, " event << arg%d;\n", argIndex);
- }
- argIndex++;
- }
-
- fprintf(out, " return event.write(LOG_ID_STATS);\n");
- fprintf(out, " } else {\n");
- fprintf(out, " return 1;\n");
- fprintf(out, " }\n");
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-
-}
-
-void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName) {
- for (auto signature_to_modules_it = atoms.signatures_to_modules.begin();
- signature_to_modules_it != atoms.signatures_to_modules.end();
- signature_to_modules_it++) {
- if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_to_modules_it->first;
-
- write_native_method_signature(out, methodName, signature, attributionDecl, " {");
-
- write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName);
- fprintf(out, "}\n\n");
- }
-}
-
-void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName,
- const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName,
- const string& tryMethodName) {
- for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
- signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
- if (!signature_needed_for_module(signature_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_it->first;
-
- write_native_method_signature(out, methodName, signature, attributionDecl, " {");
-
- write_native_stats_write_body_q(out, signature, attributionDecl, " ", tryMethodName);
- fprintf(out, "}\n\n");
- }
-}
-
-void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName) {
- for (auto signature_it = atoms.non_chained_signatures_to_modules.begin();
- signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) {
- if (!signature_needed_for_module(signature_it->second, moduleName)) {
- continue;
- }
- vector<java_type_t> signature = signature_it->first;
-
- write_native_method_signature(out, "static int try_stats_write_non_chained", signature,
- attributionDecl, " {");
-
- int argIndex = 1;
- fprintf(out, " if (kStatsdEnabled) {\n");
- fprintf(out, " stats_event_list event(kStatsEventTag);\n");
- fprintf(out, " event << get_elapsed_realtime_ns();\n\n");
- fprintf(out, " event << code;\n\n");
- for (vector<java_type_t>::const_iterator arg = signature.begin();
- arg != signature.end(); arg++) {
- if (argIndex == 1) {
- fprintf(out, " event.begin();\n\n");
- fprintf(out, " event.begin();\n");
- }
- if (*arg == JAVA_TYPE_STRING) {
- fprintf(out, " if (arg%d == NULL) {\n", argIndex);
- fprintf(out, " arg%d = \"\";\n", argIndex);
- fprintf(out, " }\n");
- }
- if (*arg == JAVA_TYPE_BYTE_ARRAY) {
- fprintf(out,
- " event.AppendCharArray(arg%d.arg, "
- "arg%d.arg_length);\n",
- argIndex, argIndex);
- } else {
- fprintf(out, " event << arg%d;\n", argIndex);
- }
- if (argIndex == 2) {
- fprintf(out, " event.end();\n\n");
- fprintf(out, " event.end();\n\n");
- }
- argIndex++;
- }
-
- fprintf(out, " return event.write(LOG_ID_STATS);\n");
- fprintf(out, " } else {\n");
- fprintf(out, " return 1;\n");
- fprintf(out, " }\n");
- fprintf(out, "}\n");
- fprintf(out, "\n");
- }
-}
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/native_writer_q.h b/tools/stats_log_api_gen/native_writer_q.h
deleted file mode 100644
index a2ab1ae5d5e2..000000000000
--- a/tools/stats_log_api_gen/native_writer_q.h
+++ /dev/null
@@ -1,49 +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.
- */
-
-#pragma once
-
-#include "Collation.h"
-
-#include <stdio.h>
-#include <string.h>
-
-namespace android {
-namespace stats_log_api_gen {
-
-using namespace std;
-
-void write_native_cpp_includes_q(FILE* out);
-
-void write_native_stats_log_cpp_globals_q(FILE* out);
-
-void write_native_try_stats_write_methods_q(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName);
-
-void write_native_stats_write_methods_q(FILE* out, const string& methodName, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName, const string& tryMethodName);
-
-void write_native_try_stats_write_non_chained_methods_q(FILE* out, const Atoms& atoms,
- const AtomDecl& attributionDecl, const string& moduleName);
-
-void write_native_stats_write_non_chained_methods_q(FILE* out, const string& methodName,
- const Atoms& atoms, const AtomDecl& attributionDecl, const string& moduleName,
- const string& tryMethodName);
-
-void write_native_get_timestamp_ns_q(FILE* out);
-
-} // namespace stats_log_api_gen
-} // namespace android
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index b892194410ae..eab622d77ef7 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -41,21 +41,20 @@ enum AnEnum {
message AllTypesAtom {
repeated android.os.statsd.AttributionNode attribution_chain = 1;
- optional double double_field = 2;
- optional float float_field = 3;
- optional int64 int64_field = 4;
- optional uint64 uint64_field = 5;
- optional int32 int32_field = 6;
- optional fixed64 fixed64_field = 7;
- optional fixed32 fixed32_field = 8;
- optional bool bool_field = 9;
- optional string string_field = 10;
- optional uint32 uint32_field = 11;
- optional AnEnum enum_field = 12;
- optional sfixed32 sfixed32_field = 13;
- optional sfixed64 sfixed64_field = 14;
- optional sint32 sint32_field = 15;
- optional sint64 sint64_field = 16;
+ optional float float_field = 2;
+ optional int64 int64_field = 3;
+ optional uint64 uint64_field = 4;
+ optional int32 int32_field = 5;
+ optional fixed64 fixed64_field = 6;
+ optional fixed32 fixed32_field = 7;
+ optional bool bool_field = 8;
+ optional string string_field = 9;
+ optional uint32 uint32_field = 10;
+ optional AnEnum enum_field = 11;
+ optional sfixed32 sfixed32_field = 12;
+ optional sfixed64 sfixed64_field = 13;
+ optional sint32 sint32_field = 14;
+ optional sint64 sint64_field = 15;
}
message Event {
@@ -70,6 +69,8 @@ message Event {
message BadTypesAtom {
optional IntAtom bad_int_atom = 1;
optional bytes bad_bytes = 2;
+ repeated int32 repeated_field = 3;
+ optional double double_field = 4;
}
message BadTypesEvent {
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index bcf18ae8bf19..a972e2342cad 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -98,7 +98,6 @@ TEST(CollationTest, CollateStats) {
EXPECT_SET_CONTAINS_SIGNATURE(
atoms.signatures_to_modules,
JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
- JAVA_TYPE_DOUBLE, // double
JAVA_TYPE_FLOAT, // float
JAVA_TYPE_LONG, // int64
JAVA_TYPE_LONG, // uint64
@@ -157,13 +156,13 @@ TEST(CollationTest, NonMessageTypeFails) {
}
/**
- * Test that atoms that have non-primitive types are rejected.
+ * Test that atoms that have non-primitive types or repeated fields are rejected.
*/
TEST(CollationTest, FailOnBadTypes) {
Atoms atoms;
int errorCount = collate_atoms(BadTypesEvent::descriptor(), &atoms);
- EXPECT_EQ(2, errorCount);
+ EXPECT_EQ(4, errorCount);
}
/**
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index 8c4abe43a49b..cd6914b4fc06 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -286,9 +286,6 @@ void write_java_atom_codes(FILE* out, const Atoms& atoms, const string& moduleNa
if (non_chained_decl != atom_code_to_non_chained_decl_map.end()) {
write_java_usage(out, "write_non_chained", constant, *non_chained_decl->second);
}
- if (moduleName == DEFAULT_MODULE_NAME) {
- fprintf(out, " * @hide\n");
- }
fprintf(out, " */\n");
fprintf(out, " public static final int %s = %d;\n", constant.c_str(), atom->code);
}
@@ -310,9 +307,6 @@ void write_java_enum_values(FILE* out, const Atoms& atoms, const string& moduleN
field->name.c_str());
for (map<int, string>::const_iterator value = field->enumValues.begin();
value != field->enumValues.end(); value++) {
- if (moduleName == DEFAULT_MODULE_NAME) {
- fprintf(out, " /** @hide */\n");
- }
fprintf(out, " public static final int %s__%s__%s = %d;\n",
make_constant_name(atom->message).c_str(),
make_constant_name(field->name).c_str(),
@@ -357,9 +351,6 @@ int write_java_non_chained_methods(
}
// Print method signature.
- if (DEFAULT_MODULE_NAME == moduleName) {
- fprintf(out, " /** @hide */\n");
- }
fprintf(out, " public static void write_non_chained(int code");
vector<java_type_t> signature = signature_to_modules_it->first;
int argIndex = 1;
@@ -434,9 +425,6 @@ int write_java_work_source_methods(
fprintf(out, "\n");
// Method header (signature)
- if (DEFAULT_MODULE_NAME == moduleName) {
- fprintf(out, " /** @hide */\n");
- }
fprintf(out, " public static void write(int code");
int argIndex = 1;
for (vector<java_type_t>::const_iterator arg = signature.begin();
diff --git a/tools/stats_log_api_gen/utils.h b/tools/stats_log_api_gen/utils.h
index cd602e53359a..715d42bc160a 100644
--- a/tools/stats_log_api_gen/utils.h
+++ b/tools/stats_log_api_gen/utils.h
@@ -34,8 +34,6 @@ const string DEFAULT_MODULE_NAME = "DEFAULT";
const string DEFAULT_CPP_NAMESPACE = "android,util";
const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h";
const string DEFAULT_ATOMS_INFO_CPP_HEADER_IMPORT = "atoms_info.h";
-const string DEFAULT_JAVA_PACKAGE = "android.util";
-const string DEFAULT_JAVA_CLASS = "StatsLogInternal";
const int JAVA_MODULE_REQUIRES_FLOAT = 0x01;
const int JAVA_MODULE_REQUIRES_ATTRIBUTION = 0x02;