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

Commit dc4a3610 authored by Oli Lan's avatar Oli Lan Committed by Bill Lin
Browse files

Include NewRollbacks in result of getAvailableRollbacks.

This CL adds NewRollbacks to the return value of getAvailableRollbacks,
as long as the PackageRollbackInfo is complete (i.e. there is one for
each child session in the install).

Including these should avoid the potential race condition between the
install finishing and getAvailableRollbacks being called which affected
some of the tests. This means that the draining of the handler that was
previously added to getAvailableRollbacks can now be removed.

In order to avoid a similar race condition when rollbacks are expired, this
change also cancels corresponding NewRollbacks when expireRollbackForPackage
is called.

Bug: 136241838
Bug: 136548146
Test: atest RollbackTest
Test: manual local test with delay added to onFinished in the service callback
Change-Id: Ie4581d218077dc16e53c337a5bb76609cc50a57e
Merged-In: I015ee5925e38118c40f4b9e145f78fb12c0e2890
parent 91fc4db1
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -74,7 +74,10 @@ public final class RollbackManager {
    }
    }


    /**
    /**
     * Returns a list of all currently available rollbacks.
     * Returns a list of all currently available rollbacks. This includes ones for very recently
     * installed packages (even if onFinished has not yet been called). As a result, packages that
     * very recently failed to install may also be included, but those rollbacks will fail with
     * 'rollback not available'.
     *
     *
     * @throws SecurityException if the caller does not have appropriate permissions.
     * @throws SecurityException if the caller does not have appropriate permissions.
     */
     */
+17 −24
Original line number Original line Diff line number Diff line
@@ -271,33 +271,9 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        }, filter, null, getHandler());
        }, filter, null, getHandler());
    }
    }


    /**
     * This method posts a blocking call to the handler thread, so it should not be called from
     * that same thread.
     * @throws {@link IllegalStateException} if called from {@link #mHandlerThread}
     */
    @Override
    @Override
    public ParceledListSlice getAvailableRollbacks() {
    public ParceledListSlice getAvailableRollbacks() {
        enforceManageRollbacks("getAvailableRollbacks");
        enforceManageRollbacks("getAvailableRollbacks");
        if (Thread.currentThread().equals(mHandlerThread)) {
            Slog.wtf(TAG, "Calling getAvailableRollbacks from mHandlerThread "
                    + "causes a deadlock");
            throw new IllegalStateException("Cannot call RollbackManager#getAvailableRollbacks "
                    + "from the handler thread!");
        }

        // Wait for the handler thread to get the list of available rollbacks
        // to get the most up-to-date results. This is intended to reduce test
        // flakiness when checking available rollbacks immediately after
        // installing a package with rollback enabled.
        CountDownLatch latch = new CountDownLatch(1);
        getHandler().post(() -> latch.countDown());
        try {
            latch.await();
        } catch (InterruptedException ie) {
            throw new IllegalStateException("RollbackManagerHandlerThread interrupted");
        }

        synchronized (mLock) {
        synchronized (mLock) {
            List<RollbackInfo> rollbacks = new ArrayList<>();
            List<RollbackInfo> rollbacks = new ArrayList<>();
            for (int i = 0; i < mRollbacks.size(); ++i) {
            for (int i = 0; i < mRollbacks.size(); ++i) {
@@ -306,6 +282,15 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    rollbacks.add(rollback.info);
                    rollbacks.add(rollback.info);
                }
                }
            }
            }

            // Also return new rollbacks for which the PackageRollbackInfo is complete.
            for (NewRollback newRollback : mNewRollbacks) {
                if (newRollback.rollback.info.getPackages().size()
                        == newRollback.packageSessionIds.length
                        && !newRollback.isCancelled) {
                    rollbacks.add(newRollback.rollback.info);
                }
            }
            return new ParceledListSlice<>(rollbacks);
            return new ParceledListSlice<>(rollbacks);
        }
        }
    }
    }
@@ -562,6 +547,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                    }
                    }
                }
                }
            }
            }
            for (NewRollback newRollback : mNewRollbacks) {
                for (PackageRollbackInfo info : newRollback.rollback.info.getPackages()) {
                    if (info.getPackageName().equals(packageName)) {
                        newRollback.isCancelled = true;
                        break;
                    }
                }
            }
        }
        }
    }
    }