diff options
4 files changed, 85 insertions, 4 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index c000bdf..c402329 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1057,6 +1057,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + String reason = data.readString(); + boolean res = killProcessesBelowForeground(reason); + reply.writeNoException(); + reply.writeInt(res ? 1 : 0); + return true; + } + case START_RUNNING_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); @@ -2910,6 +2919,18 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return res; } + @Override + public boolean killProcessesBelowForeground(String reason) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(reason); + mRemote.transact(KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION, data, reply, 0); + boolean res = reply.readInt() != 0; + data.recycle(); + reply.recycle(); + return res; + } public void startRunning(String pkg, String cls, String action, String indata) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index a809cc1..1d994d8 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -216,9 +216,10 @@ public interface IActivityManager extends IInterface { public void enterSafeMode() throws RemoteException; public void noteWakeupAlarm(IIntentSender sender) throws RemoteException; - + public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException; - + public boolean killProcessesBelowForeground(String reason) throws RemoteException; + // Special low-level communication with activity manager. public void startRunning(String pkg, String cls, String action, String data) throws RemoteException; @@ -573,4 +574,5 @@ public interface IActivityManager extends IInterface { int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140; int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141; int GET_MY_MEMORY_STATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+142; + int KILL_PROCESSES_BELOW_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+143; } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 84fcd5e..60749b3 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -6997,7 +6997,43 @@ public final class ActivityManagerService extends ActivityManagerNative } return killed; } - + + @Override + public boolean killProcessesBelowForeground(String reason) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("killProcessesBelowForeground() only available to system"); + } + + return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); + } + + private boolean killProcessesBelowAdj(int belowAdj, String reason) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("killProcessesBelowAdj() only available to system"); + } + + boolean killed = false; + synchronized (mPidsSelfLocked) { + final int size = mPidsSelfLocked.size(); + for (int i = 0; i < size; i++) { + final int pid = mPidsSelfLocked.keyAt(i); + final ProcessRecord proc = mPidsSelfLocked.valueAt(i); + if (proc == null) continue; + + final int adj = proc.setAdj; + if (adj > belowAdj && !proc.killedBackground) { + Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason); + EventLog.writeEvent( + EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason); + killed = true; + proc.killedBackground = true; + Process.killProcessQuiet(pid); + } + } + } + return killed; + } + public final void startRunning(String pkg, String cls, String action, String data) { synchronized(this) { diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 95666c0..067bf28 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -1587,7 +1587,16 @@ public class PackageManagerService extends IPackageManager.Stub { if (p != null) { final PackageSetting ps = (PackageSetting)p.mExtras; final SharedUserSetting suid = ps.sharedUser; - return suid != null ? suid.gids : ps.gids; + int[] gids = suid != null ? suid.gids : ps.gids; + + // include GIDs for any unenforced permissions + if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE)) { + final BasePermission basePerm = mSettings.mPermissions.get( + READ_EXTERNAL_STORAGE); + gids = appendInts(gids, basePerm.gids); + } + + return gids; } } // stupid thing to indicate an error. @@ -8890,6 +8899,19 @@ public class PackageManagerService extends IPackageManager.Stub { if (mSettings.mReadExternalStorageEnforcement != enforcement) { mSettings.mReadExternalStorageEnforcement = enforcement; mSettings.writeLPr(); + + // kill any non-foreground processes so we restart them and + // grant/revoke the GID. + final IActivityManager am = ActivityManagerNative.getDefault(); + if (am != null) { + final long token = Binder.clearCallingIdentity(); + try { + am.killProcessesBelowForeground("setPermissionEnforcement"); + } catch (RemoteException e) { + } finally { + Binder.restoreCallingIdentity(token); + } + } } } } else { |