1279d34af31af65b6233dbc225205871642a8514bRuben Brunk/* 2279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Copyright (C) 2017 The Android Open Source Project 3279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 4279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License"); 5279d34af31af65b6233dbc225205871642a8514bRuben Brunk * you may not use this file except in compliance with the License. 6279d34af31af65b6233dbc225205871642a8514bRuben Brunk * You may obtain a copy of the License at 7279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 8279d34af31af65b6233dbc225205871642a8514bRuben Brunk * http://www.apache.org/licenses/LICENSE-2.0 9279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 10279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Unless required by applicable law or agreed to in writing, software 11279d34af31af65b6233dbc225205871642a8514bRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS, 12279d34af31af65b6233dbc225205871642a8514bRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13279d34af31af65b6233dbc225205871642a8514bRuben Brunk * See the License for the specific language governing permissions and 14279d34af31af65b6233dbc225205871642a8514bRuben Brunk * limitations under the License 15279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 16279d34af31af65b6233dbc225205871642a8514bRuben Brunk 17279d34af31af65b6233dbc225205871642a8514bRuben Brunkpackage com.android.server.am; 18279d34af31af65b6233dbc225205871642a8514bRuben Brunk 19279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport android.content.ComponentName; 20279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport android.os.Process; 21279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport android.service.vr.IPersistentVrStateCallbacks; 22279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport android.util.Slog; 23148d7f4291d675fc17852d530be32b7dba06fc93Yi Jinimport android.util.proto.ProtoOutputStream; 24148d7f4291d675fc17852d530be32b7dba06fc93Yi Jinimport android.util.proto.ProtoUtils; 25148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin 26279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport com.android.server.LocalServices; 27279d34af31af65b6233dbc225205871642a8514bRuben Brunkimport com.android.server.vr.VrManagerInternal; 28279d34af31af65b6233dbc225205871642a8514bRuben Brunk 29279d34af31af65b6233dbc225205871642a8514bRuben Brunk/** 30279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Helper class for {@link ActivityManagerService} responsible for VrMode-related ActivityManager 31279d34af31af65b6233dbc225205871642a8514bRuben Brunk * functionality. 32279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 33279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Specifically, this class is responsible for: 34279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <ul> 35279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <li>Adjusting the scheduling of VR render threads while in VR mode. 36279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <li>Handling ActivityManager calls to set a VR or a 'persistent' VR thread. 37279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <li>Tracking the state of ActivityManagerService's view of VR-related behavior flags. 38279d34af31af65b6233dbc225205871642a8514bRuben Brunk * </ul> 39279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 40279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This is NOT the class that manages the system VR mode lifecycle. The class responsible for 41279d34af31af65b6233dbc225205871642a8514bRuben Brunk * handling everything related to VR mode state changes (e.g. the lifecycles of the associated 42279d34af31af65b6233dbc225205871642a8514bRuben Brunk * VrListenerService, VrStateCallbacks, VR HAL etc.) is VrManagerService. 43279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 44279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This class is exclusively for use by ActivityManagerService. Do not add callbacks or other 45279d34af31af65b6233dbc225205871642a8514bRuben Brunk * functionality to this for things that belong in VrManagerService. 46279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 47279d34af31af65b6233dbc225205871642a8514bRuben Brunkfinal class VrController { 48279d34af31af65b6233dbc225205871642a8514bRuben Brunk private static final String TAG = "VrController"; 49279d34af31af65b6233dbc225205871642a8514bRuben Brunk 50279d34af31af65b6233dbc225205871642a8514bRuben Brunk // VR state flags. 51279d34af31af65b6233dbc225205871642a8514bRuben Brunk private static final int FLAG_NON_VR_MODE = 0; 52279d34af31af65b6233dbc225205871642a8514bRuben Brunk private static final int FLAG_VR_MODE = 1; 53279d34af31af65b6233dbc225205871642a8514bRuben Brunk private static final int FLAG_PERSISTENT_VR_MODE = 2; 54279d34af31af65b6233dbc225205871642a8514bRuben Brunk 55148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin // Keep the enum lists in sync 56148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin private static int[] ORIG_ENUMS = new int[] { 57148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin FLAG_NON_VR_MODE, 58148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin FLAG_VR_MODE, 59148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin FLAG_PERSISTENT_VR_MODE, 60148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin }; 61148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin private static int[] PROTO_ENUMS = new int[] { 62148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin VrControllerProto.FLAG_NON_VR_MODE, 63148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin VrControllerProto.FLAG_VR_MODE, 64148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin VrControllerProto.FLAG_PERSISTENT_VR_MODE, 65148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin }; 66148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin 67279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Invariants maintained for mVrState 68279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 69279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Always true: 70279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - Only a single VR-related thread will have elevated scheduling priorities at a time 71279d34af31af65b6233dbc225205871642a8514bRuben Brunk // across all threads in all processes (and for all possible running modes). 72279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 73279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Always true while FLAG_PERSISTENT_VR_MODE is set: 74279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - An application has set a flag to run in persistent VR mode the next time VR mode is 75279d34af31af65b6233dbc225205871642a8514bRuben Brunk // entered. The device may or may not be in VR mode. 76279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - mVrState will contain FLAG_PERSISTENT_VR_MODE 77279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - An application may set a persistent VR thread that gains elevated scheduling 78279d34af31af65b6233dbc225205871642a8514bRuben Brunk // priorities via a call to setPersistentVrThread. 79279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - Calls to set a regular (non-persistent) VR thread via setVrThread will fail, and 80279d34af31af65b6233dbc225205871642a8514bRuben Brunk // thread that had previously elevated its scheduling priority in this way is returned 81279d34af31af65b6233dbc225205871642a8514bRuben Brunk // to its normal scheduling priority. 82279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 83279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Always true while FLAG_VR_MODE is set: 84279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - The current top application is running in VR mode. 85279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - mVrState will contain FLAG_VR_MODE 86279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 87279d34af31af65b6233dbc225205871642a8514bRuben Brunk // While FLAG_VR_MODE is set without FLAG_PERSISTENT_VR_MODE: 88279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - The current top application may set one of its threads to run at an elevated 89279d34af31af65b6233dbc225205871642a8514bRuben Brunk // scheduling priority via a call to setVrThread. 90279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 91279d34af31af65b6233dbc225205871642a8514bRuben Brunk // While FLAG_VR_MODE is set with FLAG_PERSISTENT_VR_MODE: 92279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - The current top application may NOT set one of its threads to run at an elevated 93279d34af31af65b6233dbc225205871642a8514bRuben Brunk // scheduling priority via a call to setVrThread (instead, the persistent VR thread will 94279d34af31af65b6233dbc225205871642a8514bRuben Brunk // be kept if an application has set one). 95279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 96279d34af31af65b6233dbc225205871642a8514bRuben Brunk // While mVrState == FLAG_NON_VR_MODE: 97279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - Calls to setVrThread will fail. 98279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - Calls to setPersistentVrThread will fail. 99279d34af31af65b6233dbc225205871642a8514bRuben Brunk // - No threads will have elevated scheduling priority for VR. 100279d34af31af65b6233dbc225205871642a8514bRuben Brunk // 101279d34af31af65b6233dbc225205871642a8514bRuben Brunk private int mVrState = FLAG_NON_VR_MODE; 102279d34af31af65b6233dbc225205871642a8514bRuben Brunk 103279d34af31af65b6233dbc225205871642a8514bRuben Brunk // The single VR render thread on the device that is given elevated scheduling priority. 104279d34af31af65b6233dbc225205871642a8514bRuben Brunk private int mVrRenderThreadTid = 0; 105279d34af31af65b6233dbc225205871642a8514bRuben Brunk 106279d34af31af65b6233dbc225205871642a8514bRuben Brunk private final Object mGlobalAmLock; 107279d34af31af65b6233dbc225205871642a8514bRuben Brunk 108279d34af31af65b6233dbc225205871642a8514bRuben Brunk private final IPersistentVrStateCallbacks mPersistentVrModeListener = 109279d34af31af65b6233dbc225205871642a8514bRuben Brunk new IPersistentVrStateCallbacks.Stub() { 110279d34af31af65b6233dbc225205871642a8514bRuben Brunk @Override 111279d34af31af65b6233dbc225205871642a8514bRuben Brunk public void onPersistentVrStateChanged(boolean enabled) { 112279d34af31af65b6233dbc225205871642a8514bRuben Brunk synchronized(mGlobalAmLock) { 113279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Note: This is the only place where mVrState should have its 114279d34af31af65b6233dbc225205871642a8514bRuben Brunk // FLAG_PERSISTENT_VR_MODE setting changed. 115279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (enabled) { 116279d34af31af65b6233dbc225205871642a8514bRuben Brunk setVrRenderThreadLocked(0, ProcessList.SCHED_GROUP_TOP_APP, true); 117279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrState |= FLAG_PERSISTENT_VR_MODE; 118279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else { 119279d34af31af65b6233dbc225205871642a8514bRuben Brunk setPersistentVrRenderThreadLocked(0, true); 120279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrState &= ~FLAG_PERSISTENT_VR_MODE; 121279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 122279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 123279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 124279d34af31af65b6233dbc225205871642a8514bRuben Brunk }; 125279d34af31af65b6233dbc225205871642a8514bRuben Brunk 126279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 127279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Create new VrController instance. 128279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 129279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param globalAmLock the global ActivityManagerService lock. 130279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 131279d34af31af65b6233dbc225205871642a8514bRuben Brunk public VrController(final Object globalAmLock) { 132279d34af31af65b6233dbc225205871642a8514bRuben Brunk mGlobalAmLock = globalAmLock; 133279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 134279d34af31af65b6233dbc225205871642a8514bRuben Brunk 135279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 136279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called when ActivityManagerService receives its systemReady call during boot. 137279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 138279d34af31af65b6233dbc225205871642a8514bRuben Brunk public void onSystemReady() { 139279d34af31af65b6233dbc225205871642a8514bRuben Brunk VrManagerInternal vrManagerInternal = LocalServices.getService(VrManagerInternal.class); 140279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (vrManagerInternal != null) { 141279d34af31af65b6233dbc225205871642a8514bRuben Brunk vrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener); 142279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 143279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 144279d34af31af65b6233dbc225205871642a8514bRuben Brunk 145279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 146279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called when ActivityManagerService's TOP_APP process has changed. 147279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 148279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Note: This must be called with the global ActivityManagerService lock held. 149279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 150279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param proc is the ProcessRecord of the process that entered or left the TOP_APP scheduling 151279d34af31af65b6233dbc225205871642a8514bRuben Brunk * group. 152279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 153279d34af31af65b6233dbc225205871642a8514bRuben Brunk public void onTopProcChangedLocked(ProcessRecord proc) { 154279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) { 155279d34af31af65b6233dbc225205871642a8514bRuben Brunk setVrRenderThreadLocked(proc.vrThreadTid, proc.curSchedGroup, true); 156279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else { 157279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc.vrThreadTid == mVrRenderThreadTid) { 158279d34af31af65b6233dbc225205871642a8514bRuben Brunk clearVrRenderThreadLocked(true); 159279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 160279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 161279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 162279d34af31af65b6233dbc225205871642a8514bRuben Brunk 163279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 164279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called when ActivityManagerService is switching VR mode for the TOP_APP process. 165279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 166279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param record the ActivityRecord of the activity changing the system VR mode. 167279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @return {@code true} if the VR state changed. 168279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 169279d34af31af65b6233dbc225205871642a8514bRuben Brunk public boolean onVrModeChanged(ActivityRecord record) { 170279d34af31af65b6233dbc225205871642a8514bRuben Brunk // This message means that the top focused activity enabled VR mode (or an activity 171279d34af31af65b6233dbc225205871642a8514bRuben Brunk // that previously set this has become focused). 172279d34af31af65b6233dbc225205871642a8514bRuben Brunk VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); 173279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (vrService == null) { 174279d34af31af65b6233dbc225205871642a8514bRuben Brunk // VR mode isn't supported on this device. 175279d34af31af65b6233dbc225205871642a8514bRuben Brunk return false; 176279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 177279d34af31af65b6233dbc225205871642a8514bRuben Brunk boolean vrMode; 178279d34af31af65b6233dbc225205871642a8514bRuben Brunk ComponentName requestedPackage; 179279d34af31af65b6233dbc225205871642a8514bRuben Brunk ComponentName callingPackage; 180279d34af31af65b6233dbc225205871642a8514bRuben Brunk int userId; 18116d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk int processId = -1; 182279d34af31af65b6233dbc225205871642a8514bRuben Brunk boolean changed = false; 183279d34af31af65b6233dbc225205871642a8514bRuben Brunk synchronized (mGlobalAmLock) { 184279d34af31af65b6233dbc225205871642a8514bRuben Brunk vrMode = record.requestedVrComponent != null; 185279d34af31af65b6233dbc225205871642a8514bRuben Brunk requestedPackage = record.requestedVrComponent; 186279d34af31af65b6233dbc225205871642a8514bRuben Brunk userId = record.userId; 187279d34af31af65b6233dbc225205871642a8514bRuben Brunk callingPackage = record.info.getComponentName(); 188279d34af31af65b6233dbc225205871642a8514bRuben Brunk 189279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Tell the VrController that a VR mode change is requested. 190279d34af31af65b6233dbc225205871642a8514bRuben Brunk changed = changeVrModeLocked(vrMode, record.app); 19116d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk 19216d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk if (record.app != null) { 19316d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk processId = record.app.pid; 19416d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk } 195279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 196279d34af31af65b6233dbc225205871642a8514bRuben Brunk 197279d34af31af65b6233dbc225205871642a8514bRuben Brunk // Tell VrManager that a VR mode changed is requested, VrManager will handle 198279d34af31af65b6233dbc225205871642a8514bRuben Brunk // notifying all non-AM dependencies if needed. 19916d2397e2d3da0e0fcd6e3d1ea14db4fd5e4e246Albert Chaulk vrService.setVrMode(vrMode, requestedPackage, userId, processId, callingPackage); 200279d34af31af65b6233dbc225205871642a8514bRuben Brunk return changed; 201279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 202279d34af31af65b6233dbc225205871642a8514bRuben Brunk 203279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 204279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called to set an application's VR thread. 205279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 206279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This will fail if the system is not in VR mode, the system has the persistent VR flag set, 207279d34af31af65b6233dbc225205871642a8514bRuben Brunk * or the scheduling group of the thread is not for the current top app. If this succeeds, any 208279d34af31af65b6233dbc225205871642a8514bRuben Brunk * previous VR thread will be returned to a normal sheduling priority; if this fails, the 209279d34af31af65b6233dbc225205871642a8514bRuben Brunk * scheduling for the previous thread will be unaffected. 210279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 211279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Note: This must be called with the global ActivityManagerService lock and the 212279d34af31af65b6233dbc225205871642a8514bRuben Brunk * mPidsSelfLocked object locks held. 213279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 214279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param tid the tid of the thread to set, or 0 to unset the current thread. 215279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param pid the pid of the process owning the thread to set. 216279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param proc the ProcessRecord of the process owning the thread to set. 217279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 218279d34af31af65b6233dbc225205871642a8514bRuben Brunk public void setVrThreadLocked(int tid, int pid, ProcessRecord proc) { 219279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (hasPersistentVrFlagSet()) { 220279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "VR thread cannot be set in persistent VR mode!"); 221279d34af31af65b6233dbc225205871642a8514bRuben Brunk return; 222279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 223279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc == null) { 224279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "Persistent VR thread not set, calling process doesn't exist!"); 225279d34af31af65b6233dbc225205871642a8514bRuben Brunk return; 226279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 227279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (tid != 0) { 228279d34af31af65b6233dbc225205871642a8514bRuben Brunk enforceThreadInProcess(tid, pid); 229279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 230279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!inVrMode()) { 231279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "VR thread cannot be set when not in VR mode!"); 232279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else { 233279d34af31af65b6233dbc225205871642a8514bRuben Brunk setVrRenderThreadLocked(tid, proc.curSchedGroup, false); 234279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 235279d34af31af65b6233dbc225205871642a8514bRuben Brunk proc.vrThreadTid = (tid > 0) ? tid : 0; 236279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 237279d34af31af65b6233dbc225205871642a8514bRuben Brunk 238279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 239279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called to set an application's persistent VR thread. 240279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 241279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This will fail if the system does not have the persistent VR flag set. If this succeeds, 242279d34af31af65b6233dbc225205871642a8514bRuben Brunk * any previous VR thread will be returned to a normal sheduling priority; if this fails, 243279d34af31af65b6233dbc225205871642a8514bRuben Brunk * the scheduling for the previous thread will be unaffected. 244279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 245279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Note: This must be called with the global ActivityManagerService lock and the 246279d34af31af65b6233dbc225205871642a8514bRuben Brunk * mPidsSelfLocked object locks held. 247279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 248279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param tid the tid of the thread to set, or 0 to unset the current thread. 249279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param pid the pid of the process owning the thread to set. 250279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param proc the ProcessRecord of the process owning the thread to set. 251279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 252279d34af31af65b6233dbc225205871642a8514bRuben Brunk public void setPersistentVrThreadLocked(int tid, int pid, ProcessRecord proc) { 253279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!hasPersistentVrFlagSet()) { 254279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "Persistent VR thread may only be set in persistent VR mode!"); 255279d34af31af65b6233dbc225205871642a8514bRuben Brunk return; 256279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 257279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc == null) { 258279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "Persistent VR thread not set, calling process doesn't exist!"); 259279d34af31af65b6233dbc225205871642a8514bRuben Brunk return; 260279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 261279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (tid != 0) { 262279d34af31af65b6233dbc225205871642a8514bRuben Brunk enforceThreadInProcess(tid, pid); 263279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 264279d34af31af65b6233dbc225205871642a8514bRuben Brunk setPersistentVrRenderThreadLocked(tid, false); 265279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 266279d34af31af65b6233dbc225205871642a8514bRuben Brunk 267279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 268279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Return {@code true} when UI features incompatible with VR mode should be disabled. 269279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 270279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Note: This must be called with the global ActivityManagerService lock held. 271279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 272279d34af31af65b6233dbc225205871642a8514bRuben Brunk public boolean shouldDisableNonVrUiLocked() { 273279d34af31af65b6233dbc225205871642a8514bRuben Brunk return mVrState != FLAG_NON_VR_MODE; 274279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 275279d34af31af65b6233dbc225205871642a8514bRuben Brunk 276279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 277279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Called when to update this VrController instance's state when the system VR mode is being 278279d34af31af65b6233dbc225205871642a8514bRuben Brunk * changed. 279279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 280279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>Note: This must be called with the global ActivityManagerService lock held. 281279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 282279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param vrMode {@code true} if the system VR mode is being enabled. 283279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param proc the ProcessRecord of the process enabling the system VR mode. 284279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 285279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @return {@code true} if our state changed. 286279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 287279d34af31af65b6233dbc225205871642a8514bRuben Brunk private boolean changeVrModeLocked(boolean vrMode, ProcessRecord proc) { 288279d34af31af65b6233dbc225205871642a8514bRuben Brunk final int oldVrState = mVrState; 289279d34af31af65b6233dbc225205871642a8514bRuben Brunk 290279d34af31af65b6233dbc225205871642a8514bRuben Brunk // This is the only place where mVrState should have its FLAG_VR_MODE setting 291279d34af31af65b6233dbc225205871642a8514bRuben Brunk // changed. 292279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (vrMode) { 293279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrState |= FLAG_VR_MODE; 294279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else { 295279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrState &= ~FLAG_VR_MODE; 296279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 297279d34af31af65b6233dbc225205871642a8514bRuben Brunk 298279d34af31af65b6233dbc225205871642a8514bRuben Brunk boolean changed = (oldVrState != mVrState); 299279d34af31af65b6233dbc225205871642a8514bRuben Brunk 300279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (changed) { 301279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc != null) { 302279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (proc.vrThreadTid > 0) { 303279d34af31af65b6233dbc225205871642a8514bRuben Brunk setVrRenderThreadLocked(proc.vrThreadTid, proc.curSchedGroup, false); 304279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 305279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else { 306279d34af31af65b6233dbc225205871642a8514bRuben Brunk clearVrRenderThreadLocked(false); 307279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 308279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 309279d34af31af65b6233dbc225205871642a8514bRuben Brunk return changed; 310279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 311279d34af31af65b6233dbc225205871642a8514bRuben Brunk 312279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 313279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Set the given thread as the new VR thread, and give it special scheduling priority. 314279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 315279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>If the current thread is this thread, do nothing. If the current thread is different from 316279d34af31af65b6233dbc225205871642a8514bRuben Brunk * the given thread, the current thread will be returned to a normal scheduling priority. 317279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 318279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param newTid the tid of the thread to set, or 0 to unset the current thread. 319279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param suppressLogs {@code true} if any error logging should be disabled. 320279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 321279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @return the tid of the thread configured to run at the scheduling priority for VR 322279d34af31af65b6233dbc225205871642a8514bRuben Brunk * mode after this call completes (this may be the previous thread). 323279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 324279d34af31af65b6233dbc225205871642a8514bRuben Brunk private int updateVrRenderThreadLocked(int newTid, boolean suppressLogs) { 325279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (mVrRenderThreadTid == newTid) { 326279d34af31af65b6233dbc225205871642a8514bRuben Brunk return mVrRenderThreadTid; 327279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 328279d34af31af65b6233dbc225205871642a8514bRuben Brunk 329279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (mVrRenderThreadTid > 0) { 330279d34af31af65b6233dbc225205871642a8514bRuben Brunk ActivityManagerService.scheduleAsRegularPriority(mVrRenderThreadTid, suppressLogs); 331279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrRenderThreadTid = 0; 332279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 333279d34af31af65b6233dbc225205871642a8514bRuben Brunk 334279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (newTid > 0) { 335279d34af31af65b6233dbc225205871642a8514bRuben Brunk mVrRenderThreadTid = newTid; 336279d34af31af65b6233dbc225205871642a8514bRuben Brunk ActivityManagerService.scheduleAsFifoPriority(mVrRenderThreadTid, suppressLogs); 337279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 338279d34af31af65b6233dbc225205871642a8514bRuben Brunk return mVrRenderThreadTid; 339279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 340279d34af31af65b6233dbc225205871642a8514bRuben Brunk 341279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 342279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Set special scheduling for the given application persistent VR thread, if allowed. 343279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 344279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This will fail if the system does not have the persistent VR flag set. If this succeeds, 345279d34af31af65b6233dbc225205871642a8514bRuben Brunk * any previous VR thread will be returned to a normal sheduling priority; if this fails, 346279d34af31af65b6233dbc225205871642a8514bRuben Brunk * the scheduling for the previous thread will be unaffected. 347279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 348279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param newTid the tid of the thread to set, or 0 to unset the current thread. 349279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param suppressLogs {@code true} if any error logging should be disabled. 350279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 351279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @return the tid of the thread configured to run at the scheduling priority for VR 352279d34af31af65b6233dbc225205871642a8514bRuben Brunk * mode after this call completes (this may be the previous thread). 353279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 354279d34af31af65b6233dbc225205871642a8514bRuben Brunk private int setPersistentVrRenderThreadLocked(int newTid, boolean suppressLogs) { 355279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!hasPersistentVrFlagSet()) { 356279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!suppressLogs) { 357279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "Failed to set persistent VR thread, " 358279d34af31af65b6233dbc225205871642a8514bRuben Brunk + "system not in persistent VR mode."); 359279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 360279d34af31af65b6233dbc225205871642a8514bRuben Brunk return mVrRenderThreadTid; 361279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 362279d34af31af65b6233dbc225205871642a8514bRuben Brunk return updateVrRenderThreadLocked(newTid, suppressLogs); 363279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 364279d34af31af65b6233dbc225205871642a8514bRuben Brunk 365279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 366279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Set special scheduling for the given application VR thread, if allowed. 367279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 368279d34af31af65b6233dbc225205871642a8514bRuben Brunk * <p>This will fail if the system is not in VR mode, the system has the persistent VR flag set, 369279d34af31af65b6233dbc225205871642a8514bRuben Brunk * or the scheduling group of the thread is not for the current top app. If this succeeds, any 370279d34af31af65b6233dbc225205871642a8514bRuben Brunk * previous VR thread will be returned to a normal sheduling priority; if this fails, the 371279d34af31af65b6233dbc225205871642a8514bRuben Brunk * scheduling for the previous thread will be unaffected. 372279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 373279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param newTid the tid of the thread to set, or 0 to unset the current thread. 374279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param schedGroup the current scheduling group of the thread to set. 375279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param suppressLogs {@code true} if any error logging should be disabled. 376279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 377279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @return the tid of the thread configured to run at the scheduling priority for VR 378279d34af31af65b6233dbc225205871642a8514bRuben Brunk * mode after this call completes (this may be the previous thread). 379279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 380279d34af31af65b6233dbc225205871642a8514bRuben Brunk private int setVrRenderThreadLocked(int newTid, int schedGroup, boolean suppressLogs) { 381279d34af31af65b6233dbc225205871642a8514bRuben Brunk boolean inVr = inVrMode(); 382279d34af31af65b6233dbc225205871642a8514bRuben Brunk boolean inPersistentVr = hasPersistentVrFlagSet(); 383279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!inVr || inPersistentVr || schedGroup != ProcessList.SCHED_GROUP_TOP_APP) { 384279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!suppressLogs) { 385279d34af31af65b6233dbc225205871642a8514bRuben Brunk String reason = "caller is not the current top application."; 386279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!inVr) { 387279d34af31af65b6233dbc225205871642a8514bRuben Brunk reason = "system not in VR mode."; 388279d34af31af65b6233dbc225205871642a8514bRuben Brunk } else if (inPersistentVr) { 389279d34af31af65b6233dbc225205871642a8514bRuben Brunk reason = "system in persistent VR mode."; 390279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 391279d34af31af65b6233dbc225205871642a8514bRuben Brunk Slog.w(TAG, "Failed to set VR thread, " + reason); 392279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 393279d34af31af65b6233dbc225205871642a8514bRuben Brunk return mVrRenderThreadTid; 394279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 395279d34af31af65b6233dbc225205871642a8514bRuben Brunk return updateVrRenderThreadLocked(newTid, suppressLogs); 396279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 397279d34af31af65b6233dbc225205871642a8514bRuben Brunk 398279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 399279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Unset any special scheduling used for the current VR render thread, and return it to normal 400279d34af31af65b6233dbc225205871642a8514bRuben Brunk * scheduling priority. 401279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 402279d34af31af65b6233dbc225205871642a8514bRuben Brunk * @param suppressLogs {@code true} if any error logging should be disabled. 403279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 404279d34af31af65b6233dbc225205871642a8514bRuben Brunk private void clearVrRenderThreadLocked(boolean suppressLogs) { 405279d34af31af65b6233dbc225205871642a8514bRuben Brunk updateVrRenderThreadLocked(0, suppressLogs); 406279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 407279d34af31af65b6233dbc225205871642a8514bRuben Brunk 408279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 409279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Check that the given tid is running in the process for the given pid, and throw an exception 410279d34af31af65b6233dbc225205871642a8514bRuben Brunk * if not. 411279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 412279d34af31af65b6233dbc225205871642a8514bRuben Brunk private void enforceThreadInProcess(int tid, int pid) { 413279d34af31af65b6233dbc225205871642a8514bRuben Brunk if (!Process.isThreadInProcess(pid, tid)) { 414279d34af31af65b6233dbc225205871642a8514bRuben Brunk throw new IllegalArgumentException("VR thread does not belong to process"); 415279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 416279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 417279d34af31af65b6233dbc225205871642a8514bRuben Brunk 418279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 419279d34af31af65b6233dbc225205871642a8514bRuben Brunk * True when the system is in VR mode. 420279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 421279d34af31af65b6233dbc225205871642a8514bRuben Brunk private boolean inVrMode() { 422279d34af31af65b6233dbc225205871642a8514bRuben Brunk return (mVrState & FLAG_VR_MODE) != 0; 423279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 424279d34af31af65b6233dbc225205871642a8514bRuben Brunk 425279d34af31af65b6233dbc225205871642a8514bRuben Brunk /** 426279d34af31af65b6233dbc225205871642a8514bRuben Brunk * True when the persistent VR mode flag has been set. 427279d34af31af65b6233dbc225205871642a8514bRuben Brunk * 428279d34af31af65b6233dbc225205871642a8514bRuben Brunk * Note: Currently this does not necessarily mean that the system is in VR mode. 429279d34af31af65b6233dbc225205871642a8514bRuben Brunk */ 430279d34af31af65b6233dbc225205871642a8514bRuben Brunk private boolean hasPersistentVrFlagSet() { 431279d34af31af65b6233dbc225205871642a8514bRuben Brunk return (mVrState & FLAG_PERSISTENT_VR_MODE) != 0; 432279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 433279d34af31af65b6233dbc225205871642a8514bRuben Brunk 434279d34af31af65b6233dbc225205871642a8514bRuben Brunk @Override 435279d34af31af65b6233dbc225205871642a8514bRuben Brunk public String toString() { 436279d34af31af65b6233dbc225205871642a8514bRuben Brunk return String.format("[VrState=0x%x,VrRenderThreadTid=%d]", mVrState, mVrRenderThreadTid); 437279d34af31af65b6233dbc225205871642a8514bRuben Brunk } 438148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin 439148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin void writeToProto(ProtoOutputStream proto, long fieldId) { 440148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin final long token = proto.start(fieldId); 441148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, VrControllerProto.VR_MODE, 442148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin mVrState, ORIG_ENUMS, PROTO_ENUMS); 443148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin proto.write(VrControllerProto.RENDER_THREAD_ID, mVrRenderThreadTid); 444148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin proto.end(token); 445148d7f4291d675fc17852d530be32b7dba06fc93Yi Jin } 446279d34af31af65b6233dbc225205871642a8514bRuben Brunk} 447