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

Commit 50140665 authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Sync too many retries"

parents 72698e6f aad2b51b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -10504,6 +10504,16 @@ public final class Settings {
         */
        public static final String BATTERY_STATS_CONSTANTS = "battery_stats_constants";

        /**
         * SyncManager specific settings.
         *
         * <p>
         * Type: string
         * @hide
         * @see com.android.server.content.SyncManagerConstants
         */
        public static final String SYNC_MANAGER_CONSTANTS = "sync_manager_constants";

        /**
         * Whether or not App Standby feature is enabled. This controls throttling of apps
         * based on usage patterns and predictions.
+1 −0
Original line number Diff line number Diff line
@@ -366,6 +366,7 @@ public class SettingsBackupTest {
                    Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
                    Settings.Global.STORAGE_BENCHMARK_INTERVAL,
                    Settings.Global.STORAGE_SETTINGS_CLOBBER_THRESHOLD,
                    Settings.Global.SYNC_MANAGER_CONSTANTS,
                    Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
                    Settings.Global.SYS_FREE_STORAGE_LOG_INTERVAL,
                    Settings.Global.SYS_STORAGE_CACHE_MAX_BYTES,
+10 −5
Original line number Diff line number Diff line
@@ -97,9 +97,7 @@ public final class ContentService extends IContentService.Stub {

        @Override
        public void onBootPhase(int phase) {
            if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
                mService.systemReady();
            }
            mService.onBootPhase(phase);
        }


@@ -300,8 +298,15 @@ public final class ContentService extends IContentService.Stub {
                localeFilter, null, null);
    }

    void systemReady() {
    void onBootPhase(int phase) {
        switch (phase) {
            case SystemService.PHASE_SYSTEM_SERVICES_READY:
                getSyncManager();
                break;
        }
        if (mSyncManager != null) {
            mSyncManager.onBootPhase(phase);
        }
    }

    /**
+29 −21
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.job.JobSchedulerInternal;
import com.google.android.collect.Lists;
import com.google.android.collect.Maps;
@@ -102,7 +103,6 @@ import com.android.server.backup.AccountSyncSettingsBackupHelper;
import com.android.server.content.SyncStorageEngine.AuthorityInfo;
import com.android.server.content.SyncStorageEngine.EndPoint;
import com.android.server.content.SyncStorageEngine.OnSyncRequestListener;
import com.android.server.job.JobSchedulerInternal.JobStorePersistStats;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -157,18 +157,6 @@ public class SyncManager {
                SystemProperties.getLong("sync.local_sync_delay", 30 * 1000 /* 30 seconds */);
    }

    /**
     * When retrying a sync for the first time use this delay. After that
     * the retry time will double until it reached MAX_SYNC_RETRY_TIME.
     * In milliseconds.
     */
    private static final long INITIAL_SYNC_RETRY_TIME_IN_MS = 30 * 1000; // 30 seconds

    /**
     * Default the max sync retry time to this value.
     */
    private static final long DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS = 60 * 60; // one hour

    /**
     * How long to wait before retrying a sync that failed due to one already being in progress.
     */
@@ -449,6 +437,7 @@ public class SyncManager {
    };

    private final SyncHandler mSyncHandler;
    private final SyncManagerConstants mConstants;

    private volatile boolean mBootCompleted = false;
    private volatile boolean mJobServiceReady = false;
@@ -616,6 +605,7 @@ public class SyncManager {
        }, mSyncHandler);

        mRand = new Random(System.currentTimeMillis());
        mConstants = new SyncManagerConstants(context);

        IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
@@ -756,6 +746,14 @@ public class SyncManager {
        mSyncHandler.post(() -> mLogger.log("onStopUser: user=", userHandle));
    }

    public void onBootPhase(int phase) {
        // Note SyncManager only receives PHASE_SYSTEM_SERVICES_READY and after.
        switch (phase) {
            case SystemService.PHASE_SYSTEM_SERVICES_READY:
                mConstants.start();
                break;
        }
    }

    private void whiteListExistingSyncAdaptersIfNeeded() {
        if (!mSyncStorageEngine.shouldGrantSyncAdaptersAccountAccess()) {
@@ -903,7 +901,10 @@ public class SyncManager {
        }
        if (isLoggable) {
            Log.d(TAG, "one-time sync for: " + requestedAccount + " " + extras.toString() + " "
                    + requestedAuthority);
                    + requestedAuthority
                    + " reason=" + reason
                    + " checkIfAccountReady=" + checkIfAccountReady
                    + " isAppStandbyExempted=" + isAppStandbyExempted);
        }

        AccountAndUser[] accounts = null;
@@ -1368,18 +1369,18 @@ public class SyncManager {
                return;
            }
            // Subsequent delays are the double of the previous delay.
            newDelayInMs = previousSettings.second * 2;
            newDelayInMs =
                    (long) (previousSettings.second * mConstants.getRetryTimeIncreaseFactor());
        }
        if (newDelayInMs <= 0) {
            // The initial delay is the jitterized INITIAL_SYNC_RETRY_TIME_IN_MS.
            newDelayInMs = jitterize(INITIAL_SYNC_RETRY_TIME_IN_MS,
                    (long)(INITIAL_SYNC_RETRY_TIME_IN_MS * 1.1));
            final long initialRetryMs = mConstants.getInitialSyncRetryTimeInSeconds() * 1000;
            newDelayInMs = jitterize(initialRetryMs, (long)(initialRetryMs * 1.1));
        }

        // Cap the delay.
        long maxSyncRetryTimeInSeconds = Settings.Global.getLong(mContext.getContentResolver(),
                Settings.Global.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
                DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS);
        final long maxSyncRetryTimeInSeconds = mConstants.getMaxSyncRetryTimeInSeconds();

        if (newDelayInMs > maxSyncRetryTimeInSeconds * 1000) {
            newDelayInMs = maxSyncRetryTimeInSeconds * 1000;
        }
@@ -1930,6 +1931,7 @@ public class SyncManager {
    protected void dump(FileDescriptor fd, PrintWriter pw, boolean dumpAll) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
        dumpSyncState(ipw);
        mConstants.dump(pw, "");
        dumpSyncAdapters(ipw);

        if (dumpAll) {
@@ -3573,7 +3575,13 @@ public class SyncManager {
                        reschedulePeriodicSyncH(syncOperation);
                    }
                } else {
                    Log.d(TAG, "failed sync operation " + syncOperation + ", " + syncResult);
                    Log.w(TAG, "failed sync operation " + syncOperation + ", " + syncResult);

                    syncOperation.retries++;
                    if (syncOperation.retries > mConstants.getMaxRetriesWithAppStandbyExemption()) {
                        syncOperation.isAppStandbyExempted = false;
                    }

                    // the operation failed so increase the backoff time
                    increaseBackoffSetting(syncOperation.target);
                    if (!syncOperation.isPeriodic) {
+146 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.content;

import android.content.Context;
import android.database.ContentObserver;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.util.KeyValueListParser;
import android.util.Slog;

import java.io.PrintWriter;

public class SyncManagerConstants extends ContentObserver {
    private static final String TAG = "SyncManagerConfig";

    private final Object mLock = new Object();
    private final Context mContext;

    private static final String KEY_INITIAL_SYNC_RETRY_TIME_IN_SECONDS =
            "initial_sync_retry_time_in_seconds";
    private static final int DEF_INITIAL_SYNC_RETRY_TIME_IN_SECONDS = 30;
    private int mInitialSyncRetryTimeInSeconds = DEF_INITIAL_SYNC_RETRY_TIME_IN_SECONDS;

    private static final String KEY_RETRY_TIME_INCREASE_FACTOR =
            "retry_time_increase_factor";
    private static final float DEF_RETRY_TIME_INCREASE_FACTOR = 2.0f;
    private float mRetryTimeIncreaseFactor = DEF_RETRY_TIME_INCREASE_FACTOR;

    private static final String KEY_MAX_SYNC_RETRY_TIME_IN_SECONDS =
            "max_sync_retry_time_in_seconds";
    private static final int DEF_MAX_SYNC_RETRY_TIME_IN_SECONDS = 60 * 60;
    private int mMaxSyncRetryTimeInSeconds = DEF_MAX_SYNC_RETRY_TIME_IN_SECONDS;

    private static final String KEY_MAX_RETRIES_WITH_APP_STANDBY_EXEMPTION =
            "max_retries_with_app_standby_exemption";
    private static final int DEF_MAX_RETRIES_WITH_APP_STANDBY_EXEMPTION = 5;
    private int mMaxRetriesWithAppStandbyExemption = DEF_MAX_RETRIES_WITH_APP_STANDBY_EXEMPTION;

    protected SyncManagerConstants(Context context) {
        super(null);
        mContext = context;
        refresh();
    }

    public void start() {
        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
                Settings.Global.SYNC_MANAGER_CONSTANTS), false, this);
        refresh();
    }

    @Override
    public void onChange(boolean selfChange) {
        refresh();
    }

    private void refresh() {
        synchronized (mLock) {

            String newValue = Settings.Global.getString(mContext.getContentResolver(),
                    Global.SYNC_MANAGER_CONSTANTS);
            final KeyValueListParser parser = new KeyValueListParser(',');
            try {
                parser.setString(newValue);
            } catch (IllegalArgumentException e) {
                Slog.wtf(TAG, "Bad constants: " + newValue);
            }

            mInitialSyncRetryTimeInSeconds = parser.getInt(
                    KEY_INITIAL_SYNC_RETRY_TIME_IN_SECONDS,
                    DEF_INITIAL_SYNC_RETRY_TIME_IN_SECONDS);

            mMaxSyncRetryTimeInSeconds = parser.getInt(
                    KEY_MAX_SYNC_RETRY_TIME_IN_SECONDS,
                    DEF_MAX_SYNC_RETRY_TIME_IN_SECONDS);

            mRetryTimeIncreaseFactor = parser.getFloat(
                    KEY_RETRY_TIME_INCREASE_FACTOR,
                    DEF_RETRY_TIME_INCREASE_FACTOR);

            mMaxRetriesWithAppStandbyExemption = parser.getInt(
                    KEY_MAX_RETRIES_WITH_APP_STANDBY_EXEMPTION,
                    DEF_MAX_RETRIES_WITH_APP_STANDBY_EXEMPTION);
        }
    }

    public int getInitialSyncRetryTimeInSeconds() {
        synchronized (mLock) {
            return mInitialSyncRetryTimeInSeconds;
        }
    }

    public float getRetryTimeIncreaseFactor() {
        synchronized (mLock) {
            return mRetryTimeIncreaseFactor;
        }
    }

    public int getMaxSyncRetryTimeInSeconds() {
        synchronized (mLock) {
            return mMaxSyncRetryTimeInSeconds;
        }
    }

    public int getMaxRetriesWithAppStandbyExemption() {
        synchronized (mLock) {
            return mMaxRetriesWithAppStandbyExemption;
        }
    }

    public void dump(PrintWriter pw, String prefix) {
        synchronized (mLock) {
            pw.print(prefix);
            pw.println("SyncManager Config:");

            pw.print(prefix);
            pw.print("  mInitialSyncRetryTimeInSeconds=");
            pw.println(mInitialSyncRetryTimeInSeconds);

            pw.print(prefix);
            pw.print("  mRetryTimeIncreaseFactor=");
            pw.println(mRetryTimeIncreaseFactor);

            pw.print(prefix);
            pw.print("  mMaxSyncRetryTimeInSeconds=");
            pw.println(mMaxSyncRetryTimeInSeconds);

            pw.print(prefix);
            pw.print("  mMaxRetriesWithAppStandbyExemption=");
            pw.println(mMaxRetriesWithAppStandbyExemption);
        }
    }
}
Loading