Home | History | Annotate | Download | only in pm
      1 /*
      2  * Copyright (C) 2011 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 com.android.server.pm;
     18 
     19 import com.android.server.pm.PackageManagerService.InstallArgs;
     20 
     21 import android.content.pm.PackageManager;
     22 import android.util.SparseBooleanArray;
     23 
     24 /**
     25  * Tracks the package verification state for a particular package. Each package
     26  * verification has a required verifier and zero or more sufficient verifiers.
     27  * Only one of the sufficient verifier list must return affirmative to allow the
     28  * package to be considered verified. If there are zero sufficient verifiers,
     29  * then package verification is considered complete.
     30  */
     31 class PackageVerificationState {
     32     private final InstallArgs mArgs;
     33 
     34     private final SparseBooleanArray mSufficientVerifierUids;
     35 
     36     private final int mRequiredVerifierUid;
     37 
     38     private boolean mSufficientVerificationComplete;
     39 
     40     private boolean mSufficientVerificationPassed;
     41 
     42     private boolean mRequiredVerificationComplete;
     43 
     44     private boolean mRequiredVerificationPassed;
     45 
     46     /**
     47      * Create a new package verification state where {@code requiredVerifierUid}
     48      * is the user ID for the package that must reply affirmative before things
     49      * can continue.
     50      *
     51      * @param requiredVerifierUid user ID of required package verifier
     52      * @param args
     53      */
     54     public PackageVerificationState(int requiredVerifierUid, InstallArgs args) {
     55         mRequiredVerifierUid = requiredVerifierUid;
     56         mArgs = args;
     57         mSufficientVerifierUids = new SparseBooleanArray();
     58     }
     59 
     60     public InstallArgs getInstallArgs() {
     61         return mArgs;
     62     }
     63 
     64     /**
     65      * Add a verifier which is added to our sufficient list.
     66      *
     67      * @param uid user ID of sufficient verifier
     68      */
     69     public void addSufficientVerifier(int uid) {
     70         mSufficientVerifierUids.put(uid, true);
     71     }
     72 
     73     /**
     74      * Should be called when a verification is received from an agent so the
     75      * state of the package verification can be tracked.
     76      *
     77      * @param uid user ID of the verifying agent
     78      * @return {@code true} if the verifying agent actually exists in our list
     79      */
     80     public boolean setVerifierResponse(int uid, int code) {
     81         if (uid == mRequiredVerifierUid) {
     82             mRequiredVerificationComplete = true;
     83             switch (code) {
     84                 case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT:
     85                     mSufficientVerifierUids.clear();
     86                     // fall through
     87                 case PackageManager.VERIFICATION_ALLOW:
     88                     mRequiredVerificationPassed = true;
     89                     break;
     90                 default:
     91                     mRequiredVerificationPassed = false;
     92             }
     93             return true;
     94         } else {
     95             if (mSufficientVerifierUids.get(uid)) {
     96                 if (code == PackageManager.VERIFICATION_ALLOW) {
     97                     mSufficientVerificationComplete = true;
     98                     mSufficientVerificationPassed = true;
     99                 }
    100 
    101                 mSufficientVerifierUids.delete(uid);
    102                 if (mSufficientVerifierUids.size() == 0) {
    103                     mSufficientVerificationComplete = true;
    104                 }
    105 
    106                 return true;
    107             }
    108         }
    109 
    110         return false;
    111     }
    112 
    113     /**
    114      * Returns whether verification is considered complete. This means that the
    115      * required verifier and at least one of the sufficient verifiers has
    116      * returned a positive verification.
    117      *
    118      * @return {@code true} when verification is considered complete
    119      */
    120     public boolean isVerificationComplete() {
    121         if (!mRequiredVerificationComplete) {
    122             return false;
    123         }
    124 
    125         if (mSufficientVerifierUids.size() == 0) {
    126             return true;
    127         }
    128 
    129         return mSufficientVerificationComplete;
    130     }
    131 
    132     /**
    133      * Returns whether installation should be allowed. This should only be
    134      * called after {@link #isVerificationComplete()} returns {@code true}.
    135      *
    136      * @return {@code true} if installation should be allowed
    137      */
    138     public boolean isInstallAllowed() {
    139         if (!mRequiredVerificationPassed) {
    140             return false;
    141         }
    142 
    143         if (mSufficientVerificationComplete) {
    144             return mSufficientVerificationPassed;
    145         }
    146 
    147         return true;
    148     }
    149 }
    150