/*
 * Copyright (C) 2017 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.timezone;

import com.android.internal.annotations.VisibleForTesting;

import android.app.timezone.RulesUpdaterContract;
import android.content.Context;
import android.content.pm.PackageManager;
import android.provider.TimeZoneRulesDataContract;
import android.util.Slog;

/**
 * Monitors the installed applications associated with time zone updates. If the app packages are
 * updated it indicates there <em>might</em> be a time zone rules update to apply so a targeted
 * broadcast intent is used to trigger the time zone updater app.
 *
 * <p>The "update triggering" behavior of this component can be disabled via device configuration.
 *
 * <p>The package tracker listens for package updates of the time zone "updater app" and "data app".
 * It also listens for "reliability" triggers. Reliability triggers are there to ensure that the
 * package tracker handles failures reliably and are "idle maintenance" events or something similar.
 * Reliability triggers can cause a time zone update check to take place if the current state is
 * unclear. For example, it can be unclear after boot or after a failure. If there are repeated
 * failures reliability updates are halted until the next boot.
 *
 * <p>This component keeps persistent track of the most recent app packages checked to avoid
 * unnecessary expense from broadcasting intents (which will cause other app processes to spawn).
 * The current status is also stored to detect whether the most recently-generated check is
 * complete successfully. For example, if the device was interrupted while doing a check and never
 * acknowledged a check then a check will be retried the next time a "reliability trigger" event
 * happens.
 */
// Also made non-final so it can be mocked.
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class PackageTracker implements IntentHelper.Listener {
    private static final String TAG = "timezone.PackageTracker";

    private final PackageManagerHelper mPackageManagerHelper;
    private final IntentHelper mIntentHelper;
    private final ConfigHelper mConfigHelper;
    private final PackageStatusStorage mPackageStatusStorage;
    private final ClockHelper mClockHelper;

    // False if tracking is disabled.
    private boolean mTrackingEnabled;

    // These fields may be null if package tracking is disabled.
    private String mUpdateAppPackageName;
    private String mDataAppPackageName;

    // The time a triggered check is allowed to take before it is considered overdue.
    private int mCheckTimeAllowedMillis;
    // The number of failed checks in a row before reliability checks should stop happening.
    private long mFailedCheckRetryCount;

    // Reliability check state: If a check was triggered but not acknowledged within
    // mCheckTimeAllowedMillis then another one can be triggered.
    private Long mLastTriggerTimestamp = null;

    // Reliability check state: Whether any checks have been triggered at all.
    private boolean mCheckTriggered;

    // Reliability check state: A count of how many failures have occurred consecutively.
    private int mCheckFailureCount;

    /** Creates the {@link PackageTracker} for normal use. */
    static PackageTracker create(Context context) {
        PackageTrackerHelperImpl helperImpl = new PackageTrackerHelperImpl(context);
        return new PackageTracker(
                helperImpl /* clock */,
                helperImpl /* configHelper */,
                helperImpl /* packageManagerHelper */,
                new PackageStatusStorage(context),
                new IntentHelperImpl(context));
    }

    // A constructor that can be used by tests to supply mocked / faked dependencies.
    PackageTracker(ClockHelper clockHelper, ConfigHelper configHelper,
            PackageManagerHelper packageManagerHelper, PackageStatusStorage packageStatusStorage,
            IntentHelper intentHelper) {
        mClockHelper = clockHelper;
        mConfigHelper = configHelper;
        mPackageManagerHelper = packageManagerHelper;
        mPackageStatusStorage = packageStatusStorage;
        mIntentHelper = intentHelper;
    }

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected synchronized void start() {
        mTrackingEnabled = mConfigHelper.isTrackingEnabled();
        if (!mTrackingEnabled) {
            Slog.i(TAG, "Time zone updater / data package tracking explicitly disabled.");
            return;
        }

        mUpdateAppPackageName = mConfigHelper.getUpdateAppPackageName();
        mDataAppPackageName = mConfigHelper.getDataAppPackageName();
        mCheckTimeAllowedMillis = mConfigHelper.getCheckTimeAllowedMillis();
        mFailedCheckRetryCount = mConfigHelper.getFailedCheckRetryCount();

        // Validate the device configuration including the application packages.
        // The manifest entries in the apps themselves are not validated until use as they can
        // change and we don't want to prevent the system server starting due to a bad application.
        throwIfDeviceSettingsOrAppsAreBad();

        // Explicitly start in a reliability state where reliability triggering will do something.
        mCheckTriggered = false;
        mCheckFailureCount = 0;

        // Initialize the intent helper.
        mIntentHelper.initialize(mUpdateAppPackageName, mDataAppPackageName, this);

        // Enable the reliability triggering so we will have at least one reliability trigger if
        // a package isn't updated.
        mIntentHelper.enableReliabilityTriggering();

        Slog.i(TAG, "Time zone updater / data package tracking enabled");
    }

    /**
     * Performs checks that confirm the system image has correctly configured package
     * tracking configuration. Only called if package tracking is enabled. Throws an exception if
     * the device is configured badly which will prevent the device booting.
     */
    private void throwIfDeviceSettingsOrAppsAreBad() {
        // None of the checks below can be based on application manifest settings, otherwise a bad
        // update could leave the device in an unbootable state. See validateDataAppManifest() and
        // validateUpdaterAppManifest() for softer errors.

        throwRuntimeExceptionIfNullOrEmpty(
                mUpdateAppPackageName, "Update app package name missing.");
        throwRuntimeExceptionIfNullOrEmpty(mDataAppPackageName, "Data app package name missing.");
        if (mFailedCheckRetryCount < 1) {
            throw logAndThrowRuntimeException("mFailedRetryCount=" + mFailedCheckRetryCount, null);
        }
        if (mCheckTimeAllowedMillis < 1000) {
            throw logAndThrowRuntimeException(
                    "mCheckTimeAllowedMillis=" + mCheckTimeAllowedMillis, null);
        }

        // Validate the updater application package.
        // TODO(nfuller) Uncomment or remove the code below. Currently an app stops being a priv-app
        // after it is replaced by one in data so this check fails. http://b/35995024
        // try {
        //     if (!mPackageManagerHelper.isPrivilegedApp(mUpdateAppPackageName)) {
        //         throw failWithException(
        //                 "Update app " + mUpdateAppPackageName + " must be a priv-app.", null);
        //     }
        // } catch (PackageManager.NameNotFoundException e) {
        //     throw failWithException("Could not determine update app package details for "
        //             + mUpdateAppPackageName, e);
        // }
        // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
        // obtained by the system version it's not clear how to check them.
        Slog.d(TAG, "Update app " + mUpdateAppPackageName + " is valid.");

        // Validate the data application package.
        // TODO(nfuller) Uncomment or remove the code below. Currently an app stops being a priv-app
        // after it is replaced by one in data. http://b/35995024
        // try {
        //     if (!mPackageManagerHelper.isPrivilegedApp(mDataAppPackageName)) {
        //         throw failWithException(
        //                 "Data app " + mDataAppPackageName + " must be a priv-app.", null);
        //     }
        // } catch (PackageManager.NameNotFoundException e) {
        //     throw failWithException("Could not determine data app package details for "
        //             + mDataAppPackageName, e);
        // }
        // TODO(nfuller) Consider permission checks. While an updated system app retains permissions
        // obtained by the system version it's not clear how to check them.
        Slog.d(TAG, "Data app " + mDataAppPackageName + " is valid.");
    }

    /**
     * Inspects the current in-memory state, installed packages and storage state to determine if an
     * update check is needed and then trigger if it is.
     *
     * @param packageChanged true if this method was called because a known packaged definitely
     *     changed, false if the cause is a reliability trigger
     */
    @Override
    public synchronized void triggerUpdateIfNeeded(boolean packageChanged) {
        if (!mTrackingEnabled) {
            throw new IllegalStateException("Unexpected call. Tracking is disabled.");
        }

        // Validate the applications' current manifest entries: make sure they are configured as
        // they should be. These are not fatal and just means that no update is triggered: we don't
        // want to take down the system server if an OEM or Google have pushed a bad update to
        // an application.
        boolean updaterAppManifestValid = validateUpdaterAppManifest();
        boolean dataAppManifestValid = validateDataAppManifest();
        if (!updaterAppManifestValid || !dataAppManifestValid) {
            Slog.e(TAG, "No update triggered due to invalid application manifest entries."
                    + " updaterApp=" + updaterAppManifestValid
                    + ", dataApp=" + dataAppManifestValid);

            // There's no point in doing reliability checks if the current packages are bad.
            mIntentHelper.disableReliabilityTriggering();
            return;
        }

        if (!packageChanged) {
            // This call was made because the device is doing a "reliability" check.
            // 4 possible cases:
            // 1) No check has previously triggered since restart. We want to trigger in this case.
            // 2) A check has previously triggered and it is in progress. We want to trigger if
            //    the response is overdue.
            // 3) A check has previously triggered and it failed. We want to trigger, but only if
            //    we're not in a persistent failure state.
            // 4) A check has previously triggered and it succeeded.
            //    We don't want to trigger, and want to stop future triggers.

            if (!mCheckTriggered) {
                // Case 1.
                Slog.d(TAG, "triggerUpdateIfNeeded: First reliability trigger.");
            } else if (isCheckInProgress()) {
                // Case 2.
                if (!isCheckResponseOverdue()) {
                    // A check is in progress but hasn't been given time to succeed.
                    Slog.d(TAG,
                            "triggerUpdateIfNeeded: checkComplete call is not yet overdue."
                                    + " Not triggering.");
                    // Not doing any work, but also not disabling future reliability triggers.
                    return;
                }
            } else if (mCheckFailureCount > mFailedCheckRetryCount) {
                // Case 3. If the system is in some kind of persistent failure state we don't want
                // to keep checking, so just stop.
                Slog.i(TAG, "triggerUpdateIfNeeded: number of allowed consecutive check failures"
                        + " exceeded. Stopping reliability triggers until next reboot or package"
                        + " update.");
                mIntentHelper.disableReliabilityTriggering();
                return;
            } else if (mCheckFailureCount == 0) {
                // Case 4.
                Slog.i(TAG, "triggerUpdateIfNeeded: No reliability check required. Last check was"
                        + " successful.");
                mIntentHelper.disableReliabilityTriggering();
                return;
            }
        }

        // Read the currently installed data / updater package versions.
        PackageVersions currentInstalledVersions = lookupInstalledPackageVersions();
        if (currentInstalledVersions == null) {
            // This should not happen if the device is configured in a valid way.
            Slog.e(TAG, "triggerUpdateIfNeeded: currentInstalledVersions was null");
            mIntentHelper.disableReliabilityTriggering();
            return;
        }

        // Establish the current state using package manager and stored state. Determine if we have
        // already successfully checked the installed versions.
        PackageStatus packageStatus = mPackageStatusStorage.getPackageStatus();
        if (packageStatus == null) {
            // This can imply corrupt, uninitialized storage state (e.g. first check ever on a
            // device) or after some kind of reset.
            Slog.i(TAG, "triggerUpdateIfNeeded: No package status data found. Data check needed.");
        } else if (!packageStatus.mVersions.equals(currentInstalledVersions)) {
            // The stored package version information differs from the installed version.
            // Trigger the check in all cases.
            Slog.i(TAG, "triggerUpdateIfNeeded: Stored package versions="
                    + packageStatus.mVersions + ", do not match current package versions="
                    + currentInstalledVersions + ". Triggering check.");
        } else {
            Slog.i(TAG, "triggerUpdateIfNeeded: Stored package versions match currently"
                    + " installed versions, currentInstalledVersions=" + currentInstalledVersions
                    + ", packageStatus.mCheckStatus=" + packageStatus.mCheckStatus);
            if (packageStatus.mCheckStatus == PackageStatus.CHECK_COMPLETED_SUCCESS) {
                // The last check succeeded and nothing has changed. Do nothing and disable
                // reliability checks.
                Slog.i(TAG, "triggerUpdateIfNeeded: Prior check succeeded. No need to trigger.");
                mIntentHelper.disableReliabilityTriggering();
                return;
            }
        }

        // Generate a token to send to the updater app.
        CheckToken checkToken =
                mPackageStatusStorage.generateCheckToken(currentInstalledVersions);
        if (checkToken == null) {
            Slog.w(TAG, "triggerUpdateIfNeeded: Unable to generate check token."
                    + " Not sending check request.");
            return;
        }

        // Trigger the update check.
        mIntentHelper.sendTriggerUpdateCheck(checkToken);
        mCheckTriggered = true;

        // Update the reliability check state in case the update fails.
        setCheckInProgress();

        // Enable reliability triggering in case the check doesn't succeed and there is no
        // response at all. Enabling reliability triggering is idempotent.
        mIntentHelper.enableReliabilityTriggering();
    }

    /**
     * Used to record the result of a check. Can be called even if active package tracking is
     * disabled.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected synchronized void recordCheckResult(CheckToken checkToken, boolean success) {
        Slog.i(TAG, "recordOperationResult: checkToken=" + checkToken + " success=" + success);

        // If package tracking is disabled it means no record-keeping is required. However, we do
        // want to clear out any stored state to make it clear that the current state is unknown and
        // should tracking become enabled again (perhaps through an OTA) we'd need to perform an
        // update check.
        if (!mTrackingEnabled) {
            // This means an updater has spontaneously modified time zone data without having been
            // triggered. This can happen if the OEM is handling their own updates, but we don't
            // need to do any tracking in this case.

            if (checkToken == null) {
                // This is the expected case if tracking is disabled but an OEM is handling time
                // zone installs using their own mechanism.
                Slog.d(TAG, "recordCheckResult: Tracking is disabled and no token has been"
                        + " provided. Resetting tracking state.");
            } else {
                // This is unexpected. If tracking is disabled then no check token should have been
                // generated by the package tracker. An updater should never create its own token.
                // This could be a bug in the updater.
                Slog.w(TAG, "recordCheckResult: Tracking is disabled and a token " + checkToken
                        + " has been unexpectedly provided. Resetting tracking state.");
            }
            mPackageStatusStorage.resetCheckState();
            return;
        }

        if (checkToken == null) {
            /*
             * If the checkToken is null it suggests an install / uninstall / acknowledgement has
             * occurred without a prior trigger (or the client didn't return the token it was given
             * for some reason, perhaps a bug).
             *
             * This shouldn't happen under normal circumstances:
             *
             * If package tracking is enabled, we assume it is the package tracker responsible for
             * triggering updates and a token should have been produced and returned.
             *
             * If the OEM is handling time zone updates case package tracking should be disabled.
             *
             * This could happen in tests. The device should recover back to a known state by
             * itself rather than be left in an invalid state.
             *
             * We treat this as putting the device into an unknown state and make sure that
             * reliability triggering is enabled so we should recover.
             */
            Slog.i(TAG, "recordCheckResult: Unexpectedly missing checkToken, resetting"
                    + " storage state.");
            mPackageStatusStorage.resetCheckState();

            // Enable reliability triggering and reset the failure count so we know that the
            // next reliability trigger will do something.
            mIntentHelper.enableReliabilityTriggering();
            mCheckFailureCount = 0;
        } else {
            // This is the expected case when tracking is enabled: a check was triggered and it has
            // completed.
            boolean recordedCheckCompleteSuccessfully =
                    mPackageStatusStorage.markChecked(checkToken, success);
            if (recordedCheckCompleteSuccessfully) {
                // If we have recorded the result (whatever it was) we know there is no check in
                // progress.
                setCheckComplete();

                if (success) {
                    // Since the check was successful, no more reliability checks are required until
                    // there is a package change.
                    mIntentHelper.disableReliabilityTriggering();
                    mCheckFailureCount = 0;
                } else {
                    // Enable reliability triggering to potentially check again in future.
                    mIntentHelper.enableReliabilityTriggering();
                    mCheckFailureCount++;
                }
            } else {
                // The failure to record the check means an optimistic lock failure and suggests
                // that another check was triggered after the token was generated.
                Slog.i(TAG, "recordCheckResult: could not update token=" + checkToken
                        + " with success=" + success + ". Optimistic lock failure");

                // Enable reliability triggering to potentially try again in future.
                mIntentHelper.enableReliabilityTriggering();
                mCheckFailureCount++;
            }
        }
    }

    /** Access to consecutive failure counts for use in tests. */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    protected int getCheckFailureCountForTests() {
        return mCheckFailureCount;
    }

    private void setCheckInProgress() {
        mLastTriggerTimestamp = mClockHelper.currentTimestamp();
    }

    private void setCheckComplete() {
        mLastTriggerTimestamp = null;
    }

    private boolean isCheckInProgress() {
        return mLastTriggerTimestamp != null;
    }

    private boolean isCheckResponseOverdue() {
        if (mLastTriggerTimestamp == null) {
            return false;
        }
        // Risk of overflow, but highly unlikely given the implementation and not problematic.
        return mClockHelper.currentTimestamp() > mLastTriggerTimestamp + mCheckTimeAllowedMillis;
    }

    private PackageVersions lookupInstalledPackageVersions() {
        int updatePackageVersion;
        int dataPackageVersion;
        try {
            updatePackageVersion =
                    mPackageManagerHelper.getInstalledPackageVersion(mUpdateAppPackageName);
            dataPackageVersion =
                    mPackageManagerHelper.getInstalledPackageVersion(mDataAppPackageName);
        } catch (PackageManager.NameNotFoundException e) {
            Slog.w(TAG, "lookupInstalledPackageVersions: Unable to resolve installed package"
                    + " versions", e);
            return null;
        }
        return new PackageVersions(updatePackageVersion, dataPackageVersion);
    }

    private boolean validateDataAppManifest() {
        // We only want to talk to a provider that exposed by the known data app package
        // so we look up the providers exposed by that app and check the well-known authority is
        // there. This prevents the case where *even if* the data app doesn't expose the provider
        // required, another app cannot expose one to replace it.
        if (!mPackageManagerHelper.contentProviderRegistered(
                TimeZoneRulesDataContract.AUTHORITY, mDataAppPackageName)) {
            // Error! Found the package but it didn't expose the correct provider.
            Slog.w(TAG, "validateDataAppManifest: Data app " + mDataAppPackageName
                    + " does not expose the required provider with authority="
                    + TimeZoneRulesDataContract.AUTHORITY);
            return false;
        }
        // TODO(nfuller) Add any permissions checks needed.
        return true;
    }

    private boolean validateUpdaterAppManifest() {
        try {
            // The updater app is expected to have the UPDATE_TIME_ZONE_RULES permission.
            // The updater app is expected to have a receiver for the intent we are going to trigger
            // and require the TRIGGER_TIME_ZONE_RULES_CHECK.
            if (!mPackageManagerHelper.usesPermission(
                    mUpdateAppPackageName,
                    RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION)) {
                Slog.w(TAG, "validateUpdaterAppManifest: Updater app " + mDataAppPackageName
                        + " does not use permission="
                        + RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
                return false;
            }
            if (!mPackageManagerHelper.receiverRegistered(
                    RulesUpdaterContract.createUpdaterIntent(mUpdateAppPackageName),
                    RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)) {
                return false;
            }

            return true;
        } catch (PackageManager.NameNotFoundException e) {
            Slog.w(TAG, "validateUpdaterAppManifest: Updater app " + mDataAppPackageName
                    + " does not expose the required broadcast receiver.", e);
            return false;
        }
    }

    private static void throwRuntimeExceptionIfNullOrEmpty(String value, String message) {
        if (value == null || value.trim().isEmpty()) {
            throw logAndThrowRuntimeException(message, null);
        }
    }

    private static RuntimeException logAndThrowRuntimeException(String message, Throwable cause) {
        Slog.wtf(TAG, message, cause);
        throw new RuntimeException(message, cause);
    }
}
