1 /*
2  * Copyright (C) 2018 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.content.pm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.List;
27 import java.util.Objects;
28 
29 /**
30  * Information you can retrieve about a particular system
31  * module.
32  */
33 public final class ModuleInfo implements Parcelable {
34 
35      // NOTE: When adding new data members be sure to update the copy-constructor, Parcel
36      // constructor, and writeToParcel.
37 
38     /** Public name of this module. */
39     private CharSequence mName;
40 
41     /** The package name of this module. */
42     private String mPackageName;
43 
44     /**
45      * The name of the APEX this module is distributed as, or null if it is not distributed via
46      * APEX.
47      */
48     @Nullable private String mApexModuleName;
49 
50     /** Whether or not this module is hidden from the user. */
51     private boolean mHidden;
52 
53     /**
54      * The list of the package names of all APK-in-APEX apps in the module, or
55      * null if there are none.
56      */
57     @Nullable
58     private List<String> mApkInApexPackageNames;
59 
60     // TODO: Decide whether we need an additional metadata bundle to support out of band
61     // updates to ModuleInfo.
62     //
63     // private Bundle mMetadata;
64 
65     /** @hide */
ModuleInfo()66     public ModuleInfo() {
67     }
68 
69     /** @hide */
ModuleInfo(ModuleInfo orig)70     public ModuleInfo(ModuleInfo orig) {
71         mName = orig.mName;
72         mPackageName = orig.mPackageName;
73         mHidden = orig.mHidden;
74         mApexModuleName = orig.mApexModuleName;
75         if (orig.mApkInApexPackageNames != null) {
76             mApkInApexPackageNames = List.copyOf(orig.mApkInApexPackageNames);
77         }
78     }
79 
80     /** @hide Sets the public name of this module. */
setName(CharSequence name)81     public ModuleInfo setName(CharSequence name) {
82         mName = name;
83         return this;
84     }
85 
86     /** Gets the public name of this module. */
getName()87     public @Nullable CharSequence getName() {
88         return mName;
89     }
90 
91     /** @hide Sets the package name of this module. */
setPackageName(String packageName)92     public ModuleInfo setPackageName(String packageName) {
93         mPackageName = packageName;
94         return this;
95     }
96 
97     /** Gets the package name of this module. */
getPackageName()98     public @Nullable String getPackageName() {
99         return mPackageName;
100     }
101 
102     /** @hide Sets whether or not this package is hidden. */
setHidden(boolean hidden)103     public ModuleInfo setHidden(boolean hidden) {
104         mHidden = hidden;
105         return this;
106     }
107 
108     /** Gets whether or not this package is hidden. */
isHidden()109     public boolean isHidden() {
110         return mHidden;
111     }
112 
113     /** @hide Sets the apex module name. */
setApexModuleName(@ullable String apexModuleName)114     public ModuleInfo setApexModuleName(@Nullable String apexModuleName) {
115         mApexModuleName = apexModuleName;
116         return this;
117     }
118 
119     /** @hide Gets the apex module name. */
getApexModuleName()120     public @Nullable String getApexModuleName() {
121         return mApexModuleName;
122     }
123 
124     /** @hide Set the list of the package names of all APK-in-APEX apps in this module. */
setApkInApexPackageNames(@onNull Collection<String> apkInApexPackageNames)125     public ModuleInfo setApkInApexPackageNames(@NonNull Collection<String> apkInApexPackageNames) {
126         Objects.requireNonNull(apkInApexPackageNames);
127         mApkInApexPackageNames = List.copyOf(apkInApexPackageNames);
128         return this;
129     }
130 
131     /** @hide Get the list of the package names of all APK-in-APEX apps in the module. */
132     @NonNull
getApkInApexPackageNames()133     public Collection<String> getApkInApexPackageNames() {
134         if (mApkInApexPackageNames == null) {
135             return Collections.emptyList();
136         }
137         return mApkInApexPackageNames;
138     }
139 
140     /** Returns a string representation of this object. */
toString()141     public String toString() {
142         return "ModuleInfo{"
143             + Integer.toHexString(System.identityHashCode(this))
144             + " " + mName + "}";
145     }
146 
147     /** Describes the kinds of special objects contained in this object. */
describeContents()148     public int describeContents() {
149         return 0;
150     }
151 
152     @Override
hashCode()153     public int hashCode() {
154         int hashCode = 0;
155         hashCode = 31 * hashCode + Objects.hashCode(mName);
156         hashCode = 31 * hashCode + Objects.hashCode(mPackageName);
157         hashCode = 31 * hashCode + Objects.hashCode(mApexModuleName);
158         hashCode = 31 * hashCode + Objects.hashCode(mApkInApexPackageNames);
159         hashCode = 31 * hashCode + Boolean.hashCode(mHidden);
160         return hashCode;
161     }
162 
163     @Override
equals(@ullable Object obj)164     public boolean equals(@Nullable Object obj) {
165         if (!(obj instanceof ModuleInfo)) {
166             return false;
167         }
168         final ModuleInfo other = (ModuleInfo) obj;
169         return Objects.equals(mName, other.mName)
170                 && Objects.equals(mPackageName, other.mPackageName)
171                 && Objects.equals(mApexModuleName, other.mApexModuleName)
172                 && Objects.equals(mApkInApexPackageNames, other.mApkInApexPackageNames)
173                 && mHidden == other.mHidden;
174     }
175 
176     /** Flattens this object into the given {@link Parcel}. */
writeToParcel(Parcel dest, int parcelableFlags)177     public void writeToParcel(Parcel dest, int parcelableFlags) {
178         dest.writeCharSequence(mName);
179         dest.writeString(mPackageName);
180         dest.writeBoolean(mHidden);
181         dest.writeString(mApexModuleName);
182         // Parcel#writeStringList handles null case, we can use it directly
183         dest.writeStringList(mApkInApexPackageNames);
184     }
185 
ModuleInfo(Parcel source)186     private ModuleInfo(Parcel source) {
187         mName = source.readCharSequence();
188         mPackageName = source.readString();
189         mHidden = source.readBoolean();
190         mApexModuleName = source.readString();
191         mApkInApexPackageNames = source.createStringArrayList();
192     }
193 
194     public static final @android.annotation.NonNull Parcelable.Creator<ModuleInfo> CREATOR =
195             new Parcelable.Creator<ModuleInfo>() {
196         public ModuleInfo createFromParcel(Parcel source) {
197             return new ModuleInfo(source);
198         }
199         public ModuleInfo[] newArray(int size) {
200             return new ModuleInfo[size];
201         }
202     };
203 }
204