/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

import android.content.pm.PackageManager;
import android.util.SparseBooleanArray;

import com.android.server.pm.PackageManagerService.InstallParams;

/**
 * Tracks the package verification state for a particular package. Each package
 * verification has a required verifier and zero or more sufficient verifiers.
 * Only one of the sufficient verifier list must return affirmative to allow the
 * package to be considered verified. If there are zero sufficient verifiers,
 * then package verification is considered complete.
 */
class PackageVerificationState {
    private final InstallParams mParams;

    private final SparseBooleanArray mSufficientVerifierUids;

    private final int mRequiredVerifierUid;

    private boolean mSufficientVerificationComplete;

    private boolean mSufficientVerificationPassed;

    private boolean mRequiredVerificationComplete;

    private boolean mRequiredVerificationPassed;

    private boolean mExtendedTimeout;

    /**
     * Create a new package verification state where {@code requiredVerifierUid}
     * is the user ID for the package that must reply affirmative before things
     * can continue.
     *
     * @param requiredVerifierUid user ID of required package verifier
     * @param args
     */
    PackageVerificationState(int requiredVerifierUid, InstallParams params) {
        mRequiredVerifierUid = requiredVerifierUid;
        mParams = params;
        mSufficientVerifierUids = new SparseBooleanArray();
        mExtendedTimeout = false;
    }

    InstallParams getInstallParams() {
        return mParams;
    }

    /**
     * Add a verifier which is added to our sufficient list.
     *
     * @param uid user ID of sufficient verifier
     */
    void addSufficientVerifier(int uid) {
        mSufficientVerifierUids.put(uid, true);
    }

    /**
     * Should be called when a verification is received from an agent so the
     * state of the package verification can be tracked.
     *
     * @param uid user ID of the verifying agent
     * @return {@code true} if the verifying agent actually exists in our list
     */
    boolean setVerifierResponse(int uid, int code) {
        if (uid == mRequiredVerifierUid) {
            mRequiredVerificationComplete = true;
            switch (code) {
                case PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT:
                    mSufficientVerifierUids.clear();
                    // fall through
                case PackageManager.VERIFICATION_ALLOW:
                    mRequiredVerificationPassed = true;
                    break;
                default:
                    mRequiredVerificationPassed = false;
            }
            return true;
        } else {
            if (mSufficientVerifierUids.get(uid)) {
                if (code == PackageManager.VERIFICATION_ALLOW) {
                    mSufficientVerificationComplete = true;
                    mSufficientVerificationPassed = true;
                }

                mSufficientVerifierUids.delete(uid);
                if (mSufficientVerifierUids.size() == 0) {
                    mSufficientVerificationComplete = true;
                }

                return true;
            }
        }

        return false;
    }

    /**
     * Returns whether verification is considered complete. This means that the
     * required verifier and at least one of the sufficient verifiers has
     * returned a positive verification.
     *
     * @return {@code true} when verification is considered complete
     */
    boolean isVerificationComplete() {
        if (!mRequiredVerificationComplete) {
            return false;
        }

        if (mSufficientVerifierUids.size() == 0) {
            return true;
        }

        return mSufficientVerificationComplete;
    }

    /**
     * Returns whether installation should be allowed. This should only be
     * called after {@link #isVerificationComplete()} returns {@code true}.
     *
     * @return {@code true} if installation should be allowed
     */
    boolean isInstallAllowed() {
        if (!mRequiredVerificationPassed) {
            return false;
        }

        if (mSufficientVerificationComplete) {
            return mSufficientVerificationPassed;
        }

        return true;
    }

    /**
     * Extend the timeout for this Package to be verified.
     */
    void extendTimeout() {
        if (!mExtendedTimeout) {
            mExtendedTimeout = true;
        }
    }

    /**
     * Returns whether the timeout was extended for verification.
     *
     * @return {@code true} if a timeout was already extended.
     */
    boolean timeoutExtended() {
        return mExtendedTimeout;
    }
}
