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