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

Commit da5e4ee7 authored by shafik's avatar shafik
Browse files

Make Rollback Manager handle time change

Add a broadcast receiver for time change intents in Rollback Manager and
handle time change accordingly so that the rollback lifetime will expire
after the designated time even if the user changes the time or the
timezone is changed.

Test: atest RollbackTest
Test: expiration time test will follow in a separate CL
Bug: 124095332
Change-Id: Ib18dcc96f06140a05b3243cfe89630db1f0aba4e
parent 0eedd597
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.SystemClock;
import android.provider.DeviceConfig;
import android.util.IntArray;
import android.util.Log;
@@ -121,6 +122,13 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private final RollbackPackageHealthObserver mPackageHealthObserver;
    private final AppDataRollbackHelper mAppDataRollbackHelper;

    // This field stores the difference in Millis between the uptime (millis since device
    // has booted) and current time (device wall clock) - it's used to update rollback data
    // timestamps when the time is changed, by the user or by change of timezone.
    // No need for guarding with lock because value is only accessed in handler thread.
    private long  mRelativeBootTime = calculateRelativeBootTime();


    RollbackManagerServiceImpl(Context context) {
        mContext = context;
        // Note that we're calling onStart here because this object is only constructed on
@@ -217,6 +225,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                }
            }
        }, enableRollbackFilter, null, getHandler());

        registerTimeChangeReceiver();
    }

    @Override
@@ -268,6 +278,45 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    callerPackageName, statusReceiver));
    }

    private void registerTimeChangeReceiver() {
        final BroadcastReceiver timeChangeIntentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                final long oldRelativeBootTime = mRelativeBootTime;
                mRelativeBootTime = calculateRelativeBootTime();
                final long timeDifference = mRelativeBootTime - oldRelativeBootTime;

                synchronized (mLock) {
                    ensureRollbackDataLoadedLocked();

                    Iterator<RollbackData> iter = mAvailableRollbacks.iterator();
                    while (iter.hasNext()) {
                        RollbackData data = iter.next();

                        data.timestamp = data.timestamp.plusMillis(timeDifference);
                        try {
                            mRollbackStore.saveAvailableRollback(data);
                        } catch (IOException ioe) {
                            // TODO: figure out the right way to deal with this, especially if
                            //  it fails for some data and succeeds for others.
                            Log.e(TAG, "Unable to save rollback info for : " + data.rollbackId,
                                    ioe);
                        }
                    }

                }
            }
        };
        final IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        mContext.registerReceiver(timeChangeIntentReceiver, filter,
                null /* broadcastPermission */, getHandler());
    }

    private static long calculateRelativeBootTime() {
        return System.currentTimeMillis() - SystemClock.elapsedRealtime();
    }

    /**
     * Performs the actual work to commit a rollback.
     * The work is done on the current thread. This may be a long running