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     private boolean mExtendedTimeout;
     47 
     48     /**
     49      * Create a new package verification state where {@code requiredVerifierUid}
     50      * is the user ID for the package that must reply affirmative before things
     51      * can continue.
     52      *
     53      * @param requiredVerifierUid user ID of required package verifier
     54      * @param args
     55      */
     56     public PackageVerificationState(int requiredVerifierUid, InstallArgs args) {
     57         mRequiredVerifierUid = requiredVerifierUid;
     58         mArgs = args;
     59         mSufficientVerifierUids = new SparseBooleanArray();
     60         mExtendedTimeout = false;
     61     }
     62 
     63     public InstallArgs getInstallArgs() {
     64         return mArgs;
     65     }
     66 
     67     /**
     68      * Add a verifier which is added to our sufficient list.
     69      *
     70      * @param uid user ID of sufficient verifier
     71      */
     72     public void addSufficientVerifier(int uid) {
     73         mSufficientVerifierUids.put(uid, true);
     74     }
     75 
     76     /**
     77      * Should be called when a verification is received from an agent so the
     78      * state of the package verification can be tracked.
     79      *
     80      * @param uid user ID of the verifying agent
     81      * @return {@code true} if the verifying agent actually exists in our list
     82      */
     83     public boolean setVerifierResponse(int uid, int code) {
     84         if (uid == mRequiredVerifierUid) {
     85             mRequiredVerificationComplete = true;
     86             switch (code) {
     87                 case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT:
     88                     mSufficientVerifierUids.clear();
     89                     // fall through
     90                 case PackageManager.VERIFICATION_ALLOW:
     91                     mRequiredVerificationPassed = true;
     92                     break;
     93                 default:
     94                     mRequiredVerificationPassed = false;
     95             }
     96             return true;
     97         } else {
     98             if (mSufficientVerifierUids.get(uid)) {
     99                 if (code == PackageManager.VERIFICATION_ALLOW) {
    100                     mSufficientVerificationComplete = true;
    101                     mSufficientVerificationPassed = true;
    102                 }
    103 
    104                 mSufficientVerifierUids.delete(uid);
    105                 if (mSufficientVerifierUids.size() == 0) {
    106                     mSufficientVerificationComplete = true;
    107                 }
    108 
    109                 return true;
    110             }
    111         }
    112 
    113         return false;
    114     }
    115 
    116     /**
    117      * Returns whether verification is considered complete. This means that the
    118      * required verifier and at least one of the sufficient verifiers has
    119      * returned a positive verification.
    120      *
    121      * @return {@code true} when verification is considered complete
    122      */
    123     public boolean isVerificationComplete() {
    124         if (!mRequiredVerificationComplete) {
    125             return false;
    126         }
    127 
    128         if (mSufficientVerifierUids.size() == 0) {
    129             return true;
    130         }
    131 
    132         return mSufficientVerificationComplete;
    133     }
    134 
    135     /**
    136      * Returns whether installation should be allowed. This should only be
    137      * called after {@link #isVerificationComplete()} returns {@code true}.
    138      *
    139      * @return {@code true} if installation should be allowed
    140      */
    141     public boolean isInstallAllowed() {
    142         if (!mRequiredVerificationPassed) {
    143             return false;
    144         }
    145 
    146         if (mSufficientVerificationComplete) {
    147             return mSufficientVerificationPassed;
    148         }
    149 
    150         return true;
    151     }
    152 
    153     /**
    154      * Extend the timeout for this Package to be verified.
    155      */
    156     public void extendTimeout() {
    157         if (!mExtendedTimeout) {
    158             mExtendedTimeout = true;
    159         }
    160     }
    161 
    162     /**
    163      * Returns whether the timeout was extended for verification.
    164      *
    165      * @return {@code true} if a timeout was already extended.
    166      */
    167     public boolean timeoutExtended() {
    168         return mExtendedTimeout;
    169     }
    170 }
    171