Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2015 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 package android.car.content.pm;
     17 
     18 import android.annotation.IntDef;
     19 import android.annotation.Nullable;
     20 import android.annotation.SystemApi;
     21 import android.content.pm.Signature;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 
     25 import java.lang.annotation.Retention;
     26 import java.lang.annotation.RetentionPolicy;
     27 import java.util.Arrays;
     28 
     29 /**
     30  * Parcelable to hold information on app blocking whitelist or blacklist for a package.
     31  * @hide
     32  */
     33 @SystemApi
     34 public class AppBlockingPackageInfo implements Parcelable {
     35 
     36     /** Package name for the package to block or allow. */
     37     public final String packageName;
     38 
     39     /** Represents system app which does not need {@link #signature}. */
     40     public static final int FLAG_SYSTEM_APP = 0x1;
     41     /** Blacklist or whitelist every Activities in the package. When this is set,
     42      *  {@link #activities} may be null. */
     43     public static final int FLAG_WHOLE_ACTIVITY = 0x2;
     44     /** @hide */
     45     @IntDef(flag = true,
     46             value = {FLAG_SYSTEM_APP, FLAG_WHOLE_ACTIVITY})
     47     @Retention(RetentionPolicy.SOURCE)
     48     public @interface ConstrcutorFlags {}
     49 
     50     /**
     51      * flags to give additional information on the package.
     52      * @see #FLAG_SYSTEM_APP
     53      * @see #FLAG_WHOLE_ACTIVITY
     54      */
     55     public final int flags;
     56 
     57     /**
     58      * Package version should be bigger than this to block or allow.
     59      * (package version > minRevisionCode)
     60      * 0 means do not care min version.
     61      */
     62     public final int minRevisionCode;
     63 
     64     /**
     65      * Package version should be smaller than this to block or allow.
     66      * (package version < minRevisionCode)
     67      * 0 means do not care max version.
     68      */
     69     public final int maxRevisionCode;
     70 
     71     /**
     72      * Signature of package. This can be null if target package is from system so that package
     73      * name is enough to uniquely identify it (= {@link #flags} having {@link #FLAG_SYSTEM_APP}.
     74      * Matching any member of array is considered as matching package.
     75      */
     76     public final Signature[] signatures;
     77 
     78     /** List of activities (full class name). This can be null if Activity is not blocked or
     79      *  allowed. Additionally, {@link #FLAG_WHOLE_ACTIVITY} set in {@link #flags} shall have
     80      *  null for this. */
     81     public final String[] activities;
     82 
     83 
     84     public AppBlockingPackageInfo(String packageName, int minRevisionCode, int maxRevisionCode,
     85             @ConstrcutorFlags int flags, @Nullable Signature[] signatures,
     86             @Nullable String[] activities) {
     87         if (packageName == null) {
     88             throw new IllegalArgumentException("packageName cannot be null");
     89         }
     90         this.packageName = packageName;
     91         this.flags = flags;
     92         this.minRevisionCode = minRevisionCode;
     93         this.maxRevisionCode = maxRevisionCode;
     94         this.signatures = signatures;
     95         this.activities = activities;
     96         verify();
     97     }
     98 
     99     public AppBlockingPackageInfo(Parcel in) {
    100         packageName = in.readString();
    101         flags = in.readInt();
    102         minRevisionCode= in.readInt();
    103         maxRevisionCode = in.readInt();
    104         signatures = in.createTypedArray(Signature.CREATOR);
    105         activities = in.createStringArray();
    106         verify();
    107     }
    108 
    109     @Override
    110     public int describeContents() {
    111         return 0;
    112     }
    113 
    114     @Override
    115     public void writeToParcel(Parcel dest, int flags) {
    116         dest.writeString(packageName);
    117         dest.writeInt(this.flags);
    118         dest.writeInt(minRevisionCode);
    119         dest.writeInt(maxRevisionCode);
    120         dest.writeTypedArray(signatures, 0);
    121         dest.writeStringArray(activities);
    122     }
    123 
    124     public static final Parcelable.Creator<AppBlockingPackageInfo> CREATOR
    125             = new Parcelable.Creator<AppBlockingPackageInfo>() {
    126         public AppBlockingPackageInfo createFromParcel(Parcel in) {
    127             return new AppBlockingPackageInfo(in);
    128         }
    129 
    130         public AppBlockingPackageInfo[] newArray(int size) {
    131             return new AppBlockingPackageInfo[size];
    132         }
    133     };
    134 
    135     /** @hide */
    136     public void verify() throws IllegalArgumentException {
    137         if (signatures == null && (flags & FLAG_SYSTEM_APP) == 0) {
    138             throw new IllegalArgumentException(
    139                     "Only system package with FLAG_SYSTEM_APP can have null signatures");
    140         }
    141     }
    142 
    143     /** @hide */
    144     public boolean isActivityCovered(String className) {
    145         if ((flags & FLAG_WHOLE_ACTIVITY) != 0) {
    146             return true;
    147         }
    148         if (activities == null) {
    149             return false;
    150         }
    151         for (String activityName : activities) {
    152             if (activityName.equals(className)) {
    153                 return true;
    154             }
    155         }
    156         return false;
    157     }
    158 
    159 
    160 
    161     @Override
    162     public int hashCode() {
    163         final int prime = 31;
    164         int result = 1;
    165         result = prime * result + Arrays.hashCode(activities);
    166         result = prime * result + flags;
    167         result = prime * result + maxRevisionCode;
    168         result = prime * result + minRevisionCode;
    169         result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
    170         result = prime * result + Arrays.hashCode(signatures);
    171         return result;
    172     }
    173 
    174     @Override
    175     public boolean equals(Object obj) {
    176         if (this == obj) {
    177             return true;
    178         }
    179         if (obj == null) {
    180             return false;
    181         }
    182         if (getClass() != obj.getClass()) {
    183             return false;
    184         }
    185         AppBlockingPackageInfo other = (AppBlockingPackageInfo) obj;
    186         if (!Arrays.equals(activities, other.activities)) {
    187             return false;
    188         }
    189         if (flags != other.flags) {
    190             return false;
    191         }
    192         if (maxRevisionCode != other.maxRevisionCode) {
    193             return false;
    194         }
    195         if (minRevisionCode != other.minRevisionCode) {
    196             return false;
    197         }
    198         if (packageName == null) {
    199             if (other.packageName != null)
    200                 return false;
    201         } else if (!packageName.equals(other.packageName))
    202             return false;
    203         if (!Arrays.equals(signatures, other.signatures)) {
    204             return false;
    205         }
    206         return true;
    207     }
    208 
    209     @Override
    210     public String toString() {
    211         return "AppBlockingPackageInfo [packageName=" + packageName + ", flags=" + flags
    212                 + ", minRevisionCode=" + minRevisionCode + ", maxRevisionCode=" + maxRevisionCode
    213                 + ", signatures=" + Arrays.toString(signatures) + ", activities="
    214                 + Arrays.toString(activities) + "]";
    215     }
    216 }
    217