Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2780e401 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix reliability triggering"

parents 096a47d5 cd1a109b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3910,6 +3910,9 @@
                 android:permission="android.permission.BIND_JOB_SERVICE" >
        </service>

        <service android:name="com.android.server.timezone.TimeZoneUpdateIdler"
                 android:permission="android.permission.BIND_JOB_SERVICE" >
        </service>
    </application>

</manifest>
+14 −7
Original line number Diff line number Diff line
@@ -23,15 +23,22 @@ package com.android.server.timezone;
 */
interface IntentHelper {

    void initialize(String updateAppPackageName, String dataAppPackageName, Listener listener);
    void initialize(String updateAppPackageName, String dataAppPackageName,
            PackageTracker packageTracker);

    void sendTriggerUpdateCheck(CheckToken checkToken);

    void enableReliabilityTriggering();

    void disableReliabilityTriggering();
    /**
     * Schedule a "reliability trigger" after at least minimumDelayMillis, replacing any existing
     * scheduled one. A reliability trigger ensures that the {@link PackageTracker} can pick up
     * reliably if a previous update check did not complete for some reason. It can happen when
     * the device is idle. The trigger is expected to call
     * {@link PackageTracker#triggerUpdateIfNeeded(boolean)} with a {@code false} value.
     */
    void scheduleReliabilityTrigger(long minimumDelayMillis);

    interface Listener {
        void triggerUpdateIfNeeded(boolean packageUpdated);
    }
    /**
     * Make sure there is no reliability trigger scheduled. No-op if there wasn't one.
     */
    void unscheduleReliabilityTrigger();
}
+11 −29
Original line number Diff line number Diff line
@@ -36,16 +36,13 @@ final class IntentHelperImpl implements IntentHelper {
    private final Context mContext;
    private String mUpdaterAppPackageName;

    private boolean mReliabilityReceiverEnabled;
    private Receiver mReliabilityReceiver;

    IntentHelperImpl(Context context) {
        mContext = context;
    }

    @Override
    public void initialize(
            String updaterAppPackageName, String dataAppPackageName, Listener listener) {
    public void initialize(String updaterAppPackageName, String dataAppPackageName,
            PackageTracker packageTracker) {
        mUpdaterAppPackageName = updaterAppPackageName;

        // Register for events of interest.
@@ -78,10 +75,8 @@ final class IntentHelperImpl implements IntentHelper {
        // We do not register for ACTION_PACKAGE_DATA_CLEARED because the updater / data apps are
        // not expected to need local data.

        Receiver packageUpdateReceiver = new Receiver(listener, true /* packageUpdated */);
        Receiver packageUpdateReceiver = new Receiver(packageTracker);
        mContext.registerReceiver(packageUpdateReceiver, packageIntentFilter);

        mReliabilityReceiver = new Receiver(listener, false /* packageUpdated */);
    }

    /** Sends an intent to trigger an update check. */
@@ -93,39 +88,26 @@ final class IntentHelperImpl implements IntentHelper {
    }

    @Override
    public synchronized void enableReliabilityTriggering() {
        if (!mReliabilityReceiverEnabled) {
            // The intent filter that exists to make updates reliable in the event of failures /
            // reboots.
            IntentFilter reliabilityIntentFilter = new IntentFilter();
            reliabilityIntentFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START);
            mContext.registerReceiver(mReliabilityReceiver, reliabilityIntentFilter);
            mReliabilityReceiverEnabled = true;
        }
    public synchronized void scheduleReliabilityTrigger(long minimumDelayMillis) {
        TimeZoneUpdateIdler.schedule(mContext, minimumDelayMillis);
    }

    @Override
    public synchronized void disableReliabilityTriggering() {
        if (mReliabilityReceiverEnabled) {
            mContext.unregisterReceiver(mReliabilityReceiver);
            mReliabilityReceiverEnabled = false;
        }
    public synchronized void unscheduleReliabilityTrigger() {
        TimeZoneUpdateIdler.unschedule(mContext);
    }

    private static class Receiver extends BroadcastReceiver {
        private final Listener mListener;
        private final boolean mPackageUpdated;
        private final PackageTracker mPackageTracker;

        private Receiver(Listener listener, boolean packageUpdated) {
            mListener = listener;
            mPackageUpdated = packageUpdated;
        private Receiver(PackageTracker packageTracker) {
            mPackageTracker = packageTracker;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            Slog.d(TAG, "Received intent: " + intent.toString());
            mListener.triggerUpdateIfNeeded(mPackageUpdated);
            mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
        }
    }

}
+35 −23
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ import java.io.PrintWriter;
 */
// Also made non-final so it can be mocked.
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public class PackageTracker implements IntentHelper.Listener {
public class PackageTracker {
    private static final String TAG = "timezone.PackageTracker";

    private final PackageManagerHelper mPackageManagerHelper;
@@ -72,6 +72,13 @@ public class PackageTracker implements IntentHelper.Listener {
    // The number of failed checks in a row before reliability checks should stop happening.
    private long mFailedCheckRetryCount;

    /*
     * The minimum delay between a successive reliability triggers / other operations. Should to be
     * larger than mCheckTimeAllowedMillis to avoid reliability triggers happening during package
     * update checks.
     */
    private int mDelayBeforeReliabilityCheckMillis;

    // Reliability check state: If a check was triggered but not acknowledged within
    // mCheckTimeAllowedMillis then another one can be triggered.
    private Long mLastTriggerTimestamp = null;
@@ -122,6 +129,7 @@ public class PackageTracker implements IntentHelper.Listener {
        mDataAppPackageName = mConfigHelper.getDataAppPackageName();
        mCheckTimeAllowedMillis = mConfigHelper.getCheckTimeAllowedMillis();
        mFailedCheckRetryCount = mConfigHelper.getFailedCheckRetryCount();
        mDelayBeforeReliabilityCheckMillis = mCheckTimeAllowedMillis + (60 * 1000);

        // Validate the device configuration including the application packages.
        // The manifest entries in the apps themselves are not validated until use as they can
@@ -135,9 +143,10 @@ public class PackageTracker implements IntentHelper.Listener {
        // 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();
        // Schedule a reliability trigger so we will have at least one after boot. This will allow
        // us to catch if a package updated wasn't handled to completion. There's no hurry: it's ok
        // to delay for a while before doing this even if idle.
        mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);

        Slog.i(TAG, "Time zone updater / data package tracking enabled");
    }
@@ -195,7 +204,6 @@ public class PackageTracker implements IntentHelper.Listener {
     * @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.");
@@ -212,8 +220,8 @@ public class PackageTracker implements IntentHelper.Listener {
                    + " updaterApp=" + updaterAppManifestValid
                    + ", dataApp=" + dataAppManifestValid);

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

@@ -238,7 +246,8 @@ public class PackageTracker implements IntentHelper.Listener {
                    Slog.d(TAG,
                            "triggerUpdateIfNeeded: checkComplete call is not yet overdue."
                                    + " Not triggering.");
                    // Not doing any work, but also not disabling future reliability triggers.
                    // Don't do any work now but we do schedule a future reliability trigger.
                    mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                    return;
                }
            } else if (mCheckFailureCount > mFailedCheckRetryCount) {
@@ -247,13 +256,13 @@ public class PackageTracker implements IntentHelper.Listener {
                Slog.i(TAG, "triggerUpdateIfNeeded: number of allowed consecutive check failures"
                        + " exceeded. Stopping reliability triggers until next reboot or package"
                        + " update.");
                mIntentHelper.disableReliabilityTriggering();
                mIntentHelper.unscheduleReliabilityTrigger();
                return;
            } else if (mCheckFailureCount == 0) {
                // Case 4.
                Slog.i(TAG, "triggerUpdateIfNeeded: No reliability check required. Last check was"
                        + " successful.");
                mIntentHelper.disableReliabilityTriggering();
                mIntentHelper.unscheduleReliabilityTrigger();
                return;
            }
        }
@@ -263,7 +272,7 @@ public class PackageTracker implements IntentHelper.Listener {
        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();
            mIntentHelper.unscheduleReliabilityTrigger();
            return;
        }

@@ -288,7 +297,7 @@ public class PackageTracker implements IntentHelper.Listener {
                // 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();
                mIntentHelper.unscheduleReliabilityTrigger();
                return;
            }
        }
@@ -299,6 +308,8 @@ public class PackageTracker implements IntentHelper.Listener {
        if (checkToken == null) {
            Slog.w(TAG, "triggerUpdateIfNeeded: Unable to generate check token."
                    + " Not sending check request.");
            // Trigger again later: perhaps we'll have better luck.
            mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
            return;
        }

@@ -309,9 +320,9 @@ public class PackageTracker implements IntentHelper.Listener {
        // 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();
        // Schedule a reliability trigger in case the update check doesn't succeed and there is no
        // response at all. It will be cancelled if the check is successful in recordCheckResult.
        mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
    }

    /**
@@ -370,9 +381,9 @@ public class PackageTracker implements IntentHelper.Listener {
                    + " storage state.");
            mPackageStatusStorage.resetCheckState();

            // Enable reliability triggering and reset the failure count so we know that the
            // Schedule a reliability trigger and reset the failure count so we know that the
            // next reliability trigger will do something.
            mIntentHelper.enableReliabilityTriggering();
            mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
            mCheckFailureCount = 0;
        } else {
            // This is the expected case when tracking is enabled: a check was triggered and it has
@@ -385,13 +396,13 @@ public class PackageTracker implements IntentHelper.Listener {
                setCheckComplete();

                if (success) {
                    // Since the check was successful, no more reliability checks are required until
                    // Since the check was successful, no reliability trigger is required until
                    // there is a package change.
                    mIntentHelper.disableReliabilityTriggering();
                    mIntentHelper.unscheduleReliabilityTrigger();
                    mCheckFailureCount = 0;
                } else {
                    // Enable reliability triggering to potentially check again in future.
                    mIntentHelper.enableReliabilityTriggering();
                    // Enable schedule a reliability trigger to check again in future.
                    mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                    mCheckFailureCount++;
                }
            } else {
@@ -400,8 +411,8 @@ public class PackageTracker implements IntentHelper.Listener {
                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();
                // Schedule a reliability trigger to potentially try again in future.
                mIntentHelper.scheduleReliabilityTrigger(mDelayBeforeReliabilityCheckMillis);
                mCheckFailureCount++;
            }
        }
@@ -515,6 +526,7 @@ public class PackageTracker implements IntentHelper.Listener {
                ", mUpdateAppPackageName='" + mUpdateAppPackageName + '\'' +
                ", mDataAppPackageName='" + mDataAppPackageName + '\'' +
                ", mCheckTimeAllowedMillis=" + mCheckTimeAllowedMillis +
                ", mDelayBeforeReliabilityCheckMillis=" + mDelayBeforeReliabilityCheckMillis +
                ", mFailedCheckRetryCount=" + mFailedCheckRetryCount +
                ", mLastTriggerTimestamp=" + mLastTriggerTimestamp +
                ", mCheckTriggered=" + mCheckTriggered +
+19 −5
Original line number Diff line number Diff line
@@ -69,18 +69,22 @@ public final class RulesManagerService extends IRulesManager.Stub {
                    DistroVersion.CURRENT_FORMAT_MINOR_VERSION);

    public static class Lifecycle extends SystemService {
        private RulesManagerService mService;

        public Lifecycle(Context context) {
            super(context);
        }

        @Override
        public void onStart() {
            mService = RulesManagerService.create(getContext());
            mService.start();
            RulesManagerService service = RulesManagerService.create(getContext());
            service.start();

            // Publish the binder service so it can be accessed from other (appropriately
            // permissioned) processes.
            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, service);

            publishBinderService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, mService);
            // Publish the service instance locally so we can use it directly from within the system
            // server from TimeZoneUpdateIdler.
            publishLocalService(RulesManagerService.class, service);
        }
    }

@@ -496,6 +500,16 @@ public final class RulesManagerService extends IRulesManager.Stub {
        mPackageTracker.dump(pw);
    }

    /**
     * Called when the device is considered idle.
     */
    void notifyIdle() {
        // No package has changed: we are just triggering because the device is idle and there
        // *might* be work to do.
        final boolean packageChanged = false;
        mPackageTracker.triggerUpdateIfNeeded(packageChanged);
    }

    @Override
    public String toString() {
        return "RulesManagerService{" +
Loading