From 5ecf6fbaab9a800254fa8b5e413758d00420d76f Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Thu, 16 Apr 2020 11:57:07 +0100 Subject: [PATCH] Cherry pick: Batch calls to create app data for new users. DO NOT MERGE This significantly reduces IPC traffic between system server and installd, resulting in a performance increase in time to create a new user. See associated installd API change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1285395 Bug: 153171028 Test: create guest user manually, trace with Perfetto. Change-Id: I6551781e5c2e184b490c4939bd75333cdb48be55 --- .../java/com/android/server/pm/Installer.java | 25 +++++++++++++++++++ .../java/com/android/server/pm/Settings.java | 18 +++++-------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index 7cee286c44514..5ac86ca3f6daa 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -39,6 +39,7 @@ import dalvik.system.BlockGuard; import dalvik.system.VMRuntime; import java.io.FileDescriptor; +import java.util.Arrays; public class Installer extends SystemService { private static final String TAG = "Installer"; @@ -186,6 +187,30 @@ public class Installer extends SystemService { } } + /** + * Batched version of createAppData for use with multiple packages. + */ + public void createAppDataBatched(String[] uuids, String[] packageNames, int userId, int flags, + int[] appIds, String[] seInfos, int[] targetSdkVersions) throws InstallerException { + if (!checkBeforeRemote()) return; + final int batchSize = 256; + for (int i = 0; i < uuids.length; i += batchSize) { + int to = i + batchSize; + if (to > uuids.length) { + to = uuids.length; + } + + try { + mInstalld.createAppDataBatched(Arrays.copyOfRange(uuids, i, to), + Arrays.copyOfRange(packageNames, i, to), userId, flags, + Arrays.copyOfRange(appIds, i, to), Arrays.copyOfRange(seInfos, i, to), + Arrays.copyOfRange(targetSdkVersions, i, to)); + } catch (Exception e) { + throw InstallerException.from(e); + } + } + } + public void restoreconAppData(String uuid, String packageName, int userId, int flags, int appId, String seInfo) throws InstallerException { if (!checkBeforeRemote()) return; diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index f6e4e1f26bd5e..53c057a58a152 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4207,18 +4207,12 @@ public final class Settings { } } t.traceBegin("createAppData"); - for (int i = 0; i < packagesCount; i++) { - if (names[i] == null) { - continue; - } - // TODO: triage flags! - final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; - try { - installer.createAppData(volumeUuids[i], names[i], userHandle, flags, appIds[i], - seinfos[i], targetSdkVersions[i]); - } catch (InstallerException e) { - Slog.w(TAG, "Failed to prepare app data", e); - } + final int flags = StorageManager.FLAG_STORAGE_CE | StorageManager.FLAG_STORAGE_DE; + try { + installer.createAppDataBatched(volumeUuids, names, userHandle, flags, appIds, seinfos, + targetSdkVersions); + } catch (InstallerException e) { + Slog.w(TAG, "Failed to prepare app data", e); } t.traceEnd(); // createAppData synchronized (mLock) {