Merge "Update framework from jetpack." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4e229f4471
@@ -50,9 +50,6 @@ import java.util.Set;
|
|||||||
public class GenericDocument {
|
public class GenericDocument {
|
||||||
private static final String TAG = "AppSearchGenericDocumen";
|
private static final String TAG = "AppSearchGenericDocumen";
|
||||||
|
|
||||||
/** The maximum number of elements in a repeatable field. */
|
|
||||||
private static final int MAX_REPEATED_PROPERTY_LENGTH = 100;
|
|
||||||
|
|
||||||
/** The maximum {@link String#length} of a {@link String} field. */
|
/** The maximum {@link String#length} of a {@link String} field. */
|
||||||
private static final int MAX_STRING_LENGTH = 20_000;
|
private static final int MAX_STRING_LENGTH = 20_000;
|
||||||
|
|
||||||
@@ -1187,8 +1184,8 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code String} values of the property.
|
* @param values the {@code String} values of the property.
|
||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
* @throws IllegalArgumentException if no values are provided, or if a passed in {@code
|
||||||
* maximum repeated property length, or if a passed in {@code String} is {@code null}.
|
* String} is {@code null}.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
|
public BuilderType setPropertyString(@NonNull String name, @NonNull String... values) {
|
||||||
@@ -1206,7 +1203,6 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code boolean} values of the property.
|
* @param values the {@code boolean} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
|
public BuilderType setPropertyBoolean(@NonNull String name, @NonNull boolean... values) {
|
||||||
@@ -1223,7 +1219,6 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code long} values of the property.
|
* @param values the {@code long} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
|
public BuilderType setPropertyLong(@NonNull String name, @NonNull long... values) {
|
||||||
@@ -1240,7 +1235,6 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code double} values of the property.
|
* @param values the {@code double} values of the property.
|
||||||
* @throws IllegalArgumentException if values exceed maximum repeated property length.
|
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
|
public BuilderType setPropertyDouble(@NonNull String name, @NonNull double... values) {
|
||||||
@@ -1257,8 +1251,8 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@code byte[]} of the property.
|
* @param values the {@code byte[]} of the property.
|
||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed
|
* @throws IllegalArgumentException if no values are provided, or if a passed in {@code
|
||||||
* maximum repeated property length, or if a passed in {@code byte[]} is {@code null}.
|
* byte[]} is {@code null}.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
|
public BuilderType setPropertyBytes(@NonNull String name, @NonNull byte[]... values) {
|
||||||
@@ -1276,8 +1270,7 @@ public class GenericDocument {
|
|||||||
* @param name the name associated with the {@code values}. Must match the name for this
|
* @param name the name associated with the {@code values}. Must match the name for this
|
||||||
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
* property as given in {@link AppSearchSchema.PropertyConfig#getName}.
|
||||||
* @param values the {@link GenericDocument} values of the property.
|
* @param values the {@link GenericDocument} values of the property.
|
||||||
* @throws IllegalArgumentException if no values are provided, if provided values exceed if
|
* @throws IllegalArgumentException if no values are provided, or if a passed in {@link
|
||||||
* provided values exceed maximum repeated property length, or if a passed in {@link
|
|
||||||
* GenericDocument} is {@code null}.
|
* GenericDocument} is {@code null}.
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -1308,7 +1301,6 @@ public class GenericDocument {
|
|||||||
|
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull String[] values)
|
private void putInPropertyBundle(@NonNull String name, @NonNull String[] values)
|
||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] == null) {
|
if (values[i] == null) {
|
||||||
throw new IllegalArgumentException("The String at " + i + " is null.");
|
throw new IllegalArgumentException("The String at " + i + " is null.");
|
||||||
@@ -1327,17 +1319,14 @@ public class GenericDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) {
|
private void putInPropertyBundle(@NonNull String name, @NonNull boolean[] values) {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
mProperties.putBooleanArray(name, values);
|
mProperties.putBooleanArray(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) {
|
private void putInPropertyBundle(@NonNull String name, @NonNull double[] values) {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
mProperties.putDoubleArray(name, values);
|
mProperties.putDoubleArray(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) {
|
private void putInPropertyBundle(@NonNull String name, @NonNull long[] values) {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
mProperties.putLongArray(name, values);
|
mProperties.putLongArray(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,7 +1337,6 @@ public class GenericDocument {
|
|||||||
* into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
|
* into ArrayList<Bundle>, and each elements will contain a one dimension byte[].
|
||||||
*/
|
*/
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) {
|
private void putInPropertyBundle(@NonNull String name, @NonNull byte[][] values) {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
ArrayList<Bundle> bundles = new ArrayList<>(values.length);
|
ArrayList<Bundle> bundles = new ArrayList<>(values.length);
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] == null) {
|
if (values[i] == null) {
|
||||||
@@ -1362,7 +1350,6 @@ public class GenericDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) {
|
private void putInPropertyBundle(@NonNull String name, @NonNull GenericDocument[] values) {
|
||||||
validateRepeatedPropertyLength(name, values.length);
|
|
||||||
Parcelable[] documentBundles = new Parcelable[values.length];
|
Parcelable[] documentBundles = new Parcelable[values.length];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] == null) {
|
if (values[i] == null) {
|
||||||
@@ -1373,18 +1360,6 @@ public class GenericDocument {
|
|||||||
mProperties.putParcelableArray(name, documentBundles);
|
mProperties.putParcelableArray(name, documentBundles);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void validateRepeatedPropertyLength(@NonNull String name, int length) {
|
|
||||||
if (length > MAX_REPEATED_PROPERTY_LENGTH) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Repeated property \""
|
|
||||||
+ name
|
|
||||||
+ "\" has length "
|
|
||||||
+ length
|
|
||||||
+ ", which exceeds the limit of "
|
|
||||||
+ MAX_REPEATED_PROPERTY_LENGTH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Builds the {@link GenericDocument} object. */
|
/** Builds the {@link GenericDocument} object. */
|
||||||
@NonNull
|
@NonNull
|
||||||
public GenericDocument build() {
|
public GenericDocument build() {
|
||||||
|
|||||||
@@ -169,13 +169,14 @@ public final class SetSchemaRequest {
|
|||||||
|
|
||||||
/** Builder for {@link SetSchemaRequest} objects. */
|
/** Builder for {@link SetSchemaRequest} objects. */
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
private static final int DEFAULT_VERSION = 1;
|
||||||
private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>();
|
private ArraySet<AppSearchSchema> mSchemas = new ArraySet<>();
|
||||||
private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
|
private ArraySet<String> mSchemasNotDisplayedBySystem = new ArraySet<>();
|
||||||
private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
|
private ArrayMap<String, Set<PackageIdentifier>> mSchemasVisibleToPackages =
|
||||||
new ArrayMap<>();
|
new ArrayMap<>();
|
||||||
private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
|
private ArrayMap<String, Migrator> mMigrators = new ArrayMap<>();
|
||||||
private boolean mForceOverride = false;
|
private boolean mForceOverride = false;
|
||||||
private int mVersion = 1;
|
private int mVersion = DEFAULT_VERSION;
|
||||||
private boolean mBuilt = false;
|
private boolean mBuilt = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -384,6 +385,9 @@ public final class SetSchemaRequest {
|
|||||||
* <p>The version number can stay the same, increase, or decrease relative to the current
|
* <p>The version number can stay the same, increase, or decrease relative to the current
|
||||||
* version number that is already stored in the {@link AppSearchSession} database.
|
* version number that is already stored in the {@link AppSearchSession} database.
|
||||||
*
|
*
|
||||||
|
* <p>The version of an empty database will always be 0. You cannot set version to the
|
||||||
|
* {@link SetSchemaRequest}, if it doesn't contains any {@link AppSearchSchema}.
|
||||||
|
*
|
||||||
* @param version A positive integer representing the version of the entire set of schemas
|
* @param version A positive integer representing the version of the entire set of schemas
|
||||||
* represents the version of the whole schema in the {@link AppSearchSession} database,
|
* represents the version of the whole schema in the {@link AppSearchSession} database,
|
||||||
* default version is 1.
|
* default version is 1.
|
||||||
@@ -423,7 +427,10 @@ public final class SetSchemaRequest {
|
|||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Schema types " + referencedSchemas + " referenced, but were not added.");
|
"Schema types " + referencedSchemas + " referenced, but were not added.");
|
||||||
}
|
}
|
||||||
|
if (mSchemas.isEmpty() && mVersion != DEFAULT_VERSION) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Cannot set version to the request if schema is empty.");
|
||||||
|
}
|
||||||
mBuilt = true;
|
mBuilt = true;
|
||||||
return new SetSchemaRequest(
|
return new SetSchemaRequest(
|
||||||
mSchemas,
|
mSchemas,
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.server.LocalManagerRegistry;
|
import com.android.server.LocalManagerRegistry;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
import com.android.server.appsearch.external.localstorage.stats.CallStats;
|
||||||
|
import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
|
||||||
import com.android.server.appsearch.util.PackageUtil;
|
import com.android.server.appsearch.util.PackageUtil;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
|
||||||
import com.android.server.usage.StorageStatsManagerLocal;
|
import com.android.server.usage.StorageStatsManagerLocal;
|
||||||
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
|
import com.android.server.usage.StorageStatsManagerLocal.StorageStatsAugmenter;
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import android.annotation.NonNull;
|
|||||||
|
|
||||||
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||||
import com.android.server.appsearch.stats.PlatformLogger;
|
import com.android.server.appsearch.stats.PlatformLogger;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -30,12 +30,12 @@ import java.util.Objects;
|
|||||||
public final class AppSearchUserInstance {
|
public final class AppSearchUserInstance {
|
||||||
private final PlatformLogger mLogger;
|
private final PlatformLogger mLogger;
|
||||||
private final AppSearchImpl mAppSearchImpl;
|
private final AppSearchImpl mAppSearchImpl;
|
||||||
private final VisibilityStore mVisibilityStore;
|
private final VisibilityStoreImpl mVisibilityStore;
|
||||||
|
|
||||||
AppSearchUserInstance(
|
AppSearchUserInstance(
|
||||||
@NonNull PlatformLogger logger,
|
@NonNull PlatformLogger logger,
|
||||||
@NonNull AppSearchImpl appSearchImpl,
|
@NonNull AppSearchImpl appSearchImpl,
|
||||||
@NonNull VisibilityStore visibilityStore) {
|
@NonNull VisibilityStoreImpl visibilityStore) {
|
||||||
mLogger = Objects.requireNonNull(logger);
|
mLogger = Objects.requireNonNull(logger);
|
||||||
mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
|
mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
|
||||||
mVisibilityStore = Objects.requireNonNull(visibilityStore);
|
mVisibilityStore = Objects.requireNonNull(visibilityStore);
|
||||||
@@ -52,7 +52,7 @@ public final class AppSearchUserInstance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public VisibilityStore getVisibilityStore() {
|
public VisibilityStoreImpl getVisibilityStore() {
|
||||||
return mVisibilityStore;
|
return mVisibilityStore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
|||||||
import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
|
import com.android.server.appsearch.external.localstorage.FrameworkOptimizeStrategy;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
||||||
import com.android.server.appsearch.stats.PlatformLogger;
|
import com.android.server.appsearch.stats.PlatformLogger;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -178,7 +178,8 @@ public final class AppSearchUserInstanceManager {
|
|||||||
AppSearchImpl.create(icingDir, initStatsBuilder, new FrameworkOptimizeStrategy());
|
AppSearchImpl.create(icingDir, initStatsBuilder, new FrameworkOptimizeStrategy());
|
||||||
|
|
||||||
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
|
long prepareVisibilityStoreLatencyStartMillis = SystemClock.elapsedRealtime();
|
||||||
VisibilityStore visibilityStore = VisibilityStore.create(appSearchImpl, userContext);
|
VisibilityStoreImpl visibilityStore =
|
||||||
|
VisibilityStoreImpl.create(appSearchImpl, userContext);
|
||||||
long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
|
long prepareVisibilityStoreLatencyEndMillis = SystemClock.elapsedRealtime();
|
||||||
|
|
||||||
initStatsBuilder
|
initStatsBuilder
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ import com.android.server.appsearch.external.localstorage.stats.InitializeStats;
|
|||||||
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
import com.android.server.appsearch.external.localstorage.stats.PutDocumentStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
import com.android.server.appsearch.external.localstorage.stats.RemoveStats;
|
||||||
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
import com.android.server.appsearch.external.localstorage.stats.SearchStats;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
|
||||||
|
|
||||||
import com.google.android.icing.IcingSearchEngine;
|
import com.google.android.icing.IcingSearchEngine;
|
||||||
import com.google.android.icing.proto.DeleteByQueryResultProto;
|
import com.google.android.icing.proto.DeleteByQueryResultProto;
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 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.external.localstorage.visibilitystore;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.app.appsearch.PackageIdentifier;
|
||||||
|
import android.app.appsearch.exceptions.AppSearchException;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for classes that store and validate document visibility data.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public interface VisibilityStore {
|
||||||
|
/**
|
||||||
|
* These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
|
||||||
|
* AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
|
||||||
|
*/
|
||||||
|
String PACKAGE_NAME = "VS#Pkg";
|
||||||
|
|
||||||
|
@VisibleForTesting String DATABASE_NAME = "VS#Db";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets visibility settings for the given database. Any previous visibility settings will be
|
||||||
|
* overwritten.
|
||||||
|
*
|
||||||
|
* @param packageName Package of app that owns the schemas.
|
||||||
|
* @param databaseName Database that owns the schemas.
|
||||||
|
* @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from
|
||||||
|
* platform surfaces.
|
||||||
|
* @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
|
||||||
|
* have access to the schema.
|
||||||
|
* @throws AppSearchException on AppSearchImpl error.
|
||||||
|
*/
|
||||||
|
void setVisibility(
|
||||||
|
@NonNull String packageName,
|
||||||
|
@NonNull String databaseName,
|
||||||
|
@NonNull Set<String> schemasNotDisplayedBySystem,
|
||||||
|
@NonNull Map<String, List<PackageIdentifier>> schemasVisibleToPackages)
|
||||||
|
throws AppSearchException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package has access to system-surfaceable schemas.
|
||||||
|
*
|
||||||
|
* @param callerUid UID of the app that wants to see the data.
|
||||||
|
*/
|
||||||
|
boolean isSchemaSearchableByCaller(
|
||||||
|
@NonNull String packageName,
|
||||||
|
@NonNull String databaseName,
|
||||||
|
@NonNull String prefixedSchema,
|
||||||
|
int callerUid,
|
||||||
|
boolean callerHasSystemAccess);
|
||||||
|
}
|
||||||
@@ -30,9 +30,9 @@ import android.os.UserHandle;
|
|||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
|
||||||
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||||
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
||||||
|
import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
|
||||||
import com.android.server.appsearch.util.PackageUtil;
|
import com.android.server.appsearch.util.PackageUtil;
|
||||||
|
|
||||||
import com.google.android.icing.proto.PersistType;
|
import com.google.android.icing.proto.PersistType;
|
||||||
@@ -60,23 +60,12 @@ import java.util.Set;
|
|||||||
* <p>This class doesn't handle any locking itself. Its callers should handle the locking at a
|
* <p>This class doesn't handle any locking itself. Its callers should handle the locking at a
|
||||||
* higher level.
|
* higher level.
|
||||||
*
|
*
|
||||||
* <p>NOTE: This class holds an instance of AppSearchImpl and AppSearchImpl holds an instance of
|
|
||||||
* this class. Take care to not cause any circular dependencies.
|
|
||||||
*
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public class VisibilityStore {
|
public class VisibilityStoreImpl implements VisibilityStore {
|
||||||
/** Version for the visibility schema */
|
/** Version for the visibility schema */
|
||||||
private static final int SCHEMA_VERSION = 0;
|
private static final int SCHEMA_VERSION = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* These cannot have any of the special characters used by AppSearchImpl (e.g. {@code
|
|
||||||
* AppSearchImpl#PACKAGE_DELIMITER} or {@code AppSearchImpl#DATABASE_DELIMITER}.
|
|
||||||
*/
|
|
||||||
public static final String PACKAGE_NAME = "VS#Pkg";
|
|
||||||
|
|
||||||
@VisibleForTesting public static final String DATABASE_NAME = "VS#Db";
|
|
||||||
|
|
||||||
/** Namespace of documents that contain visibility settings */
|
/** Namespace of documents that contain visibility settings */
|
||||||
private static final String NAMESPACE = "";
|
private static final String NAMESPACE = "";
|
||||||
|
|
||||||
@@ -101,13 +90,13 @@ public class VisibilityStore {
|
|||||||
* @param userContext Context of the user that the call is being made as
|
* @param userContext Context of the user that the call is being made as
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
public static VisibilityStore create(
|
public static VisibilityStoreImpl create(
|
||||||
@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
|
@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
return new VisibilityStore(appSearchImpl, userContext);
|
return new VisibilityStoreImpl(appSearchImpl, userContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
private VisibilityStore(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
|
private VisibilityStoreImpl(@NonNull AppSearchImpl appSearchImpl, @NonNull Context userContext)
|
||||||
throws AppSearchException {
|
throws AppSearchException {
|
||||||
mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
|
mAppSearchImpl = Objects.requireNonNull(appSearchImpl);
|
||||||
mUserContext = Objects.requireNonNull(userContext);
|
mUserContext = Objects.requireNonNull(userContext);
|
||||||
@@ -207,18 +196,7 @@ public class VisibilityStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Sets visibility settings for the given database. Any previous visibility settings will be
|
|
||||||
* overwritten.
|
|
||||||
*
|
|
||||||
* @param packageName Package of app that owns the schemas.
|
|
||||||
* @param databaseName Database that owns the schemas.
|
|
||||||
* @param schemasNotDisplayedBySystem Set of prefixed schemas that should be hidden from the
|
|
||||||
* platform.
|
|
||||||
* @param schemasVisibleToPackages Map of prefixed schemas to a list of package identifiers that
|
|
||||||
* have access to the schema.
|
|
||||||
* @throws AppSearchException on AppSearchImpl error.
|
|
||||||
*/
|
|
||||||
public void setVisibility(
|
public void setVisibility(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull String databaseName,
|
@NonNull String databaseName,
|
||||||
@@ -282,17 +260,7 @@ public class VisibilityStore {
|
|||||||
== PackageManager.PERMISSION_GRANTED;
|
== PackageManager.PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Checks whether {@code prefixedSchema} can be searched over by the {@code callerUid}.
|
|
||||||
*
|
|
||||||
* @param packageName Package that owns the schema.
|
|
||||||
* @param databaseName Database within the package that owns the schema.
|
|
||||||
* @param prefixedSchema Prefixed schema type the caller is trying to access.
|
|
||||||
* @param callerUid UID of the client making the globalQuery call.
|
|
||||||
* @param callerHasSystemAccess Whether the caller has been identified as having
|
|
||||||
* access to schemas marked system surfaceable by {@link
|
|
||||||
* #doesCallerHaveSystemAccess}.
|
|
||||||
*/
|
|
||||||
public boolean isSchemaSearchableByCaller(
|
public boolean isSchemaSearchableByCaller(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@NonNull String databaseName,
|
@NonNull String databaseName,
|
||||||
@@ -1 +1 @@
|
|||||||
04351b43fbbf9d59ffeae41903322023931c84f2
|
a11281766f66aa4919e9bbe70da95919ce054c35
|
||||||
|
|||||||
@@ -1,44 +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 static com.google.common.truth.Truth.assertThat;
|
|
||||||
|
|
||||||
import com.android.server.appsearch.testing.AppSearchEmail;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class PutDocumentsRequestTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void addGenericDocument_byCollection() {
|
|
||||||
Set<AppSearchEmail> emails =
|
|
||||||
ImmutableSet.of(
|
|
||||||
new AppSearchEmail.Builder("namespace", "test1").build(),
|
|
||||||
new AppSearchEmail.Builder("namespace", "test2").build());
|
|
||||||
PutDocumentsRequest request =
|
|
||||||
new PutDocumentsRequest.Builder().addGenericDocuments(emails).build();
|
|
||||||
|
|
||||||
assertThat(request.getGenericDocuments().get(0).getId()).isEqualTo("test1");
|
|
||||||
assertThat(request.getGenericDocuments().get(1).getId()).isEqualTo("test2");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -42,7 +42,7 @@ import androidx.test.core.app.ApplicationProvider;
|
|||||||
|
|
||||||
import com.android.compatibility.common.util.SystemUtil;
|
import com.android.compatibility.common.util.SystemUtil;
|
||||||
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
import com.android.server.appsearch.visibilitystore.VisibilityStoreImpl;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
@@ -67,7 +67,7 @@ public class AppSearchImplPlatformTest {
|
|||||||
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private AppSearchImpl mAppSearchImpl;
|
private AppSearchImpl mAppSearchImpl;
|
||||||
private VisibilityStore mVisibilityStore;
|
private VisibilityStoreImpl mVisibilityStore;
|
||||||
private int mGlobalQuerierUid;
|
private int mGlobalQuerierUid;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -93,7 +93,7 @@ public class AppSearchImplPlatformTest {
|
|||||||
// Give ourselves global query permissions
|
// Give ourselves global query permissions
|
||||||
mAppSearchImpl = AppSearchImpl.create(
|
mAppSearchImpl = AppSearchImpl.create(
|
||||||
mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
|
mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
|
||||||
mVisibilityStore = VisibilityStore.create(mAppSearchImpl, mContext);
|
mVisibilityStore = VisibilityStoreImpl.create(mAppSearchImpl, mContext);
|
||||||
mGlobalQuerierUid =
|
mGlobalQuerierUid =
|
||||||
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,10 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO(b/169883602): This is purposely a different package from the path so that it can access
|
package com.android.server.appsearch.visibilitystore;
|
||||||
// AppSearchImpl methods without having to make methods public. This should be moved into a proper
|
|
||||||
// package once AppSearchImpl-VisibilityStore's dependencies are refactored.
|
|
||||||
package com.android.server.appsearch.external.localstorage;
|
|
||||||
|
|
||||||
import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
|
import static android.Manifest.permission.READ_GLOBAL_APP_SEARCH_DATA;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||||
@@ -39,8 +36,10 @@ import android.util.ArrayMap;
|
|||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.server.appsearch.external.localstorage.AppSearchImpl;
|
||||||
|
import com.android.server.appsearch.external.localstorage.OptimizeStrategy;
|
||||||
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
import com.android.server.appsearch.external.localstorage.util.PrefixUtil;
|
||||||
import com.android.server.appsearch.visibilitystore.VisibilityStore;
|
import com.android.server.appsearch.external.localstorage.visibilitystore.VisibilityStore;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
@@ -55,7 +54,7 @@ import org.mockito.Mockito;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class VisibilityStoreTest {
|
public class VisibilityStoreImplTest {
|
||||||
/**
|
/**
|
||||||
* Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
|
* Always trigger optimize in this class. OptimizeStrategy will be tested in its own test class.
|
||||||
*/
|
*/
|
||||||
@@ -64,7 +63,7 @@ public class VisibilityStoreTest {
|
|||||||
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
|
@Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
|
||||||
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
private final Map<UserHandle, PackageManager> mMockPackageManagers = new ArrayMap<>();
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private VisibilityStore mVisibilityStore;
|
private VisibilityStoreImpl mVisibilityStore;
|
||||||
private int mUid;
|
private int mUid;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -90,7 +89,7 @@ public class VisibilityStoreTest {
|
|||||||
// Give ourselves global query permissions
|
// Give ourselves global query permissions
|
||||||
AppSearchImpl appSearchImpl = AppSearchImpl.create(
|
AppSearchImpl appSearchImpl = AppSearchImpl.create(
|
||||||
mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
|
mTemporaryFolder.newFolder(), /*initStatsBuilder=*/ null, ALWAYS_OPTIMIZE);
|
||||||
mVisibilityStore = VisibilityStore.create(appSearchImpl, mContext);
|
mVisibilityStore = VisibilityStoreImpl.create(appSearchImpl, mContext);
|
||||||
mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
mUid = mContext.getPackageManager().getPackageUid(mContext.getPackageName(), /*flags=*/ 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user