summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/PinnerService.java154
1 files changed, 126 insertions, 28 deletions
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index a3bcbbe25e88..ce8863cc9993 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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;
@@ -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);
@@ -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);
@@ -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) {
@@ -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 */);
}
}
@@ -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 {