• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app.appsearch;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.appsearch.util.BundleUtil;
22 import android.os.Bundle;
23 
24 import java.util.Objects;
25 
26 /** This class represents a uniquely identifiable package. */
27 public class PackageIdentifier {
28     private static final String PACKAGE_NAME_FIELD = "packageName";
29     private static final String SHA256_CERTIFICATE_FIELD = "sha256Certificate";
30 
31     private final Bundle mBundle;
32 
33     /**
34      * Creates a unique identifier for a package.
35      *
36      * <p>SHA-256 certificate digests for a signed application can be retrieved with the <a
37      * href="{@docRoot}studio/command-line/apksigner/">apksigner tool</a> that is part of the
38      * Android SDK build tools. Use {@code apksigner verify --print-certs path/to/apk.apk} to
39      * retrieve the SHA-256 certificate digest for the target application. Once retrieved, the
40      * SHA-256 certificate digest should be converted to a {@code byte[]} by decoding it in base16:
41      *
42      * <pre>
43      * new android.content.pm.Signature(outputDigest).toByteArray();
44      * </pre>
45      *
46      * @param packageName Name of the package.
47      * @param sha256Certificate SHA-256 certificate digest of the package.
48      */
PackageIdentifier(@onNull String packageName, @NonNull byte[] sha256Certificate)49     public PackageIdentifier(@NonNull String packageName, @NonNull byte[] sha256Certificate) {
50         mBundle = new Bundle();
51         mBundle.putString(PACKAGE_NAME_FIELD, packageName);
52         mBundle.putByteArray(SHA256_CERTIFICATE_FIELD, sha256Certificate);
53     }
54 
55     /** @hide */
PackageIdentifier(@onNull Bundle bundle)56     public PackageIdentifier(@NonNull Bundle bundle) {
57         mBundle = Objects.requireNonNull(bundle);
58     }
59 
60     /** @hide */
61     @NonNull
getBundle()62     public Bundle getBundle() {
63         return mBundle;
64     }
65 
66     @NonNull
getPackageName()67     public String getPackageName() {
68         return Objects.requireNonNull(mBundle.getString(PACKAGE_NAME_FIELD));
69     }
70 
71     @NonNull
getSha256Certificate()72     public byte[] getSha256Certificate() {
73         return Objects.requireNonNull(mBundle.getByteArray(SHA256_CERTIFICATE_FIELD));
74     }
75 
76     @Override
equals(@ullable Object obj)77     public boolean equals(@Nullable Object obj) {
78         if (this == obj) {
79             return true;
80         }
81         if (obj == null || !(obj instanceof PackageIdentifier)) {
82             return false;
83         }
84         final PackageIdentifier other = (PackageIdentifier) obj;
85         return BundleUtil.deepEquals(mBundle, other.mBundle);
86     }
87 
88     @Override
hashCode()89     public int hashCode() {
90         return BundleUtil.deepHashCode(mBundle);
91     }
92 }
93