Safeparcelables in AppSearch - VisibilityDocument
Make VisibilityDocument and VisibilityPermissionDocument SafeParcelable,
and remove their inheritance to GenericDocument. GenericDocument will
contain a GenericDocumentParcel in the future, and it is unnecessary to
have this internal SafeParcel for VisibilityDocument. Plus, we have plan
NOT to store visibility documents in IcingLib in the future:
b/298118943.
For now, we still need to convert those two to GenericDocuments until
we completely treat them differently for b/298118943.
Bug: 275629842
Test: appsearch:appsearch:connectedCheck appsearch:appsearch-local-storage:connectedCheck
Change-Id: Ic237f2460f79d6997e8639e7a0e320cccbe30190
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
index c2eac42..d20b0f7 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/AppSearchImplTest.java
@@ -2269,7 +2269,6 @@
VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("schema")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
// Insert schema for package A and B.
@@ -2314,13 +2313,11 @@
new VisibilityDocument.Builder("packageA$database/schema")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
VisibilityDocument expectedVisibilityDocumentB =
new VisibilityDocument.Builder("packageB$database/schema")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked
.getVisibility("packageA$database/schema"))
@@ -4243,7 +4240,6 @@
VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("Email").build());
@@ -4264,17 +4260,17 @@
VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
.isEqualTo(expectedDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(expectedDocument);
}
@@ -4284,7 +4280,6 @@
VisibilityDocument visibilityDocument1 = new VisibilityDocument.Builder("Email1")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
List<AppSearchSchema> schemas1 =
Collections.singletonList(new AppSearchSchema.Builder("Email1").build());
@@ -4305,24 +4300,23 @@
VisibilityDocument expectedDocument1 = new VisibilityDocument.Builder(prefix1 + "Email1")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix1 + "Email1"))
.isEqualTo(expectedDocument1);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument1 = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument1 =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix1 + "Email1",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument1).isEqualTo(expectedDocument1);
// Create Visibility Document for Email2
VisibilityDocument visibilityDocument2 = new VisibilityDocument.Builder("Email2")
.setNotDisplayedBySystem(false)
.addVisibleToPackage(new PackageIdentifier("pkgFoo", new byte[32]))
- .setCreationTimestampMillis(54321L)
.build();
List<AppSearchSchema> schemas2 =
Collections.singletonList(new AppSearchSchema.Builder("Email2").build());
@@ -4343,29 +4337,29 @@
VisibilityDocument expectedDocument2 = new VisibilityDocument.Builder(prefix2 + "Email2")
.setNotDisplayedBySystem(false)
.addVisibleToPackage(new PackageIdentifier("pkgFoo", new byte[32]))
- .setCreationTimestampMillis(54321)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix2 + "Email2"))
.isEqualTo(expectedDocument2);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument2 = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument2 = new VisibilityDocument.Builder(
+ mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix2 + "Email2",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument2).isEqualTo(expectedDocument2);
// Check the existing visibility document retains.
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix1 + "Email1"))
.isEqualTo(expectedDocument1);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- actualDocument1 = new VisibilityDocument(mAppSearchImpl.getDocument(
+ actualDocument1 = new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix1 + "Email1",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument1).isEqualTo(expectedDocument1);
}
@@ -4375,7 +4369,6 @@
VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
List<AppSearchSchema> schemas =
@@ -4395,17 +4388,17 @@
VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
.isEqualTo(expectedDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(expectedDocument);
// Set schema Email and its all-default visibility document to AppSearch database1
@@ -4439,7 +4432,6 @@
VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
List<AppSearchSchema> schemas =
@@ -4458,17 +4450,17 @@
VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
.isEqualTo(expectedDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(expectedDocument);
// remove the schema and visibility setting from AppSearch
@@ -4511,7 +4503,6 @@
VisibilityDocument visibilityDocument = new VisibilityDocument.Builder("Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
List<AppSearchSchema> schemas =
Collections.singletonList(new AppSearchSchema.Builder("Email").build());
@@ -4541,18 +4532,18 @@
VisibilityDocument expectedDocument = new VisibilityDocument.Builder(prefix + "Email")
.setNotDisplayedBySystem(true)
.addVisibleToPackage(new PackageIdentifier("pkgBar", new byte[32]))
- .setCreationTimestampMillis(12345L)
.build();
assertThat(mAppSearchImpl.mVisibilityStoreLocked.getVisibility(prefix + "Email"))
.isEqualTo(expectedDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(expectedDocument);
// remove schema and visibility document
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
index d516e81..77772c4 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV0Test.java
@@ -134,31 +134,29 @@
ALWAYS_OPTIMIZE,
/*visibilityChecker=*/null);
- VisibilityDocument actualDocument1 = new VisibilityDocument(
+ VisibilityDocument actualDocument1 = new VisibilityDocument.Builder(
appSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Schema1",
- /*typePropertyPaths=*/ Collections.emptyMap()));
- VisibilityDocument actualDocument2 = new VisibilityDocument(
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
+ VisibilityDocument actualDocument2 = new VisibilityDocument.Builder(
appSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Schema2",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
VisibilityDocument expectedDocument1 =
new VisibilityDocument.Builder(/*id=*/ prefix + "Schema1")
.setNotDisplayedBySystem(true)
- .setCreationTimestampMillis(actualDocument1.getCreationTimestampMillis())
.addVisibleToPackage(new PackageIdentifier(packageNameFoo, sha256CertFoo))
.build();
VisibilityDocument expectedDocument2 =
new VisibilityDocument.Builder(/*id=*/ prefix + "Schema2")
.setNotDisplayedBySystem(true)
- .setCreationTimestampMillis(actualDocument2.getCreationTimestampMillis())
.addVisibleToPackage(new PackageIdentifier(packageNameBar, sha256CertBar))
.build();
assertThat(actualDocument1).isEqualTo(expectedDocument1);
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
index 56086d4..c5bd8ac 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreMigrationHelperFromV1Test.java
@@ -128,13 +128,13 @@
ALWAYS_OPTIMIZE,
/*visibilityChecker=*/null);
- VisibilityDocument actualDocument = new VisibilityDocument(
+ VisibilityDocument actualDocument = new VisibilityDocument.Builder(
appSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Schema",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument.isNotDisplayedBySystem()).isTrue();
assertThat(actualDocument.getPackageNames()).asList().containsExactly(packageNameFoo,
diff --git a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
index 721b3ad..17e8a15 100644
--- a/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
+++ b/appsearch/appsearch-local-storage/src/androidTest/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStoreTest.java
@@ -110,12 +110,13 @@
assertThat(mVisibilityStore.getVisibility(prefix + "Email"))
.isEqualTo(visibilityDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument =
+ new VisibilityDocument.Builder(mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefix + "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(visibilityDocument);
}
@@ -130,12 +131,13 @@
assertThat(mVisibilityStore.getVisibility("Email"))
.isEqualTo(visibilityDocument);
// Verify the VisibilityDocument is saved to AppSearchImpl.
- VisibilityDocument actualDocument = new VisibilityDocument(mAppSearchImpl.getDocument(
+ VisibilityDocument actualDocument = new VisibilityDocument.Builder(
+ mAppSearchImpl.getDocument(
VisibilityStore.VISIBILITY_PACKAGE_NAME,
VisibilityStore.VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ "Email",
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
assertThat(actualDocument).isEqualTo(visibilityDocument);
mVisibilityStore.removeVisibility(ImmutableSet.of(visibilityDocument.getId()));
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
index 8b136a3..b64bab8 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/AppSearchImpl.java
@@ -813,10 +813,9 @@
// fake the id, they can only mess their own app. That's totally allowed and
// they can do this via the public API too.
String prefixedSchemaType = prefix + unPrefixedDocument.getId();
- prefixedVisibilityDocuments.add(new VisibilityDocument(
- unPrefixedDocument.toBuilder()
- .setId(prefixedSchemaType)
- .build()));
+ prefixedVisibilityDocuments.add(
+ new VisibilityDocument.Builder(
+ unPrefixedDocument).setId(prefixedSchemaType).build());
// This schema has visibility settings. We should keep it from the removal list.
deprecatedVisibilityDocuments.remove(prefixedSchemaType);
}
diff --git a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
index b44cc3e..e3d5916 100644
--- a/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
+++ b/appsearch/appsearch-local-storage/src/main/java/androidx/appsearch/localstorage/visibilitystore/VisibilityStore.java
@@ -165,7 +165,7 @@
mAppSearchImpl.putDocument(
VISIBILITY_PACKAGE_NAME,
VISIBILITY_DATABASE_NAME,
- prefixedVisibilityDocument,
+ prefixedVisibilityDocument.toGenericDocument(),
/*sendChangeNotifications=*/ false,
/*logger=*/ null);
mVisibilityDocumentMap.put(prefixedVisibilityDocument.getId(),
@@ -226,13 +226,13 @@
VisibilityDocument visibilityDocument;
try {
// Note: We use the other clients' prefixed schema type as ids
- visibilityDocument = new VisibilityDocument(
+ visibilityDocument = new VisibilityDocument.Builder(
mAppSearchImpl.getDocument(
VISIBILITY_PACKAGE_NAME,
VISIBILITY_DATABASE_NAME,
VisibilityDocument.NAMESPACE,
/*id=*/ prefixedSchemaType,
- /*typePropertyPaths=*/ Collections.emptyMap()));
+ /*typePropertyPaths=*/ Collections.emptyMap())).build();
} catch (AppSearchException e) {
if (e.getResultCode() == RESULT_NOT_FOUND) {
// The schema has all default setting and we won't have a VisibilityDocument for
@@ -274,7 +274,7 @@
mAppSearchImpl.putDocument(
VISIBILITY_PACKAGE_NAME,
VISIBILITY_DATABASE_NAME,
- migratedDocument,
+ migratedDocument.toGenericDocument(),
/*sendChangeNotifications=*/ false,
/*logger=*/ null);
}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
index f794752..2bea91f 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityDocument.java
@@ -15,19 +15,23 @@
*/
package androidx.appsearch.app;
-import android.os.Bundle;
+import android.os.Parcel;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.appsearch.annotation.CanIgnoreReturnValue;
+import androidx.appsearch.safeparcel.AbstractSafeParcelable;
+import androidx.appsearch.safeparcel.SafeParcelable;
+import androidx.appsearch.safeparcel.stub.StubCreators.VisibilityDocumentCreator;
import androidx.collection.ArraySet;
-import androidx.core.util.Preconditions;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -35,7 +39,11 @@
* @exportToFramework:hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public class VisibilityDocument extends GenericDocument {
[email protected](creator = "VisibilityDocumentCreator")
+public final class VisibilityDocument extends AbstractSafeParcelable {
+ @NonNull
+ public static final VisibilityDocumentCreator CREATOR = new VisibilityDocumentCreator();
+
/**
* The Schema type for documents that hold AppSearch's metadata, such as visibility settings.
*/
@@ -92,53 +100,107 @@
.build())
.build();
- public VisibilityDocument(@NonNull GenericDocument genericDocument) {
- super(genericDocument);
+ @NonNull
+ @Field(id = 1, getter = "getId")
+ private String mId;
+
+ @Field(id = 2, getter = "isNotDisplayedBySystem")
+ private final boolean mIsNotDisplayedBySystem;
+
+ @NonNull
+ @Field(id = 3, getter = "getPackageNames")
+ private final String[] mPackageNames;
+
+ @NonNull
+ @Field(id = 4, getter = "getSha256Certs")
+ private final byte[][] mSha256Certs;
+
+ @Nullable
+ @Field(id = 5, getter = "getPermissionDocuments")
+ private final VisibilityPermissionDocument[] mPermissionDocuments;
+
+ @Nullable
+ // We still need to convert this class to a GenericDocument until we completely treat it
+ // differently in AppSearchImpl.
+ // TODO(b/298118943) Remove this once internally we don't use GenericDocument to store
+ // visibility information.
+ private GenericDocument mGenericDocument;
+
+ @Nullable
+ private Integer mHashCode;
+
+ @Constructor
+ VisibilityDocument(
+ @Param(id = 1) @NonNull String id,
+ @Param(id = 2) boolean isNotDisplayedBySystem,
+ @Param(id = 3) @NonNull String[] packageNames,
+ @Param(id = 4) @NonNull byte[][] sha256Certs,
+ @Param(id = 5) @Nullable VisibilityPermissionDocument[] permissionDocuments) {
+ mId = Objects.requireNonNull(id);
+ mIsNotDisplayedBySystem = isNotDisplayedBySystem;
+ mPackageNames = Objects.requireNonNull(packageNames);
+ mSha256Certs = Objects.requireNonNull(sha256Certs);
+ mPermissionDocuments = permissionDocuments;
}
- public VisibilityDocument(@NonNull Bundle bundle) {
- super(bundle);
+ /**
+ * Gets the id for this VisibilityDocument.
+ *
+ * <p>This is being used as the document id when we convert a {@link VisibilityDocument}
+ * to a {@link GenericDocument}.
+ */
+ @NonNull
+ public String getId() {
+ return mId;
}
/** Returns whether this schema is visible to the system. */
public boolean isNotDisplayedBySystem() {
- return getPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
+ return mIsNotDisplayedBySystem;
}
/**
- * Returns a package name array which could access this schema. Use {@link #getSha256Certs()}
- * to get package's sha 256 certs. The same index of package names array and sha256Certs array
+ * Returns a package name array which could access this schema. Use {@link #getSha256Certs()} to
+ * get package's sha 256 certs. The same index of package names array and sha256Certs array
* represents same package.
*/
@NonNull
public String[] getPackageNames() {
- return Preconditions.checkNotNull(getPropertyStringArray(PACKAGE_NAME_PROPERTY));
+ return mPackageNames;
}
/**
- * Returns a package sha256Certs array which could access this schema. Use
- * {@link #getPackageNames()} to get package's name. The same index of package names array
- * and sha256Certs array represents same package.
+ * Returns a package sha256Certs array which could access this schema. Use {@link
+ * #getPackageNames()} to get package's name. The same index of package names array and
+ * sha256Certs array represents same package.
*/
@NonNull
public byte[][] getSha256Certs() {
- return Preconditions.checkNotNull(getPropertyBytesArray(SHA_256_CERT_PROPERTY));
+ return mSha256Certs;
+ }
+
+ /** Gets a list of {@link VisibilityDocument}.
+ *
+ * <p>A {@link VisibilityDocument} holds all required permissions for the caller need to have
+ * to access the schema this {@link VisibilityDocument} presents.
+ */
+ @Nullable
+ VisibilityPermissionDocument[] getPermissionDocuments() {
+ return mPermissionDocuments;
}
/**
- * Returns an array of Android Permissions that caller mush hold to access the schema
- * this {@link VisibilityDocument} represents.
+ * Returns an array of Android Permissions that caller mush hold to access the schema this
+ * {@link VisibilityDocument} represents.
*/
- @Nullable
+ @NonNull
public Set<Set<Integer>> getVisibleToPermissions() {
- GenericDocument[] permissionDocuments = getPropertyDocumentArray(PERMISSION_PROPERTY);
- if (permissionDocuments == null) {
+ if (mPermissionDocuments == null) {
return Collections.emptySet();
}
- Set<Set<Integer>> visibleToPermissions = new ArraySet<>(permissionDocuments.length);
- for (GenericDocument permissionDocument : permissionDocuments) {
- Set<Integer> requiredPermissions = new VisibilityPermissionDocument(
- permissionDocument).getAllRequiredPermissions();
+ Set<Set<Integer>> visibleToPermissions = new ArraySet<>(mPermissionDocuments.length);
+ for (VisibilityPermissionDocument permissionDocument : mPermissionDocuments) {
+ Set<Integer> requiredPermissions = permissionDocument.getAllRequiredPermissions();
if (requiredPermissions != null) {
visibleToPermissions.add(requiredPermissions);
}
@@ -146,92 +208,7 @@
return visibleToPermissions;
}
- /** Builder for {@link VisibilityDocument}. */
- public static class Builder extends GenericDocument.Builder<Builder> {
- private final Set<PackageIdentifier> mPackageIdentifiers = new ArraySet<>();
-
- /**
- * Creates a {@link Builder} for a {@link VisibilityDocument}.
- *
- * @param id The SchemaType of the {@link AppSearchSchema} that this
- * {@link VisibilityDocument} represents. The package and database prefix will be
- * added in server side. We are using prefixed schema type to be the final id of
- * this {@link VisibilityDocument}.
- */
- public Builder(@NonNull String id) {
- super(NAMESPACE, id, SCHEMA_TYPE);
- }
-
- /** Sets whether this schema has opted out of platform surfacing. */
- @CanIgnoreReturnValue
- @NonNull
- public Builder setNotDisplayedBySystem(boolean notDisplayedBySystem) {
- return setPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY,
- notDisplayedBySystem);
- }
-
- /** Add {@link PackageIdentifier} of packages which has access to this schema. */
- @CanIgnoreReturnValue
- @NonNull
- public Builder addVisibleToPackages(@NonNull Set<PackageIdentifier> packageIdentifiers) {
- Preconditions.checkNotNull(packageIdentifiers);
- mPackageIdentifiers.addAll(packageIdentifiers);
- return this;
- }
-
- /** Add {@link PackageIdentifier} of packages which has access to this schema. */
- @CanIgnoreReturnValue
- @NonNull
- public Builder addVisibleToPackage(@NonNull PackageIdentifier packageIdentifier) {
- Preconditions.checkNotNull(packageIdentifier);
- mPackageIdentifiers.add(packageIdentifier);
- return this;
- }
-
- /**
- * Sets required permission sets for a package needs to hold to the schema this
- * {@link VisibilityDocument} represents.
- *
- * <p> The querier could have access if they holds ALL required permissions of ANY of the
- * individual value sets.
- */
- @CanIgnoreReturnValue
- @NonNull
- public Builder setVisibleToPermissions(@NonNull Set<Set<Integer>> visibleToPermissions) {
- Preconditions.checkNotNull(visibleToPermissions);
- VisibilityPermissionDocument[] permissionDocuments =
- new VisibilityPermissionDocument[visibleToPermissions.size()];
- int i = 0;
- for (Set<Integer> allRequiredPermissions : visibleToPermissions) {
- permissionDocuments[i++] = new VisibilityPermissionDocument
- .Builder(NAMESPACE, /*id=*/String.valueOf(i))
- .setVisibleToAllRequiredPermissions(allRequiredPermissions)
- .build();
- }
- setPropertyDocument(PERMISSION_PROPERTY, permissionDocuments);
- return this;
- }
-
- /** Build a {@link VisibilityDocument} */
- @Override
- @NonNull
- public VisibilityDocument build() {
- String[] packageNames = new String[mPackageIdentifiers.size()];
- byte[][] sha256Certs = new byte[mPackageIdentifiers.size()][32];
- int i = 0;
- for (PackageIdentifier packageIdentifier : mPackageIdentifiers) {
- packageNames[i] = packageIdentifier.getPackageName();
- sha256Certs[i] = packageIdentifier.getSha256Certificate();
- ++i;
- }
- setPropertyString(PACKAGE_NAME_PROPERTY, packageNames);
- setPropertyBytes(SHA_256_CERT_PROPERTY, sha256Certs);
- return new VisibilityDocument(super.build());
- }
- }
-
-
- /** Build the List of {@link VisibilityDocument} from visibility settings. */
+ /** Build the List of {@link VisibilityDocument} from visibility settings. */
@NonNull
public static List<VisibilityDocument> toVisibilityDocuments(
@NonNull SetSchemaRequest setSchemaRequest) {
@@ -241,13 +218,11 @@
setSchemaRequest.getSchemasVisibleToPackages();
Map<String, Set<Set<Integer>>> schemasVisibleToPermissions =
setSchemaRequest.getRequiredPermissionsForSchemaTypeVisibility();
-
List<VisibilityDocument> visibilityDocuments = new ArrayList<>(searchSchemas.size());
-
for (AppSearchSchema searchSchema : searchSchemas) {
String schemaType = searchSchema.getSchemaType();
VisibilityDocument.Builder documentBuilder =
- new VisibilityDocument.Builder(/*id=*/searchSchema.getSchemaType());
+ new VisibilityDocument.Builder(/*id=*/ searchSchema.getSchemaType());
documentBuilder.setNotDisplayedBySystem(
schemasNotDisplayedBySystem.contains(schemaType));
@@ -263,4 +238,209 @@
}
return visibilityDocuments;
}
+
+ /**
+ * Generates a {@link GenericDocument} from the current class.
+ *
+ * <p>This conversion is needed until we don't treat Visibility related documents as
+ * {@link GenericDocument}s internally.
+ */
+ @NonNull
+ public GenericDocument toGenericDocument() {
+ if (mGenericDocument == null) {
+ GenericDocument.Builder<?> builder = new GenericDocument.Builder<>(
+ NAMESPACE, mId, SCHEMA_TYPE);
+ builder.setPropertyBoolean(NOT_DISPLAYED_BY_SYSTEM_PROPERTY, mIsNotDisplayedBySystem);
+ builder.setPropertyString(PACKAGE_NAME_PROPERTY, mPackageNames);
+ builder.setPropertyBytes(SHA_256_CERT_PROPERTY, mSha256Certs);
+
+ // Generate an array of GenericDocument for VisibilityPermissionDocument.
+ if (mPermissionDocuments != null) {
+ GenericDocument[] permissionGenericDocs =
+ new GenericDocument[mPermissionDocuments.length];
+ for (int i = 0; i < mPermissionDocuments.length; ++i) {
+ permissionGenericDocs[i] = mPermissionDocuments[i].toGenericDocument();
+ }
+ builder.setPropertyDocument(PERMISSION_PROPERTY, permissionGenericDocs);
+ }
+
+ // The creationTimestamp doesn't matter for Visibility documents.
+ // But to make tests pass, we set it 0 so two GenericDocuments generated from
+ // the same VisibilityDocument can be same.
+ builder.setCreationTimestampMillis(0L);
+
+ mGenericDocument = builder.build();
+ }
+ return mGenericDocument;
+ }
+
+ @Override
+ public int hashCode() {
+ if (mHashCode == null) {
+ mHashCode = Objects.hash(
+ mId,
+ mIsNotDisplayedBySystem,
+ Arrays.hashCode(mPackageNames),
+ Arrays.deepHashCode(mSha256Certs),
+ Arrays.hashCode(mPermissionDocuments));
+ }
+ return mHashCode;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof VisibilityDocument)) {
+ return false;
+ }
+ VisibilityDocument otherVisibilityDocument = (VisibilityDocument) other;
+ return mId.equals(otherVisibilityDocument.mId)
+ && mIsNotDisplayedBySystem == otherVisibilityDocument.mIsNotDisplayedBySystem
+ && Arrays.equals(
+ mPackageNames, otherVisibilityDocument.mPackageNames)
+ && Arrays.deepEquals(
+ mSha256Certs, otherVisibilityDocument.mSha256Certs)
+ && Arrays.equals(
+ mPermissionDocuments, otherVisibilityDocument.mPermissionDocuments);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ VisibilityDocumentCreator.writeToParcel(this, dest, flags);
+ }
+
+ /** Builder for {@link VisibilityDocument}. */
+ public static final class Builder {
+ private final Set<PackageIdentifier> mPackageIdentifiers = new ArraySet<>();
+ private String mId;
+ private boolean mIsNotDisplayedBySystem;
+ private VisibilityPermissionDocument[] mPermissionDocuments;
+
+ /**
+ * Creates a {@link Builder} for a {@link VisibilityDocument}.
+ *
+ * @param id The SchemaType of the {@link AppSearchSchema} that this {@link
+ * VisibilityDocument} represents. The package and database prefix will be added in
+ * server side. We are using prefixed schema type to be the final id of this {@link
+ * VisibilityDocument}.
+ */
+ public Builder(@NonNull String id) {
+ mId = Objects.requireNonNull(id);
+ }
+
+ /**
+ * Constructs a {@link VisibilityDocument} from a {@link GenericDocument}.
+ *
+ * <p>This constructor is still needed until we don't treat Visibility related documents as
+ * {@link GenericDocument}s internally.
+ */
+ public Builder(@NonNull GenericDocument genericDocument) {
+ Objects.requireNonNull(genericDocument);
+
+ mId = genericDocument.getId();
+ mIsNotDisplayedBySystem = genericDocument.getPropertyBoolean(
+ NOT_DISPLAYED_BY_SYSTEM_PROPERTY);
+
+ String[] packageNames = genericDocument.getPropertyStringArray(PACKAGE_NAME_PROPERTY);
+ byte[][] sha256Certs = genericDocument.getPropertyBytesArray(SHA_256_CERT_PROPERTY);
+ for (int i = 0; i < packageNames.length; ++i) {
+ mPackageIdentifiers.add(new PackageIdentifier(packageNames[i], sha256Certs[i]));
+ }
+
+ GenericDocument[] permissionDocs =
+ genericDocument.getPropertyDocumentArray(PERMISSION_PROPERTY);
+ if (permissionDocs != null) {
+ mPermissionDocuments = new VisibilityPermissionDocument[permissionDocs.length];
+ for (int i = 0; i < permissionDocs.length; ++i) {
+ mPermissionDocuments[i] = new VisibilityPermissionDocument.Builder(
+ permissionDocs[i]).build();
+ }
+ }
+ }
+
+ public Builder(@NonNull VisibilityDocument visibilityDocument) {
+ Objects.requireNonNull(visibilityDocument);
+
+ mIsNotDisplayedBySystem = visibilityDocument.mIsNotDisplayedBySystem;
+ mPermissionDocuments = visibilityDocument.mPermissionDocuments;
+ for (int i = 0; i < visibilityDocument.mPackageNames.length; ++i) {
+ mPackageIdentifiers.add(new PackageIdentifier(visibilityDocument.mPackageNames[i],
+ visibilityDocument.mSha256Certs[i]));
+ }
+ }
+
+ /** Sets id. */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder setId(@NonNull String id) {
+ mId = Objects.requireNonNull(id);
+ return this;
+ }
+
+ /** Sets whether this schema has opted out of platform surfacing. */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder setNotDisplayedBySystem(boolean notDisplayedBySystem) {
+ mIsNotDisplayedBySystem = notDisplayedBySystem;
+ return this;
+ }
+
+ /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder addVisibleToPackages(@NonNull Set<PackageIdentifier> packageIdentifiers) {
+ mPackageIdentifiers.addAll(Objects.requireNonNull(packageIdentifiers));
+ return this;
+ }
+
+ /** Add {@link PackageIdentifier} of packages which has access to this schema. */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder addVisibleToPackage(@NonNull PackageIdentifier packageIdentifier) {
+ mPackageIdentifiers.add(Objects.requireNonNull(packageIdentifier));
+ return this;
+ }
+
+ /**
+ * Sets required permission sets for a package needs to hold to the schema this {@link
+ * VisibilityDocument} represents.
+ *
+ * <p>The querier could have access if they holds ALL required permissions of ANY of the
+ * individual value sets.
+ */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder setVisibleToPermissions(@NonNull Set<Set<Integer>> visibleToPermissions) {
+ Objects.requireNonNull(visibleToPermissions);
+ mPermissionDocuments =
+ new VisibilityPermissionDocument[visibleToPermissions.size()];
+ int i = 0;
+ for (Set<Integer> allRequiredPermissions : visibleToPermissions) {
+ mPermissionDocuments[i++] =
+ new VisibilityPermissionDocument.Builder(
+ NAMESPACE, /*id=*/ String.valueOf(i))
+ .setVisibleToAllRequiredPermissions(allRequiredPermissions)
+ .build();
+ }
+ return this;
+ }
+
+ /** Build a {@link VisibilityDocument} */
+ @NonNull
+ public VisibilityDocument build() {
+ String[] packageNames = new String[mPackageIdentifiers.size()];
+ byte[][] sha256Certs = new byte[mPackageIdentifiers.size()][32];
+ int i = 0;
+ for (PackageIdentifier packageIdentifier : mPackageIdentifiers) {
+ packageNames[i] = packageIdentifier.getPackageName();
+ sha256Certs[i] = packageIdentifier.getSha256Certificate();
+ ++i;
+ }
+ return new VisibilityDocument(mId, mIsNotDisplayedBySystem,
+ packageNames, sha256Certs, mPermissionDocuments);
+ }
+ }
}
+
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
index 80a6a2e..54269fd 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/app/VisibilityPermissionDocument.java
@@ -16,12 +16,19 @@
package androidx.appsearch.app;
+import android.os.Parcel;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.appsearch.annotation.CanIgnoreReturnValue;
+import androidx.appsearch.safeparcel.AbstractSafeParcelable;
+import androidx.appsearch.safeparcel.SafeParcelable;
+import androidx.appsearch.safeparcel.stub.StubCreators.VisibilityPermissionDocumentCreator;
import androidx.collection.ArraySet;
+import java.util.Arrays;
+import java.util.Objects;
import java.util.Set;
/**
@@ -30,7 +37,11 @@
* @exportToFramework:hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
-public class VisibilityPermissionDocument extends GenericDocument {
[email protected](creator = "VisibilityPermissionDocumentCreator")
+public final class VisibilityPermissionDocument extends AbstractSafeParcelable {
+ @NonNull
+ public static final VisibilityPermissionDocumentCreator CREATOR =
+ new VisibilityPermissionDocumentCreator();
/**
* The Schema type for documents that hold AppSearch's metadata, such as visibility settings.
@@ -53,49 +64,79 @@
.build())
.build();
- VisibilityPermissionDocument(@NonNull GenericDocument genericDocument) {
- super(genericDocument);
+ @NonNull
+ @Field(id = 1, getter = "getId")
+ private final String mId;
+
+ @NonNull
+ @Field(id = 2, getter = "getNamespace")
+ private final String mNamespace;
+
+ @Nullable
+ @Field(id = 3, getter = "getAllRequiredPermissionsInts")
+ // SafeParcelable doesn't support Set<Integer>, so we have to convert it to int[].
+ private final int[] mAllRequiredPermissions;
+
+ @Nullable
+ // We still need to convert this class to a GenericDocument until we completely treat it
+ // differently in AppSearchImpl.
+ // TODO(b/298118943) Remove this once internally we don't use GenericDocument to store
+ // visibility information.
+ private GenericDocument mGenericDocument;
+
+ @Nullable
+ private Integer mHashCode;
+
+ @Constructor
+ VisibilityPermissionDocument(
+ @Param(id = 1) @NonNull String id,
+ @Param(id = 2) @NonNull String namespace,
+ @Param(id = 3) @Nullable int[] allRequiredPermissions) {
+ mId = Objects.requireNonNull(id);
+ mNamespace = Objects.requireNonNull(namespace);
+ mAllRequiredPermissions = allRequiredPermissions;
}
/**
- * Returns an array of Android Permissions that caller mush hold to access the schema
- * that the outer {@link VisibilityDocument} represents.
+ * Gets the id for this {@link VisibilityPermissionDocument}.
+ *
+ * <p>This is being used as the document id when we convert a
+ * {@link VisibilityPermissionDocument} to a {@link GenericDocument}.
+ */
+ @NonNull
+ public String getId() {
+ return mId;
+ }
+
+ /**
+ * Gets the namespace for this {@link VisibilityPermissionDocument}.
+ *
+ * <p>This is being used as the namespace when we convert a
+ * {@link VisibilityPermissionDocument} to a {@link GenericDocument}.
+ */
+ @NonNull
+ public String getNamespace() {
+ return mNamespace;
+ }
+
+ /** Gets the required Android Permissions in an int array. */
+ @Nullable
+ int[] getAllRequiredPermissionsInts() {
+ return mAllRequiredPermissions;
+ }
+
+ /**
+ * Returns an array of Android Permissions that caller mush hold to access the schema that the
+ * outer {@link VisibilityDocument} represents.
*/
@Nullable
public Set<Integer> getAllRequiredPermissions() {
- return toInts(getPropertyLongArray(ALL_REQUIRED_PERMISSIONS_PROPERTY));
- }
-
- /** Builder for {@link VisibilityPermissionDocument}. */
- public static class Builder extends GenericDocument.Builder<Builder> {
-
- /**
- * Creates a {@link VisibilityDocument.Builder} for a {@link VisibilityDocument}.
- */
- public Builder(@NonNull String namespace, @NonNull String id) {
- super(namespace, id, SCHEMA_TYPE);
- }
-
- /** Sets whether this schema has opted out of platform surfacing. */
- @CanIgnoreReturnValue
- @NonNull
- public Builder setVisibleToAllRequiredPermissions(
- @NonNull Set<Integer> allRequiredPermissions) {
- setPropertyLong(ALL_REQUIRED_PERMISSIONS_PROPERTY, toLongs(allRequiredPermissions));
- return this;
- }
-
- /** Build a {@link VisibilityPermissionDocument} */
- @Override
- @NonNull
- public VisibilityPermissionDocument build() {
- return new VisibilityPermissionDocument(super.build());
- }
+ return toIntegerSet(mAllRequiredPermissions);
}
@NonNull
- static long[] toLongs(@NonNull Set<Integer> properties) {
- long[] outputs = new long[properties.size()];
+ private static int[] toInts(@NonNull Set<Integer> properties) {
+ int[] outputs = new int[properties.size()];
int i = 0;
for (int property : properties) {
outputs[i++] = property;
@@ -104,14 +145,125 @@
}
@Nullable
- private static Set<Integer> toInts(@Nullable long[] properties) {
+ private static Set<Integer> toIntegerSet(@Nullable int[] properties) {
if (properties == null) {
return null;
}
Set<Integer> outputs = new ArraySet<>(properties.length);
- for (long property : properties) {
- outputs.add((int) property);
+ for (int property : properties) {
+ outputs.add(property);
}
return outputs;
}
+
+ /**
+ * Generates a {@link GenericDocument} from the current class.
+ *
+ * <p>This conversion is needed until we don't treat Visibility related documents as
+ * {@link GenericDocument}s internally.
+ */
+ @NonNull
+ public GenericDocument toGenericDocument() {
+ if (mGenericDocument == null) {
+ GenericDocument.Builder<?> builder = new GenericDocument.Builder<>(
+ mNamespace, mId, SCHEMA_TYPE);
+
+ if (mAllRequiredPermissions != null) {
+ // GenericDocument only supports long, so int[] needs to be converted to
+ // long[] here.
+ long[] longs = new long[mAllRequiredPermissions.length];
+ for (int i = 0; i < mAllRequiredPermissions.length; ++i) {
+ longs[i] = mAllRequiredPermissions[i];
+ }
+ builder.setPropertyLong(ALL_REQUIRED_PERMISSIONS_PROPERTY, longs);
+ }
+
+ mGenericDocument = builder.build();
+ }
+ return mGenericDocument;
+ }
+
+ @Override
+ public int hashCode() {
+ if (mHashCode == null) {
+ mHashCode = Objects.hash(mId, mNamespace, Arrays.hashCode(mAllRequiredPermissions));
+ }
+ return mHashCode;
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof VisibilityPermissionDocument)) {
+ return false;
+ }
+ VisibilityPermissionDocument otherVisibilityPermissionDocument =
+ (VisibilityPermissionDocument) other;
+ return mId.equals(otherVisibilityPermissionDocument.mId)
+ && mNamespace.equals(otherVisibilityPermissionDocument.mNamespace)
+ && Arrays.equals(
+ mAllRequiredPermissions,
+ otherVisibilityPermissionDocument.mAllRequiredPermissions);
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ VisibilityPermissionDocumentCreator.writeToParcel(this, dest, flags);
+ }
+
+ /** Builder for {@link VisibilityPermissionDocument}. */
+ public static final class Builder {
+ private String mId;
+ private String mNamespace;
+ private int[] mAllRequiredPermissions;
+
+ /**
+ * Constructs a {@link VisibilityPermissionDocument} from a {@link GenericDocument}.
+ *
+ * <p>This constructor is still needed until we don't treat Visibility related documents as
+ * {@link GenericDocument}s internally.
+ */
+ public Builder(@NonNull GenericDocument genericDocument) {
+ Objects.requireNonNull(genericDocument);
+ mId = genericDocument.getId();
+ mNamespace = genericDocument.getNamespace();
+ // GenericDocument only supports long[], so we need to convert it back to int[].
+ long[] longs = genericDocument.getPropertyLongArray(
+ ALL_REQUIRED_PERMISSIONS_PROPERTY);
+ if (longs != null) {
+ mAllRequiredPermissions = new int[longs.length];
+ for (int i = 0; i < longs.length; ++i) {
+ mAllRequiredPermissions[i] = (int) longs[i];
+ }
+ }
+ }
+
+ /** Creates a {@link VisibilityDocument.Builder} for a {@link VisibilityDocument}. */
+ public Builder(@NonNull String namespace, @NonNull String id) {
+ mNamespace = Objects.requireNonNull(namespace);
+ mId = Objects.requireNonNull(id);
+ }
+
+ /**
+ * Sets a set of Android Permissions that caller mush hold to access the schema that the
+ * outer {@link VisibilityDocument} represents.
+ */
+ @CanIgnoreReturnValue
+ @NonNull
+ public Builder setVisibleToAllRequiredPermissions(
+ @NonNull Set<Integer> allRequiredPermissions) {
+ mAllRequiredPermissions = toInts(Objects.requireNonNull(allRequiredPermissions));
+ return this;
+ }
+
+ /** Builds a {@link VisibilityPermissionDocument} */
+ @NonNull
+ public VisibilityPermissionDocument build() {
+ return new VisibilityPermissionDocument(mId,
+ mNamespace,
+ mAllRequiredPermissions);
+ }
+ }
}
diff --git a/appsearch/appsearch/src/main/java/androidx/appsearch/safeparcel/stub/StubCreators.java b/appsearch/appsearch/src/main/java/androidx/appsearch/safeparcel/stub/StubCreators.java
index c4f9241..b60c9e4 100644
--- a/appsearch/appsearch/src/main/java/androidx/appsearch/safeparcel/stub/StubCreators.java
+++ b/appsearch/appsearch/src/main/java/androidx/appsearch/safeparcel/stub/StubCreators.java
@@ -74,4 +74,12 @@
/** Stub creator for {@link GenericDocumentParcel}. */
public static class GenericDocumentParcelCreator extends AbstractCreator {
}
+
+ /** Stub creator for {@link androidx.appsearch.app.VisibilityPermissionDocument}. */
+ public static class VisibilityPermissionDocumentCreator extends AbstractCreator {
+ }
+
+ /** Stub creator for {@link androidx.appsearch.app.VisibilityDocument}. */
+ public static class VisibilityDocumentCreator extends AbstractCreator {
+ }
}