Loading services/core/java/com/android/server/am/ActivityManagerService.java +65 −207 Original line number Diff line number Diff line Loading @@ -333,7 +333,6 @@ import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionSession; import android.service.vr.IPersistentVrStateCallbacks; import android.telecom.TelecomManager; import android.text.TextUtils; import android.text.format.DateUtils; Loading Loading @@ -664,70 +663,8 @@ public class ActivityManagerService extends IActivityManager.Stub // default action automatically. Important for devices without direct input // devices. private boolean mShowDialogs = true; // VR state flags. static final int NON_VR_MODE = 0; static final int VR_MODE = 1; static final int PERSISTENT_VR_MODE = 2; private int mVrState = NON_VR_MODE; private int mTopAppVrThreadTid = 0; private int mPersistentVrThreadTid = 0; final IPersistentVrStateCallbacks mPersistentVrModeListener = new IPersistentVrStateCallbacks.Stub() { @Override public void onPersistentVrStateChanged(boolean enabled) { synchronized(ActivityManagerService.this) { // There are 4 possible cases here: // // Cases for enabled == true // Invariant: mVrState != PERSISTENT_VR_MODE; // This is guaranteed as only this function sets mVrState to PERSISTENT_VR_MODE // Invariant: mPersistentVrThreadTid == 0 // This is guaranteed by VrManagerService, which only emits callbacks when the // mode changes, and in setPersistentVrThread, which only sets // mPersistentVrThreadTid when mVrState = PERSISTENT_VR_MODE // Case 1: mTopAppVrThreadTid > 0 (someone called setVrThread successfully and is // the top-app) // We reset the app which currently has SCHED_FIFO (mPersistentVrThreadTid) to // SCHED_OTHER // Case 2: mTopAppVrThreadTid == 0 // Do nothing // // Cases for enabled == false // Invariant: mVrState == PERSISTENT_VR_MODE; // This is guaranteed by VrManagerService, which only emits callbacks when the // mode changes, and the only other assignment of mVrState outside of this // function checks if mVrState != PERSISTENT_VR_MODE // Invariant: mTopAppVrThreadTid == 0 // This is guaranteed in that mTopAppVrThreadTid is only set to a tid when // mVrState is VR_MODE, and is explicitly set to 0 when setPersistentVrThread is // called // mPersistentVrThreadTid > 0 (someone called setPersistentVrThread successfully) // 3. Reset mPersistentVrThreadTidto SCHED_OTHER // mPersistentVrThreadTid == 0 // 4. Do nothing if (enabled) { mVrState = PERSISTENT_VR_MODE; } else { // Leaving persistent mode implies leaving VR mode. mVrState = NON_VR_MODE; } if (mVrState == PERSISTENT_VR_MODE) { if (mTopAppVrThreadTid > 0) { // Ensure that when entering persistent VR mode the last top-app loses // SCHED_FIFO. setThreadScheduler(mTopAppVrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } } else if (mPersistentVrThreadTid > 0) { // Ensure that when leaving persistent VR mode we reschedule the high priority // persistent thread. setThreadScheduler(mPersistentVrThreadTid, SCHED_OTHER, 0); mPersistentVrThreadTid = 0; } } } }; private final VrController mVrController; // VR Compatibility Display Id. int mVrCompatibilityDisplayId = INVALID_DISPLAY; Loading Loading @@ -2447,53 +2384,7 @@ public class ActivityManagerService extends IActivityManager.Stub idleUids(); } break; case VR_MODE_CHANGE_MSG: { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { break; } final ActivityRecord r = (ActivityRecord) msg.obj; boolean vrMode; boolean inVrMode; ComponentName requestedPackage; ComponentName callingPackage; int userId; synchronized (ActivityManagerService.this) { vrMode = r.requestedVrComponent != null; inVrMode = mVrState != NON_VR_MODE; requestedPackage = r.requestedVrComponent; userId = r.userId; callingPackage = r.info.getComponentName(); if (vrMode != inVrMode) { // Don't change state if we're in persistent VR mode, but do update thread // priorities if necessary. if (mVrState != PERSISTENT_VR_MODE) { mVrState = vrMode ? VR_MODE : NON_VR_MODE; } mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), vrMode); if (r.app != null) { ProcessRecord proc = r.app; if (proc.vrThreadTid > 0) { if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { try { if (mVrState == VR_MODE) { setThreadScheduler(proc.vrThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); mTopAppVrThreadTid = proc.vrThreadTid; } else { setThreadScheduler(proc.vrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed to set scheduling policy, thread does" + " not exist:\n" + e); } } } } } } vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); mVrController.onVrModeChanged((ActivityRecord) msg.obj); } break; case NOTIFY_VR_SLEEPING_MSG: { notifyVrManagerOfSleepState(msg.arg1 != 0); Loading Loading @@ -2770,6 +2661,7 @@ public class ActivityManagerService extends IActivityManager.Stub mTaskChangeNotificationController = null; mUiHandler = injector.getUiHandler(null); mUserController = null; mVrController = null; } // Note: This method is invoked on the main thread but may need to attach various Loading Loading @@ -2856,6 +2748,8 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController = new UserController(this); mVrController = new VrController(this); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", ConfigurationInfo.GL_ES_VERSION_UNDEFINED); Loading Loading @@ -13263,23 +13157,12 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setVrThread(int tid) { if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } enforceSystemHasVrFeature(); synchronized (this) { if (tid > 0 && mVrState == PERSISTENT_VR_MODE) { Slog.e(TAG, "VR thread cannot be set in persistent VR mode!"); return; } ProcessRecord proc; synchronized (mPidsSelfLocked) { final int pid = Binder.getCallingPid(); proc = mPidsSelfLocked.get(pid); if (proc != null && mVrState == VR_MODE && tid >= 0) { proc.vrThreadTid = updateVrThreadLocked(proc, proc.vrThreadTid, pid, tid); mTopAppVrThreadTid = proc.vrThreadTid; } final ProcessRecord proc = mPidsSelfLocked.get(pid); mVrController.setVrThreadLocked(tid, pid, proc); } } } Loading @@ -13287,72 +13170,71 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setPersistentVrThread(int tid) { if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { String msg = "Permission Denial: setPersistentVrThread() from pid=" final String msg = "Permission Denial: setPersistentVrThread() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + permission.RESTRICTED_VR_ACCESS; Slog.w(TAG, msg); throw new SecurityException(msg); } if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } enforceSystemHasVrFeature(); synchronized (this) { // Disable any existing VR thread. if (mTopAppVrThreadTid > 0) { setThreadScheduler(mTopAppVrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } if (tid > 0 && mVrState != PERSISTENT_VR_MODE) { Slog.e(TAG, "Persistent VR thread may only be set in persistent VR mode!"); return; } ProcessRecord proc; synchronized (mPidsSelfLocked) { final int pid = Binder.getCallingPid(); mPersistentVrThreadTid = updateVrThreadLocked(null, mPersistentVrThreadTid, pid, tid); final ProcessRecord proc = mPidsSelfLocked.get(pid); mVrController.setPersistentVrThreadLocked(tid, pid, proc); } } } /** * Used by setVrThread and setPersistentVrThread to update a thread's priority. When proc is * non-null it must be in SCHED_GROUP_TOP_APP. When it is null, the tid is unconditionally * rescheduled. * Schedule the given thread a normal scheduling priority. * * @param newTid the tid of the thread to adjust the scheduling of. * @param suppressLogs {@code true} if any error logging should be disabled. * * @return {@code true} if this succeeded. */ private int updateVrThreadLocked(ProcessRecord proc, int lastTid, int pid, int tid) { // ensure the tid belongs to the process if (!isThreadInProcess(pid, tid)) { throw new IllegalArgumentException("VR thread does not belong to process"); } // reset existing VR thread to CFS if this thread still exists and belongs to // the calling process if (lastTid != 0 && isThreadInProcess(pid, lastTid)) { static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) { try { setThreadScheduler(lastTid, SCHED_OTHER, 0); Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0); return true; } catch (IllegalArgumentException e) { // Ignore this. Only occurs in race condition where previous VR thread // was destroyed during this method call. if (!suppressLogs) { Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); } } return false; } // promote to FIFO now if the tid is non-zero /** * Schedule the given thread an FIFO scheduling priority. * * @param newTid the tid of the thread to adjust the scheduling of. * @param suppressLogs {@code true} if any error logging should be disabled. * * @return {@code true} if this succeeded. */ static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) { try { if ((proc == null || proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) && tid > 0) { setThreadScheduler(tid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } return tid; Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); return true; } catch (IllegalArgumentException e) { Slog.e(TAG, "Failed to set scheduling policy, thread does" + " not exist:\n" + e); if (!suppressLogs) { Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); } } return false; } /** * Check that we have the features required for VR-related API calls, and throw an exception if * not. */ private void enforceSystemHasVrFeature() { if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } return lastTid; } @Override Loading Loading @@ -13944,10 +13826,7 @@ public class ActivityManagerService extends IActivityManager.Stub mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); mAssistUtils = new AssistUtils(mContext); VrManagerInternal vrManagerInternal = LocalServices.getService(VrManagerInternal.class); if (vrManagerInternal != null) { vrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); } mVrController.onSystemReady(); // Make sure we have the current profile info, since it is needed for security checks. mUserController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); Loading Loading @@ -15629,6 +15508,7 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mVoiceWakeLock" + mVoiceWakeLock); } } pw.println(" mVrController=" + mVrController); if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient || mOrigWaitForDebugger) { if (dumpPackage == null || dumpPackage.equals(mDebugApp) Loading Loading @@ -20055,7 +19935,7 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController.getCurrentUserIdLocked()); // TODO: If our config changes, should we auto dismiss any currently showing dialogs? mShowDialogs = shouldShowDialogs(mTempConfig, mVrState != NON_VR_MODE); mShowDialogs = shouldShowDialogs(mTempConfig); AttributeCache ac = AttributeCache.instance(); if (ac != null) { Loading Loading @@ -20285,15 +20165,16 @@ public class ActivityManagerService extends IActivityManager.Stub * A thought: SystemUI might also want to get told about this, the Power * dialog / global actions also might want different behaviors. */ private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) { private static boolean shouldShowDialogs(Configuration config) { final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH && config.navigation == Configuration.NAVIGATION_NONAV); int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)) && modeType != Configuration.UI_MODE_TYPE_TELEVISION); return inputMethodExists && uiModeSupportsDialogs && !inVrMode; && modeType != Configuration.UI_MODE_TYPE_TELEVISION && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); return inputMethodExists && uiModeSupportsDialogs; } @Override Loading Loading @@ -21596,32 +21477,14 @@ public class ActivityManagerService extends IActivityManager.Stub 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 (mVrState == VR_MODE && app.vrThreadTid != 0) { try { setThreadScheduler(app.vrThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); mTopAppVrThreadTid = app.vrThreadTid; } catch (IllegalArgumentException e) { // thread died, ignore } } mVrController.onTopProcChangedLocked(app); if (mUseFifoUiScheduling) { // Switch UI pipeline for app to SCHED_FIFO app.savedPriority = getThreadPriority(app.pid); try { setThreadScheduler(app.pid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } catch (IllegalArgumentException e) { // thread died, ignore } app.savedPriority = Process.getThreadPriority(app.pid); scheduleAsFifoPriority(app.pid, /* suppressLogs */true); if (app.renderThreadTid != 0) { try { setThreadScheduler(app.renderThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } catch (IllegalArgumentException e) { // thread died, ignore } scheduleAsFifoPriority(app.renderThreadTid, /* suppressLogs */true); if (DEBUG_OOM_ADJ) { Slog.d("UI_FIFO", "Set RenderThread (TID " + app.renderThreadTid + ") to FIFO"); Loading @@ -21645,12 +21508,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } 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) { setThreadScheduler(app.vrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } mVrController.onTopProcChangedLocked(app); if (mUseFifoUiScheduling) { // Reset UI pipeline to SCHED_OTHER setThreadScheduler(app.pid, SCHED_OTHER, 0); services/core/java/com/android/server/am/VrController.java 0 → 100644 +418 −0 File added.Preview size limit exceeded, changes collapsed. Show changes Loading
services/core/java/com/android/server/am/ActivityManagerService.java +65 −207 Original line number Diff line number Diff line Loading @@ -333,7 +333,6 @@ import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionSession; import android.service.vr.IPersistentVrStateCallbacks; import android.telecom.TelecomManager; import android.text.TextUtils; import android.text.format.DateUtils; Loading Loading @@ -664,70 +663,8 @@ public class ActivityManagerService extends IActivityManager.Stub // default action automatically. Important for devices without direct input // devices. private boolean mShowDialogs = true; // VR state flags. static final int NON_VR_MODE = 0; static final int VR_MODE = 1; static final int PERSISTENT_VR_MODE = 2; private int mVrState = NON_VR_MODE; private int mTopAppVrThreadTid = 0; private int mPersistentVrThreadTid = 0; final IPersistentVrStateCallbacks mPersistentVrModeListener = new IPersistentVrStateCallbacks.Stub() { @Override public void onPersistentVrStateChanged(boolean enabled) { synchronized(ActivityManagerService.this) { // There are 4 possible cases here: // // Cases for enabled == true // Invariant: mVrState != PERSISTENT_VR_MODE; // This is guaranteed as only this function sets mVrState to PERSISTENT_VR_MODE // Invariant: mPersistentVrThreadTid == 0 // This is guaranteed by VrManagerService, which only emits callbacks when the // mode changes, and in setPersistentVrThread, which only sets // mPersistentVrThreadTid when mVrState = PERSISTENT_VR_MODE // Case 1: mTopAppVrThreadTid > 0 (someone called setVrThread successfully and is // the top-app) // We reset the app which currently has SCHED_FIFO (mPersistentVrThreadTid) to // SCHED_OTHER // Case 2: mTopAppVrThreadTid == 0 // Do nothing // // Cases for enabled == false // Invariant: mVrState == PERSISTENT_VR_MODE; // This is guaranteed by VrManagerService, which only emits callbacks when the // mode changes, and the only other assignment of mVrState outside of this // function checks if mVrState != PERSISTENT_VR_MODE // Invariant: mTopAppVrThreadTid == 0 // This is guaranteed in that mTopAppVrThreadTid is only set to a tid when // mVrState is VR_MODE, and is explicitly set to 0 when setPersistentVrThread is // called // mPersistentVrThreadTid > 0 (someone called setPersistentVrThread successfully) // 3. Reset mPersistentVrThreadTidto SCHED_OTHER // mPersistentVrThreadTid == 0 // 4. Do nothing if (enabled) { mVrState = PERSISTENT_VR_MODE; } else { // Leaving persistent mode implies leaving VR mode. mVrState = NON_VR_MODE; } if (mVrState == PERSISTENT_VR_MODE) { if (mTopAppVrThreadTid > 0) { // Ensure that when entering persistent VR mode the last top-app loses // SCHED_FIFO. setThreadScheduler(mTopAppVrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } } else if (mPersistentVrThreadTid > 0) { // Ensure that when leaving persistent VR mode we reschedule the high priority // persistent thread. setThreadScheduler(mPersistentVrThreadTid, SCHED_OTHER, 0); mPersistentVrThreadTid = 0; } } } }; private final VrController mVrController; // VR Compatibility Display Id. int mVrCompatibilityDisplayId = INVALID_DISPLAY; Loading Loading @@ -2447,53 +2384,7 @@ public class ActivityManagerService extends IActivityManager.Stub idleUids(); } break; case VR_MODE_CHANGE_MSG: { VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); if (vrService == null) { break; } final ActivityRecord r = (ActivityRecord) msg.obj; boolean vrMode; boolean inVrMode; ComponentName requestedPackage; ComponentName callingPackage; int userId; synchronized (ActivityManagerService.this) { vrMode = r.requestedVrComponent != null; inVrMode = mVrState != NON_VR_MODE; requestedPackage = r.requestedVrComponent; userId = r.userId; callingPackage = r.info.getComponentName(); if (vrMode != inVrMode) { // Don't change state if we're in persistent VR mode, but do update thread // priorities if necessary. if (mVrState != PERSISTENT_VR_MODE) { mVrState = vrMode ? VR_MODE : NON_VR_MODE; } mShowDialogs = shouldShowDialogs(getGlobalConfiguration(), vrMode); if (r.app != null) { ProcessRecord proc = r.app; if (proc.vrThreadTid > 0) { if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { try { if (mVrState == VR_MODE) { setThreadScheduler(proc.vrThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); mTopAppVrThreadTid = proc.vrThreadTid; } else { setThreadScheduler(proc.vrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } } catch (IllegalArgumentException e) { Slog.w(TAG, "Failed to set scheduling policy, thread does" + " not exist:\n" + e); } } } } } } vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage); mVrController.onVrModeChanged((ActivityRecord) msg.obj); } break; case NOTIFY_VR_SLEEPING_MSG: { notifyVrManagerOfSleepState(msg.arg1 != 0); Loading Loading @@ -2770,6 +2661,7 @@ public class ActivityManagerService extends IActivityManager.Stub mTaskChangeNotificationController = null; mUiHandler = injector.getUiHandler(null); mUserController = null; mVrController = null; } // Note: This method is invoked on the main thread but may need to attach various Loading Loading @@ -2856,6 +2748,8 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController = new UserController(this); mVrController = new VrController(this); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", ConfigurationInfo.GL_ES_VERSION_UNDEFINED); Loading Loading @@ -13263,23 +13157,12 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setVrThread(int tid) { if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } enforceSystemHasVrFeature(); synchronized (this) { if (tid > 0 && mVrState == PERSISTENT_VR_MODE) { Slog.e(TAG, "VR thread cannot be set in persistent VR mode!"); return; } ProcessRecord proc; synchronized (mPidsSelfLocked) { final int pid = Binder.getCallingPid(); proc = mPidsSelfLocked.get(pid); if (proc != null && mVrState == VR_MODE && tid >= 0) { proc.vrThreadTid = updateVrThreadLocked(proc, proc.vrThreadTid, pid, tid); mTopAppVrThreadTid = proc.vrThreadTid; } final ProcessRecord proc = mPidsSelfLocked.get(pid); mVrController.setVrThreadLocked(tid, pid, proc); } } } Loading @@ -13287,72 +13170,71 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setPersistentVrThread(int tid) { if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { String msg = "Permission Denial: setPersistentVrThread() from pid=" final String msg = "Permission Denial: setPersistentVrThread() from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + " requires " + permission.RESTRICTED_VR_ACCESS; Slog.w(TAG, msg); throw new SecurityException(msg); } if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } enforceSystemHasVrFeature(); synchronized (this) { // Disable any existing VR thread. if (mTopAppVrThreadTid > 0) { setThreadScheduler(mTopAppVrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } if (tid > 0 && mVrState != PERSISTENT_VR_MODE) { Slog.e(TAG, "Persistent VR thread may only be set in persistent VR mode!"); return; } ProcessRecord proc; synchronized (mPidsSelfLocked) { final int pid = Binder.getCallingPid(); mPersistentVrThreadTid = updateVrThreadLocked(null, mPersistentVrThreadTid, pid, tid); final ProcessRecord proc = mPidsSelfLocked.get(pid); mVrController.setPersistentVrThreadLocked(tid, pid, proc); } } } /** * Used by setVrThread and setPersistentVrThread to update a thread's priority. When proc is * non-null it must be in SCHED_GROUP_TOP_APP. When it is null, the tid is unconditionally * rescheduled. * Schedule the given thread a normal scheduling priority. * * @param newTid the tid of the thread to adjust the scheduling of. * @param suppressLogs {@code true} if any error logging should be disabled. * * @return {@code true} if this succeeded. */ private int updateVrThreadLocked(ProcessRecord proc, int lastTid, int pid, int tid) { // ensure the tid belongs to the process if (!isThreadInProcess(pid, tid)) { throw new IllegalArgumentException("VR thread does not belong to process"); } // reset existing VR thread to CFS if this thread still exists and belongs to // the calling process if (lastTid != 0 && isThreadInProcess(pid, lastTid)) { static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) { try { setThreadScheduler(lastTid, SCHED_OTHER, 0); Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0); return true; } catch (IllegalArgumentException e) { // Ignore this. Only occurs in race condition where previous VR thread // was destroyed during this method call. if (!suppressLogs) { Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); } } return false; } // promote to FIFO now if the tid is non-zero /** * Schedule the given thread an FIFO scheduling priority. * * @param newTid the tid of the thread to adjust the scheduling of. * @param suppressLogs {@code true} if any error logging should be disabled. * * @return {@code true} if this succeeded. */ static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) { try { if ((proc == null || proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) && tid > 0) { setThreadScheduler(tid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } return tid; Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1); return true; } catch (IllegalArgumentException e) { Slog.e(TAG, "Failed to set scheduling policy, thread does" + " not exist:\n" + e); if (!suppressLogs) { Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e); } } return false; } /** * Check that we have the features required for VR-related API calls, and throw an exception if * not. */ private void enforceSystemHasVrFeature() { if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) { throw new UnsupportedOperationException("VR mode not supported on this device!"); } return lastTid; } @Override Loading Loading @@ -13944,10 +13826,7 @@ public class ActivityManagerService extends IActivityManager.Stub mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class); mAssistUtils = new AssistUtils(mContext); VrManagerInternal vrManagerInternal = LocalServices.getService(VrManagerInternal.class); if (vrManagerInternal != null) { vrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); } mVrController.onSystemReady(); // Make sure we have the current profile info, since it is needed for security checks. mUserController.onSystemReady(); mRecentTasks.onSystemReadyLocked(); Loading Loading @@ -15629,6 +15508,7 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mVoiceWakeLock" + mVoiceWakeLock); } } pw.println(" mVrController=" + mVrController); if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient || mOrigWaitForDebugger) { if (dumpPackage == null || dumpPackage.equals(mDebugApp) Loading Loading @@ -20055,7 +19935,7 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController.getCurrentUserIdLocked()); // TODO: If our config changes, should we auto dismiss any currently showing dialogs? mShowDialogs = shouldShowDialogs(mTempConfig, mVrState != NON_VR_MODE); mShowDialogs = shouldShowDialogs(mTempConfig); AttributeCache ac = AttributeCache.instance(); if (ac != null) { Loading Loading @@ -20285,15 +20165,16 @@ public class ActivityManagerService extends IActivityManager.Stub * A thought: SystemUI might also want to get told about this, the Power * dialog / global actions also might want different behaviors. */ private static boolean shouldShowDialogs(Configuration config, boolean inVrMode) { private static boolean shouldShowDialogs(Configuration config) { final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH && config.navigation == Configuration.NAVIGATION_NONAV); int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK; final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)) && modeType != Configuration.UI_MODE_TYPE_TELEVISION); return inputMethodExists && uiModeSupportsDialogs && !inVrMode; && modeType != Configuration.UI_MODE_TYPE_TELEVISION && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET); return inputMethodExists && uiModeSupportsDialogs; } @Override Loading Loading @@ -21596,32 +21477,14 @@ public class ActivityManagerService extends IActivityManager.Stub 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 (mVrState == VR_MODE && app.vrThreadTid != 0) { try { setThreadScheduler(app.vrThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); mTopAppVrThreadTid = app.vrThreadTid; } catch (IllegalArgumentException e) { // thread died, ignore } } mVrController.onTopProcChangedLocked(app); if (mUseFifoUiScheduling) { // Switch UI pipeline for app to SCHED_FIFO app.savedPriority = getThreadPriority(app.pid); try { setThreadScheduler(app.pid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } catch (IllegalArgumentException e) { // thread died, ignore } app.savedPriority = Process.getThreadPriority(app.pid); scheduleAsFifoPriority(app.pid, /* suppressLogs */true); if (app.renderThreadTid != 0) { try { setThreadScheduler(app.renderThreadTid, SCHED_FIFO | SCHED_RESET_ON_FORK, 1); } catch (IllegalArgumentException e) { // thread died, ignore } scheduleAsFifoPriority(app.renderThreadTid, /* suppressLogs */true); if (DEBUG_OOM_ADJ) { Slog.d("UI_FIFO", "Set RenderThread (TID " + app.renderThreadTid + ") to FIFO"); Loading @@ -21645,12 +21508,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } 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) { setThreadScheduler(app.vrThreadTid, SCHED_OTHER, 0); mTopAppVrThreadTid = 0; } mVrController.onTopProcChangedLocked(app); if (mUseFifoUiScheduling) { // Reset UI pipeline to SCHED_OTHER setThreadScheduler(app.pid, SCHED_OTHER, 0);
services/core/java/com/android/server/am/VrController.java 0 → 100644 +418 −0 File added.Preview size limit exceeded, changes collapsed. Show changes