Merge \"Add a new API to improve VR thread scheduling.\" into nyc-mr1-dev
am: 5e261441d3
Change-Id: Ie7c734ca22abad05a4f0800a1dba9553eb7cbfef
This commit is contained in:
@@ -3705,6 +3705,7 @@ package android.app {
|
||||
method public void moveTaskToFront(int, int);
|
||||
method public void moveTaskToFront(int, int, android.os.Bundle);
|
||||
method public deprecated void restartPackage(java.lang.String);
|
||||
method public static void setVrThread(int);
|
||||
method public void setWatchHeapLimit(long);
|
||||
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
|
||||
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1
|
||||
|
||||
@@ -3841,6 +3841,7 @@ package android.app {
|
||||
method public void moveTaskToFront(int, int);
|
||||
method public void moveTaskToFront(int, int, android.os.Bundle);
|
||||
method public deprecated void restartPackage(java.lang.String);
|
||||
method public static void setVrThread(int);
|
||||
method public void setWatchHeapLimit(long);
|
||||
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
|
||||
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1
|
||||
|
||||
@@ -3705,6 +3705,7 @@ package android.app {
|
||||
method public void moveTaskToFront(int, int);
|
||||
method public void moveTaskToFront(int, int, android.os.Bundle);
|
||||
method public deprecated void restartPackage(java.lang.String);
|
||||
method public static void setVrThread(int);
|
||||
method public void setWatchHeapLimit(long);
|
||||
field public static final java.lang.String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
|
||||
field public static final int LOCK_TASK_MODE_LOCKED = 1; // 0x1
|
||||
|
||||
@@ -3624,6 +3624,24 @@ public class ActivityManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable more aggressive scheduling for latency-sensitive low-runtime VR threads. Only one
|
||||
* thread can be a VR thread in a process at a time, and that thread may be subject to
|
||||
* restrictions on the amount of time it can run.
|
||||
*
|
||||
* To reset the VR thread for an application, a tid of 0 can be passed.
|
||||
*
|
||||
* @see android.os.Process#myTid()
|
||||
* @param tid tid of the VR thread
|
||||
*/
|
||||
public static void setVrThread(int tid) {
|
||||
try {
|
||||
ActivityManagerNative.getDefault().setVrThread(tid);
|
||||
} catch (RemoteException e) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The AppTask allows you to manage your own application's tasks.
|
||||
* See {@link android.app.ActivityManager#getAppTasks()}
|
||||
|
||||
@@ -2996,6 +2996,13 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
reply.writeInt(result);
|
||||
return true;
|
||||
}
|
||||
case SET_VR_THREAD_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
final int tid = data.readInt();
|
||||
setVrThread(tid);
|
||||
reply.writeNoException();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.onTransact(code, data, reply, flags);
|
||||
@@ -7031,5 +7038,19 @@ class ActivityManagerProxy implements IActivityManager
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVrThread(int tid)
|
||||
throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeInt(tid);
|
||||
mRemote.transact(SET_VR_THREAD_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
return;
|
||||
}
|
||||
|
||||
private IBinder mRemote;
|
||||
}
|
||||
|
||||
@@ -658,6 +658,8 @@ public interface IActivityManager extends IInterface {
|
||||
IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)
|
||||
throws RemoteException;
|
||||
|
||||
public void setVrThread(int tid) throws RemoteException;
|
||||
|
||||
/*
|
||||
* Private non-Binder interfaces
|
||||
*/
|
||||
@@ -1044,4 +1046,5 @@ public interface IActivityManager extends IInterface {
|
||||
int START_CONFIRM_DEVICE_CREDENTIAL_INTENT = IBinder.FIRST_CALL_TRANSACTION + 374;
|
||||
int SEND_IDLE_JOB_TRIGGER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 375;
|
||||
int SEND_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 376;
|
||||
int SET_VR_THREAD_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 377;
|
||||
}
|
||||
|
||||
@@ -322,6 +322,13 @@ public class Process {
|
||||
*/
|
||||
public static final int SCHED_IDLE = 5;
|
||||
|
||||
/**
|
||||
* Reset scheduler choice on fork.
|
||||
* @hide
|
||||
*/
|
||||
public static final int SCHED_RESET_ON_FORK = 0x40000000;
|
||||
|
||||
|
||||
// Keep in sync with SP_* constants of enum type SchedPolicy
|
||||
// declared in system/core/include/cutils/sched_policy.h,
|
||||
// except THREAD_GROUP_DEFAULT does not correspond to any SP_* value.
|
||||
|
||||
@@ -2310,6 +2310,20 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
if (mInVrMode != vrMode) {
|
||||
mInVrMode = vrMode;
|
||||
mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
|
||||
if (r.app != null) {
|
||||
ProcessRecord proc = r.app;
|
||||
if (proc.vrThreadTid > 0) {
|
||||
if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
|
||||
if (mInVrMode == true) {
|
||||
Process.setThreadScheduler(proc.vrThreadTid,
|
||||
Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
|
||||
} else {
|
||||
Process.setThreadScheduler(proc.vrThreadTid,
|
||||
Process.SCHED_OTHER, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
|
||||
@@ -12508,6 +12522,34 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
}
|
||||
|
||||
public void setVrThread(int tid) {
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
|
||||
throw new UnsupportedOperationException("VR mode not supported on this device!");
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
ProcessRecord proc;
|
||||
synchronized (mPidsSelfLocked) {
|
||||
final int pid = Binder.getCallingPid();
|
||||
proc = mPidsSelfLocked.get(pid);
|
||||
if (proc != null && mInVrMode && tid >= 0) {
|
||||
// reset existing VR thread to CFS
|
||||
if (proc.vrThreadTid != 0) {
|
||||
Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
|
||||
}
|
||||
// add check to guarantee that tid belongs to pid?
|
||||
proc.vrThreadTid = tid;
|
||||
// promote to FIFO now if the tid is non-zero
|
||||
if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP && proc.vrThreadTid > 0) {
|
||||
Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
|
||||
}
|
||||
} else {
|
||||
//Slog.e("VR_FIFO", "Didn't set thread from setVrThread?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
|
||||
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
|
||||
@@ -20107,6 +20149,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
if (app.setSchedGroup != app.curSchedGroup) {
|
||||
int oldSchedGroup = app.setSchedGroup;
|
||||
app.setSchedGroup = app.curSchedGroup;
|
||||
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
|
||||
"Setting sched group of " + app.processName
|
||||
@@ -20132,6 +20175,23 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
long oldId = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Process.setProcessGroup(app.pid, processGroup);
|
||||
if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
|
||||
// do nothing if we already switched to RT
|
||||
if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
|
||||
// Switch VR thread for app to SCHED_FIFO
|
||||
if (mInVrMode && app.vrThreadTid != 0) {
|
||||
Process.setThreadScheduler(app.vrThreadTid,
|
||||
Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
|
||||
}
|
||||
}
|
||||
} else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
|
||||
app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
|
||||
// Reset VR thread to SCHED_OTHER
|
||||
// Safe to do even if we're not in VR mode
|
||||
if (app.vrThreadTid != 0) {
|
||||
Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Slog.w(TAG, "Failed setting process group of " + app.pid
|
||||
+ " to " + app.curSchedGroup);
|
||||
|
||||
@@ -97,6 +97,7 @@ final class ProcessRecord {
|
||||
int verifiedAdj; // The last adjustment that was verified as actually being set
|
||||
int curSchedGroup; // Currently desired scheduling class
|
||||
int setSchedGroup; // Last set to background scheduling class
|
||||
int vrThreadTid; // Thread currently set for VR scheduling
|
||||
int trimMemoryLevel; // Last selected memory trimming level
|
||||
int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
|
||||
int repProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
|
||||
@@ -293,6 +294,7 @@ final class ProcessRecord {
|
||||
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
|
||||
pw.print(" systemNoUi="); pw.print(systemNoUi);
|
||||
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
|
||||
pw.print(prefix); pw.print("vrThreadTid="); pw.print(vrThreadTid);
|
||||
pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
|
||||
pw.print(" repProcState="); pw.print(repProcState);
|
||||
pw.print(" pssProcState="); pw.print(pssProcState);
|
||||
|
||||
Reference in New Issue
Block a user