Loading core/java/android/content/pm/IPackageManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -791,4 +791,6 @@ interface IPackageManager { void setKeepUninstalledPackages(in List<String> packageList); boolean[] canPackageQuery(String sourcePackageName, in String[] targetPackageNames, int userId); boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler); } services/core/java/com/android/server/pm/PackageManagerService.java +31 −0 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; Loading Loading @@ -6295,6 +6296,36 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } /** * Wait for the handler to finish handling all pending messages. * @param timeoutMillis Maximum time in milliseconds to wait. * @param forBackgroundHandler Whether to wait for the background handler instead. * @return True if all the waiting messages in the handler has been handled. * False if timeout. */ @Override public boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler) { final CountDownLatch latch = new CountDownLatch(1); if (forBackgroundHandler) { mBackgroundHandler.post(latch::countDown); } else { mHandler.post(latch::countDown); } final long endTimeMillis = System.currentTimeMillis() + timeoutMillis; while (latch.getCount() > 0) { try { final long remainingTimeMillis = endTimeMillis - System.currentTimeMillis(); if (remainingTimeMillis <= 0) { return false; } return latch.await(remainingTimeMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // ignore and retry } } return true; } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { Loading services/core/java/com/android/server/pm/PackageManagerShellCommand.java +50 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,10 @@ class PackageManagerShellCommand extends ShellCommand { return runSetSilentUpdatesPolicy(); case "get-app-metadata": return runGetAppMetadata(); case "wait-for-handler": return runWaitForHandler(/* forBackgroundHandler= */ false); case "wait-for-background-handler": return runWaitForHandler(/* forBackgroundHandler= */ true); default: { if (ART_SERVICE_COMMANDS.contains(cmd)) { if (DexOptHelper.useArtService()) { Loading Loading @@ -3601,6 +3605,40 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } private int runWaitForHandler(boolean forBackgroundHandler) { final PrintWriter pw = getOutPrintWriter(); long timeoutMillis = 60000; // default timeout is 60 seconds String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--timeout": timeoutMillis = Long.parseLong(getNextArgRequired()); break; default: pw.println("Error: Unknown option: " + opt); return -1; } } if (timeoutMillis <= 0) { pw.println("Error: --timeout value must be positive: " + timeoutMillis); return -1; } final boolean success; try { success = mInterface.waitForHandler(timeoutMillis, forBackgroundHandler); } catch (RemoteException e) { pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]"); return -1; } if (success) { pw.println("Success"); return 0; } else { pw.println("Timeout. PackageManager handlers are still busy."); return -1; } } private int runArtServiceCommand() { try (var in = ParcelFileDescriptor.dup(getInFileDescriptor()); var out = ParcelFileDescriptor.dup(getOutFileDescriptor()); Loading Loading @@ -4427,6 +4465,18 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" --reset: restore the installer and throttle time to the default, and"); pw.println(" clear tracks of silent updates in the system."); pw.println(""); pw.println(" wait-for-handler --timeout <MILLIS>"); pw.println(" Wait for a given amount of time till the package manager handler finishes"); pw.println(" handling all pending messages."); pw.println(" --timeout: wait for a given number of milliseconds. If the handler(s)"); pw.println(" fail to finish before the timeout, the command returns error."); pw.println(""); pw.println(" wait-for-background-handler --timeout <MILLIS>"); pw.println(" Wait for a given amount of time till the package manager's background"); pw.println(" handler finishes handling all pending messages."); pw.println(" --timeout: wait for a given number of milliseconds. If the handler(s)"); pw.println(" fail to finish before the timeout, the command returns error."); pw.println(""); if (DexOptHelper.useArtService()) { printArtServiceHelp(); } else { Loading Loading
core/java/android/content/pm/IPackageManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -791,4 +791,6 @@ interface IPackageManager { void setKeepUninstalledPackages(in List<String> packageList); boolean[] canPackageQuery(String sourcePackageName, in String[] targetPackageNames, int userId); boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler); }
services/core/java/com/android/server/pm/PackageManagerService.java +31 −0 Original line number Diff line number Diff line Loading @@ -279,6 +279,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; Loading Loading @@ -6295,6 +6296,36 @@ public class PackageManagerService implements PackageSender, TestUtilityService } } /** * Wait for the handler to finish handling all pending messages. * @param timeoutMillis Maximum time in milliseconds to wait. * @param forBackgroundHandler Whether to wait for the background handler instead. * @return True if all the waiting messages in the handler has been handled. * False if timeout. */ @Override public boolean waitForHandler(long timeoutMillis, boolean forBackgroundHandler) { final CountDownLatch latch = new CountDownLatch(1); if (forBackgroundHandler) { mBackgroundHandler.post(latch::countDown); } else { mHandler.post(latch::countDown); } final long endTimeMillis = System.currentTimeMillis() + timeoutMillis; while (latch.getCount() > 0) { try { final long remainingTimeMillis = endTimeMillis - System.currentTimeMillis(); if (remainingTimeMillis <= 0) { return false; } return latch.await(remainingTimeMillis, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { // ignore and retry } } return true; } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { Loading
services/core/java/com/android/server/pm/PackageManagerShellCommand.java +50 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,10 @@ class PackageManagerShellCommand extends ShellCommand { return runSetSilentUpdatesPolicy(); case "get-app-metadata": return runGetAppMetadata(); case "wait-for-handler": return runWaitForHandler(/* forBackgroundHandler= */ false); case "wait-for-background-handler": return runWaitForHandler(/* forBackgroundHandler= */ true); default: { if (ART_SERVICE_COMMANDS.contains(cmd)) { if (DexOptHelper.useArtService()) { Loading Loading @@ -3601,6 +3605,40 @@ class PackageManagerShellCommand extends ShellCommand { return 1; } private int runWaitForHandler(boolean forBackgroundHandler) { final PrintWriter pw = getOutPrintWriter(); long timeoutMillis = 60000; // default timeout is 60 seconds String opt; while ((opt = getNextOption()) != null) { switch (opt) { case "--timeout": timeoutMillis = Long.parseLong(getNextArgRequired()); break; default: pw.println("Error: Unknown option: " + opt); return -1; } } if (timeoutMillis <= 0) { pw.println("Error: --timeout value must be positive: " + timeoutMillis); return -1; } final boolean success; try { success = mInterface.waitForHandler(timeoutMillis, forBackgroundHandler); } catch (RemoteException e) { pw.println("Failure [" + e.getClass().getName() + " - " + e.getMessage() + "]"); return -1; } if (success) { pw.println("Success"); return 0; } else { pw.println("Timeout. PackageManager handlers are still busy."); return -1; } } private int runArtServiceCommand() { try (var in = ParcelFileDescriptor.dup(getInFileDescriptor()); var out = ParcelFileDescriptor.dup(getOutFileDescriptor()); Loading Loading @@ -4427,6 +4465,18 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" --reset: restore the installer and throttle time to the default, and"); pw.println(" clear tracks of silent updates in the system."); pw.println(""); pw.println(" wait-for-handler --timeout <MILLIS>"); pw.println(" Wait for a given amount of time till the package manager handler finishes"); pw.println(" handling all pending messages."); pw.println(" --timeout: wait for a given number of milliseconds. If the handler(s)"); pw.println(" fail to finish before the timeout, the command returns error."); pw.println(""); pw.println(" wait-for-background-handler --timeout <MILLIS>"); pw.println(" Wait for a given amount of time till the package manager's background"); pw.println(" handler finishes handling all pending messages."); pw.println(" --timeout: wait for a given number of milliseconds. If the handler(s)"); pw.println(" fail to finish before the timeout, the command returns error."); pw.println(""); if (DexOptHelper.useArtService()) { printArtServiceHelp(); } else { Loading