Loading services/core/java/com/android/server/PinnerService.java +126 −28 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; Loading @@ -61,7 +63,6 @@ import com.android.internal.app.ResolverActivity; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.SystemService.TargetUser; import com.android.server.wm.ActivityTaskManagerInternal; import dalvik.system.DexFile; Loading @@ -70,6 +71,7 @@ import dalvik.system.VMRuntime; import java.io.Closeable; import java.io.DataInputStream; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; Loading Loading @@ -100,12 +102,6 @@ public final class PinnerService extends SystemService { private static final int KEY_HOME = 1; private static final int KEY_ASSISTANT = 2; // Pin the camera application. Default to the system property only if the experiment phenotype // property is not set. private static boolean PROP_PIN_CAMERA = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", false)); // Pin using pinlist.meta when pinning apps. private static boolean PROP_PIN_PINLIST = SystemProperties.getBoolean( "pinner.use_pinlist", true); Loading Loading @@ -150,7 +146,13 @@ public final class PinnerService extends SystemService { /** * A set of {@link AppKey} that are configured to be pinned. */ private final ArraySet<Integer> mPinKeys = new ArraySet<>(); @GuardedBy("this") private ArraySet<Integer> mPinKeys; // Resource-configured pinner flags; private final boolean mConfiguredToPinCamera; private final boolean mConfiguredToPinHome; private final boolean mConfiguredToPinAssistant; private BinderService mBinderService; private PinnerHandler mPinnerHandler = null; Loading @@ -173,25 +175,13 @@ public final class PinnerService extends SystemService { super(context); mContext = context; boolean shouldPinCamera = context.getResources().getBoolean( mConfiguredToPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); boolean shouldPinHome = context.getResources().getBoolean( mConfiguredToPinHome = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerHomeApp); boolean shouldPinAssistant = context.getResources().getBoolean( mConfiguredToPinAssistant = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerAssistantApp); if (shouldPinCamera) { if (PROP_PIN_CAMERA) { mPinKeys.add(KEY_CAMERA); } else if (DEBUG) { Slog.i(TAG, "Pinner - skip pinning camera app"); } } if (shouldPinHome) { mPinKeys.add(KEY_HOME); } if (shouldPinAssistant) { mPinKeys.add(KEY_ASSISTANT); } mPinKeys = createPinKeys(); mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper()); mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); Loading Loading @@ -259,9 +249,10 @@ public final class PinnerService extends SystemService { * The other files pinned in onStart will not need to be updated. */ public void update(ArraySet<String> updatedPackages, boolean force) { ArraySet<Integer> pinKeys = getPinKeys(); int currentUser = ActivityManager.getCurrentUser(); for (int i = mPinKeys.size() - 1; i >= 0; i--) { int key = mPinKeys.valueAt(i); for (int i = pinKeys.size() - 1; i >= 0; i--) { int key = pinKeys.valueAt(i); ApplicationInfo info = getInfoForKey(key, currentUser); if (info != null && updatedPackages.contains(info.packageName)) { Slog.i(TAG, "Updating pinned files for " + info.packageName + " force=" + force); Loading Loading @@ -385,6 +376,14 @@ public final class PinnerService extends SystemService { } } private void unpinApps() { ArraySet<Integer> pinKeys = getPinKeys(); for (int i = pinKeys.size() - 1; i >= 0; i--) { int key = pinKeys.valueAt(i); unpinApp(key); } } private void unpinApp(@AppKey int key) { ArrayList<PinnedFile> pinnedAppFiles; synchronized (this) { Loading Loading @@ -490,9 +489,72 @@ public final class PinnerService extends SystemService { userHandle)); } private void sendPinAppsWithUpdatedKeysMessage(int userHandle) { mPinnerHandler.sendMessage(PooledLambda.obtainMessage(PinnerService::pinAppsWithUpdatedKeys, this, userHandle)); } private void sendUnpinAppsMessage() { mPinnerHandler.sendMessage(PooledLambda.obtainMessage(PinnerService::unpinApps, this)); } private ArraySet<Integer> createPinKeys() { ArraySet<Integer> pinKeys = new ArraySet<>(); // Pin the camera application. Default to the system property only if the experiment // phenotype property is not set. boolean shouldPinCamera = mConfiguredToPinCamera && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", false)); if (shouldPinCamera) { pinKeys.add(KEY_CAMERA); } else if (DEBUG) { Slog.i(TAG, "Pinner - skip pinning camera app"); } if (mConfiguredToPinHome) { pinKeys.add(KEY_HOME); } if (mConfiguredToPinAssistant) { pinKeys.add(KEY_ASSISTANT); } return pinKeys; } private synchronized ArraySet<Integer> getPinKeys() { return mPinKeys; } private void pinApps(int userHandle) { for (int i = mPinKeys.size() - 1; i >= 0; i--) { int key = mPinKeys.valueAt(i); pinAppsInternal(userHandle, false); } private void pinAppsWithUpdatedKeys(int userHandle) { pinAppsInternal(userHandle, true); } /** * @param updateKeys True if the pinned app list has to be updated. This is true only when * "pinner repin" shell command is requested. */ private void pinAppsInternal(int userHandle, boolean updateKeys) { if (updateKeys) { ArraySet<Integer> newKeys = createPinKeys(); synchronized (this) { // This code path demands preceding unpinApps() call. if (!mPinnedApps.isEmpty()) { Slog.e(TAG, "Attempted to update a list of apps, " + "but apps were already pinned. Skipping."); return; } mPinKeys = newKeys; } } ArraySet<Integer> currentPinKeys = getPinKeys(); for (int i = currentPinKeys.size() - 1; i >= 0; i--) { int key = currentPinKeys.valueAt(i); pinApp(key, userHandle, true /* force */); } } Loading Loading @@ -981,6 +1043,42 @@ public final class PinnerService extends SystemService { } } } private void repin() { sendUnpinAppsMessage(); // TODO(morrita): Consider supporting non-system user. sendPinAppsWithUpdatedKeysMessage(UserHandle.USER_SYSTEM); } private void printError(FileDescriptor out, String message) { PrintWriter writer = new PrintWriter(new FileOutputStream(out)); writer.println(message); writer.flush(); } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { if (args.length < 1) { printError(out, "Command is not given."); resultReceiver.send(-1, null); return; } String command = args[0]; switch (command) { case "repin": repin(); break; default: printError(out, String.format( "Unknown pinner command: %s. Supported commands: repin", command)); resultReceiver.send(-1, null); return; } resultReceiver.send(0, null); } } private static final class PinnedFile implements AutoCloseable { Loading Loading
services/core/java/com/android/server/PinnerService.java +126 −28 Original line number Diff line number Diff line Loading @@ -43,6 +43,8 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; Loading @@ -61,7 +63,6 @@ import com.android.internal.app.ResolverActivity; import com.android.internal.os.BackgroundThread; import com.android.internal.util.DumpUtils; import com.android.internal.util.function.pooled.PooledLambda; import com.android.server.SystemService.TargetUser; import com.android.server.wm.ActivityTaskManagerInternal; import dalvik.system.DexFile; Loading @@ -70,6 +71,7 @@ import dalvik.system.VMRuntime; import java.io.Closeable; import java.io.DataInputStream; import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; Loading Loading @@ -100,12 +102,6 @@ public final class PinnerService extends SystemService { private static final int KEY_HOME = 1; private static final int KEY_ASSISTANT = 2; // Pin the camera application. Default to the system property only if the experiment phenotype // property is not set. private static boolean PROP_PIN_CAMERA = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", false)); // Pin using pinlist.meta when pinning apps. private static boolean PROP_PIN_PINLIST = SystemProperties.getBoolean( "pinner.use_pinlist", true); Loading Loading @@ -150,7 +146,13 @@ public final class PinnerService extends SystemService { /** * A set of {@link AppKey} that are configured to be pinned. */ private final ArraySet<Integer> mPinKeys = new ArraySet<>(); @GuardedBy("this") private ArraySet<Integer> mPinKeys; // Resource-configured pinner flags; private final boolean mConfiguredToPinCamera; private final boolean mConfiguredToPinHome; private final boolean mConfiguredToPinAssistant; private BinderService mBinderService; private PinnerHandler mPinnerHandler = null; Loading @@ -173,25 +175,13 @@ public final class PinnerService extends SystemService { super(context); mContext = context; boolean shouldPinCamera = context.getResources().getBoolean( mConfiguredToPinCamera = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerCameraApp); boolean shouldPinHome = context.getResources().getBoolean( mConfiguredToPinHome = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerHomeApp); boolean shouldPinAssistant = context.getResources().getBoolean( mConfiguredToPinAssistant = context.getResources().getBoolean( com.android.internal.R.bool.config_pinnerAssistantApp); if (shouldPinCamera) { if (PROP_PIN_CAMERA) { mPinKeys.add(KEY_CAMERA); } else if (DEBUG) { Slog.i(TAG, "Pinner - skip pinning camera app"); } } if (shouldPinHome) { mPinKeys.add(KEY_HOME); } if (shouldPinAssistant) { mPinKeys.add(KEY_ASSISTANT); } mPinKeys = createPinKeys(); mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper()); mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); Loading Loading @@ -259,9 +249,10 @@ public final class PinnerService extends SystemService { * The other files pinned in onStart will not need to be updated. */ public void update(ArraySet<String> updatedPackages, boolean force) { ArraySet<Integer> pinKeys = getPinKeys(); int currentUser = ActivityManager.getCurrentUser(); for (int i = mPinKeys.size() - 1; i >= 0; i--) { int key = mPinKeys.valueAt(i); for (int i = pinKeys.size() - 1; i >= 0; i--) { int key = pinKeys.valueAt(i); ApplicationInfo info = getInfoForKey(key, currentUser); if (info != null && updatedPackages.contains(info.packageName)) { Slog.i(TAG, "Updating pinned files for " + info.packageName + " force=" + force); Loading Loading @@ -385,6 +376,14 @@ public final class PinnerService extends SystemService { } } private void unpinApps() { ArraySet<Integer> pinKeys = getPinKeys(); for (int i = pinKeys.size() - 1; i >= 0; i--) { int key = pinKeys.valueAt(i); unpinApp(key); } } private void unpinApp(@AppKey int key) { ArrayList<PinnedFile> pinnedAppFiles; synchronized (this) { Loading Loading @@ -490,9 +489,72 @@ public final class PinnerService extends SystemService { userHandle)); } private void sendPinAppsWithUpdatedKeysMessage(int userHandle) { mPinnerHandler.sendMessage(PooledLambda.obtainMessage(PinnerService::pinAppsWithUpdatedKeys, this, userHandle)); } private void sendUnpinAppsMessage() { mPinnerHandler.sendMessage(PooledLambda.obtainMessage(PinnerService::unpinApps, this)); } private ArraySet<Integer> createPinKeys() { ArraySet<Integer> pinKeys = new ArraySet<>(); // Pin the camera application. Default to the system property only if the experiment // phenotype property is not set. boolean shouldPinCamera = mConfiguredToPinCamera && DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT, "pin_camera", SystemProperties.getBoolean("pinner.pin_camera", false)); if (shouldPinCamera) { pinKeys.add(KEY_CAMERA); } else if (DEBUG) { Slog.i(TAG, "Pinner - skip pinning camera app"); } if (mConfiguredToPinHome) { pinKeys.add(KEY_HOME); } if (mConfiguredToPinAssistant) { pinKeys.add(KEY_ASSISTANT); } return pinKeys; } private synchronized ArraySet<Integer> getPinKeys() { return mPinKeys; } private void pinApps(int userHandle) { for (int i = mPinKeys.size() - 1; i >= 0; i--) { int key = mPinKeys.valueAt(i); pinAppsInternal(userHandle, false); } private void pinAppsWithUpdatedKeys(int userHandle) { pinAppsInternal(userHandle, true); } /** * @param updateKeys True if the pinned app list has to be updated. This is true only when * "pinner repin" shell command is requested. */ private void pinAppsInternal(int userHandle, boolean updateKeys) { if (updateKeys) { ArraySet<Integer> newKeys = createPinKeys(); synchronized (this) { // This code path demands preceding unpinApps() call. if (!mPinnedApps.isEmpty()) { Slog.e(TAG, "Attempted to update a list of apps, " + "but apps were already pinned. Skipping."); return; } mPinKeys = newKeys; } } ArraySet<Integer> currentPinKeys = getPinKeys(); for (int i = currentPinKeys.size() - 1; i >= 0; i--) { int key = currentPinKeys.valueAt(i); pinApp(key, userHandle, true /* force */); } } Loading Loading @@ -981,6 +1043,42 @@ public final class PinnerService extends SystemService { } } } private void repin() { sendUnpinAppsMessage(); // TODO(morrita): Consider supporting non-system user. sendPinAppsWithUpdatedKeysMessage(UserHandle.USER_SYSTEM); } private void printError(FileDescriptor out, String message) { PrintWriter writer = new PrintWriter(new FileOutputStream(out)); writer.println(message); writer.flush(); } @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) { if (args.length < 1) { printError(out, "Command is not given."); resultReceiver.send(-1, null); return; } String command = args[0]; switch (command) { case "repin": repin(); break; default: printError(out, String.format( "Unknown pinner command: %s. Supported commands: repin", command)); resultReceiver.send(-1, null); return; } resultReceiver.send(0, null); } } private static final class PinnedFile implements AutoCloseable { Loading