blob: d84fbc53c5f9b8bf730b497fed987cda4dc7cc7d [file] [log] [blame]
Ruben Brunke24b9a62016-02-16 21:38:24 -08001/**
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08002 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.vr;
17
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -080018import static android.view.Display.INVALID_DISPLAY;
19
Ruben Brunkc7be3be2016-04-01 17:07:51 -070020import android.Manifest;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -080021import android.app.ActivityManagerInternal;
Jeff Sharkey9765e442017-12-14 22:15:14 -070022import android.app.ActivityManagerInternal.ScreenObserver;
Ruben Brunk8820f942016-05-09 12:46:28 -070023import android.app.ActivityManager;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080024import android.app.AppOpsManager;
Julia Reynoldsb852e562017-06-06 16:14:18 -040025import android.app.INotificationManager;
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -070026import android.app.Vr2dDisplayProperties;
Ruben Brunk98576cf2016-03-07 18:54:28 -080027import android.app.NotificationManager;
Ruben Brunke24b9a62016-02-16 21:38:24 -080028import android.annotation.NonNull;
Steven Thomas68cc84f2017-06-08 16:55:04 -070029import android.content.BroadcastReceiver;
Ruben Brunke24b9a62016-02-16 21:38:24 -080030import android.content.ComponentName;
Ruben Brunk98576cf2016-03-07 18:54:28 -080031import android.content.ContentResolver;
32import android.content.Context;
Steven Thomas68cc84f2017-06-08 16:55:04 -070033import android.content.Intent;
34import android.content.IntentFilter;
Ruben Brunk98576cf2016-03-07 18:54:28 -080035import android.content.pm.ApplicationInfo;
36import android.content.pm.PackageManager;
37import android.content.pm.PackageManager.NameNotFoundException;
Santos Cordon2f22da72017-02-27 17:24:44 -080038import android.hardware.display.DisplayManager;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080039import android.os.Binder;
Ruben Brunke24b9a62016-02-16 21:38:24 -080040import android.os.Handler;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080041import android.os.IBinder;
Ruben Brunke24b9a62016-02-16 21:38:24 -080042import android.os.IInterface;
43import android.os.Looper;
Ruben Brunkc7be3be2016-04-01 17:07:51 -070044import android.os.Message;
45import android.os.RemoteCallbackList;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080046import android.os.RemoteException;
Julia Reynoldsb852e562017-06-06 16:14:18 -040047import android.os.ServiceManager;
Steven Thomas68cc84f2017-06-08 16:55:04 -070048import android.os.SystemProperties;
Ruben Brunk98576cf2016-03-07 18:54:28 -080049import android.os.UserHandle;
Ruben Brunke24b9a62016-02-16 21:38:24 -080050import android.provider.Settings;
Ruben Brunk98576cf2016-03-07 18:54:28 -080051import android.service.notification.NotificationListenerService;
Steven Thomasb70845c2017-03-16 14:32:37 -070052import android.service.vr.IPersistentVrStateCallbacks;
Ruben Brunke24b9a62016-02-16 21:38:24 -080053import android.service.vr.IVrListener;
Ruben Brunkc7be3be2016-04-01 17:07:51 -070054import android.service.vr.IVrManager;
55import android.service.vr.IVrStateCallbacks;
Ruben Brunke24b9a62016-02-16 21:38:24 -080056import android.service.vr.VrListenerService;
Ruben Brunk1f4f26b2016-08-02 14:21:36 -070057import android.text.TextUtils;
Svetoslav Ganove33f6132016-06-01 16:25:31 -070058import android.util.ArrayMap;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080059import android.util.ArraySet;
60import android.util.Slog;
Ruben Brunk8820f942016-05-09 12:46:28 -070061import android.util.SparseArray;
Fyodor Kupolovab781c22017-12-19 16:44:26 -080062
63import com.android.server.FgThread;
Adrian Roose99bc052017-11-20 17:55:31 +010064import com.android.server.wm.WindowManagerInternal;
Tarandeep Singh89a6c482017-11-21 14:26:11 -080065import android.view.inputmethod.InputMethodManagerInternal;
Santos Cordonc14513d2016-12-14 14:52:59 -080066
Ruben Brunke24b9a62016-02-16 21:38:24 -080067import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060068import com.android.internal.util.DumpUtils;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -080069import com.android.server.LocalServices;
Craig Donner99062592016-04-14 21:45:19 -070070import com.android.server.SystemConfig;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080071import com.android.server.SystemService;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080072import com.android.server.utils.ManagedApplicationService.PendingEvent;
Ruben Brunkd675f512017-10-03 15:39:41 -070073import com.android.server.utils.ManagedApplicationService.LogEvent;
74import com.android.server.utils.ManagedApplicationService.LogFormattable;
Ruben Brunke24b9a62016-02-16 21:38:24 -080075import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
76import com.android.server.utils.ManagedApplicationService;
77import com.android.server.utils.ManagedApplicationService.BinderChecker;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080078
Dan Sandlerdc34df52016-04-07 21:04:46 -040079import java.io.FileDescriptor;
80import java.io.PrintWriter;
Ruben Brunk98576cf2016-03-07 18:54:28 -080081import java.lang.StringBuilder;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070082import java.text.SimpleDateFormat;
Santos Cordone6d77232017-08-08 17:11:41 -070083import java.util.Arrays;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070084import java.util.ArrayDeque;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080085import java.util.ArrayList;
Ruben Brunk98576cf2016-03-07 18:54:28 -080086import java.util.Collection;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070087import java.util.Date;
Julia Reynoldsb852e562017-06-06 16:14:18 -040088import java.util.List;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080089import java.util.Objects;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080090
91/**
Ruben Brunke24b9a62016-02-16 21:38:24 -080092 * Service tracking whether VR mode is active, and notifying listening services of state changes.
93 * <p/>
94 * Services running in system server may modify the state of VrManagerService via the interface in
95 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
96 * interface given in VrStateListener.
97 * <p/>
98 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
99 * hardware/libhardware/modules/vr
100 * <p/>
101 * In general applications may enable or disable VR mode by calling
Ruben Brunk98576cf2016-03-07 18:54:28 -0800102 * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to
103 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800104 *
Elliot Waite54de7742017-01-11 15:30:35 -0800105 * @see android.service.vr.VrListenerService
106 * @see com.android.server.vr.VrManagerInternal
107 * @see com.android.server.vr.VrStateListener
Ruben Brunke24b9a62016-02-16 21:38:24 -0800108 *
109 * @hide
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800110 */
Jeff Sharkey9765e442017-12-14 22:15:14 -0700111public class VrManagerService extends SystemService
112 implements EnabledComponentChangeListener, ScreenObserver {
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800113
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800114 public static final String TAG = "VrManagerService";
Joe Onorato82ba91d2017-04-27 16:18:05 -0700115 static final boolean DBG = false;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800116
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700117 private static final int PENDING_STATE_DELAY_MS = 300;
Ruben Brunkd675f512017-10-03 15:39:41 -0700118 private static final int EVENT_LOG_SIZE = 64;
Ruben Brunk8820f942016-05-09 12:46:28 -0700119 private static final int INVALID_APPOPS_MODE = -1;
Ruben Brunk040484c2016-10-28 20:18:57 -0700120 /** Null set of sleep sleep flags. */
121 private static final int FLAG_NONE = 0;
122 /** Flag set when the device is not sleeping. */
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700123 private static final int FLAG_AWAKE = 1 << 0;
Ruben Brunk040484c2016-10-28 20:18:57 -0700124 /** Flag set when the screen has been turned on. */
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700125 private static final int FLAG_SCREEN_ON = 1 << 1;
126 /** Flag set when the keyguard is not active. */
127 private static final int FLAG_KEYGUARD_UNLOCKED = 1 << 2;
Ruben Brunk040484c2016-10-28 20:18:57 -0700128 /** Flag indicating that all system sleep flags have been set.*/
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700129 private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON | FLAG_KEYGUARD_UNLOCKED;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700130
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800131 private static native void initializeNative();
132 private static native void setVrModeNative(boolean enabled);
133
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800134 private final Object mLock = new Object();
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800135
136 private final IBinder mOverlayToken = new Binder();
137
Ruben Brunke24b9a62016-02-16 21:38:24 -0800138 // State protected by mLock
Ruben Brunk040484c2016-10-28 20:18:57 -0700139 private boolean mVrModeAllowed;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800140 private boolean mVrModeEnabled;
Zak Cohen56345f42017-01-26 13:54:28 -0800141 private boolean mPersistentVrModeEnabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400142 private boolean mRunning2dInVr;
143 private int mVrAppProcessId;
Ruben Brunke24b9a62016-02-16 21:38:24 -0800144 private EnabledComponentsObserver mComponentObserver;
145 private ManagedApplicationService mCurrentVrService;
Ruben Brunk52ea6622017-10-02 23:51:25 -0700146 private ManagedApplicationService mCurrentVrCompositorService;
Zak Cohen56345f42017-01-26 13:54:28 -0800147 private ComponentName mDefaultVrService;
Ruben Brunke24b9a62016-02-16 21:38:24 -0800148 private Context mContext;
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800149 private ComponentName mCurrentVrModeComponent;
150 private int mCurrentVrModeUser;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800151 private boolean mWasDefaultGranted;
152 private boolean mGuard;
Steven Thomasb70845c2017-03-16 14:32:37 -0700153 private final RemoteCallbackList<IVrStateCallbacks> mVrStateRemoteCallbacks =
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700154 new RemoteCallbackList<>();
Steven Thomasb70845c2017-03-16 14:32:37 -0700155 private final RemoteCallbackList<IPersistentVrStateCallbacks>
156 mPersistentVrStateRemoteCallbacks = new RemoteCallbackList<>();
Ruben Brunk8820f942016-05-09 12:46:28 -0700157 private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
158 private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700159 private VrState mPendingState;
Ruben Brunkd675f512017-10-03 15:39:41 -0700160 private boolean mLogLimitHit;
161 private final ArrayDeque<LogFormattable> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
Ruben Brunk8820f942016-05-09 12:46:28 -0700162 private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
Julia Reynoldsb852e562017-06-06 16:14:18 -0400163 private INotificationManager mNotificationManager;
Ruben Brunk040484c2016-10-28 20:18:57 -0700164 /** Tracks the state of the screen and keyguard UI.*/
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700165 private int mSystemSleepFlags = FLAG_AWAKE | FLAG_KEYGUARD_UNLOCKED;
Steven Thomas68cc84f2017-06-08 16:55:04 -0700166 /**
167 * Set when ACTION_USER_UNLOCKED is fired. We shouldn't try to bind to the
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700168 * vr service before then. This gets set only once the first time the user unlocks the device
169 * and stays true thereafter.
Steven Thomas68cc84f2017-06-08 16:55:04 -0700170 */
171 private boolean mUserUnlocked;
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700172 private Vr2dDisplay mVr2dDisplay;
Steven Thomas68cc84f2017-06-08 16:55:04 -0700173 private boolean mBootsToVr;
Steven Thomas1356ec92017-09-07 11:26:38 -0700174 private boolean mStandby;
175 private boolean mUseStandbyToExitVrMode;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800176
Ruben Brunkd675f512017-10-03 15:39:41 -0700177 // Handles events from the managed services (e.g. VrListenerService and any bound VR compositor
178 // service).
179 private final ManagedApplicationService.EventCallback mEventCallback
180 = new ManagedApplicationService.EventCallback() {
181 @Override
182 public void onServiceEvent(LogEvent event) {
183 logEvent(event);
184
185 ComponentName component = null;
186 synchronized (mLock) {
187 component = ((mCurrentVrService == null) ? null : mCurrentVrService.getComponent());
Steven Thomas9aedfb12017-12-06 19:41:07 -0800188
189 // If the VrCore main service was disconnected or the binding died we'll rebind
190 // automatically. Call focusedActivityChanged() once we rebind.
191 if (component != null && component.equals(event.component) &&
192 (event.event == LogEvent.EVENT_DISCONNECTED ||
193 event.event == LogEvent.EVENT_BINDING_DIED)) {
194 callFocusedActivityChangedLocked();
195 }
Ruben Brunkd675f512017-10-03 15:39:41 -0700196 }
197
198 // If not on an AIO device and we permanently stopped trying to connect to the
199 // VrListenerService (or don't have one bound), leave persistent VR mode and VR mode.
200 if (!mBootsToVr && event.event == LogEvent.EVENT_STOPPED_PERMANENTLY &&
201 (component == null || component.equals(event.component))) {
202 Slog.e(TAG, "VrListenerSevice has died permanently, leaving system VR mode.");
203 // We're not a native VR device. Leave VR + persistent mode.
204 setPersistentVrModeEnabled(false);
205 }
206 }
207 };
208
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700209 private static final int MSG_VR_STATE_CHANGE = 0;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700210 private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
Zak Cohen732aeb02017-01-29 14:19:52 -0800211 private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2;
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700212
Ruben Brunk040484c2016-10-28 20:18:57 -0700213 /**
214 * Set whether VR mode may be enabled.
215 * <p/>
216 * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode
217 * is again allowed to be enabled, the most recent cached state will be applied.
218 *
Ruben Brunk040484c2016-10-28 20:18:57 -0700219 */
Steven Thomas68cc84f2017-06-08 16:55:04 -0700220 private void updateVrModeAllowedLocked() {
Steven Thomas1356ec92017-09-07 11:26:38 -0700221 boolean ignoreSleepFlags = mBootsToVr && mUseStandbyToExitVrMode;
222 boolean disallowedByStandby = mStandby && mUseStandbyToExitVrMode;
223 boolean allowed = (mSystemSleepFlags == FLAG_ALL || ignoreSleepFlags) && mUserUnlocked
224 && !disallowedByStandby;
Ruben Brunk040484c2016-10-28 20:18:57 -0700225 if (mVrModeAllowed != allowed) {
226 mVrModeAllowed = allowed;
Joe Onorato82ba91d2017-04-27 16:18:05 -0700227 if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
Ruben Brunk040484c2016-10-28 20:18:57 -0700228 if (mVrModeAllowed) {
Steven Thomas68cc84f2017-06-08 16:55:04 -0700229 if (mBootsToVr) {
230 setPersistentVrModeEnabled(true);
231 }
Steven Thomas68cc84f2017-06-08 16:55:04 -0700232 if (mBootsToVr && !mVrModeEnabled) {
Albert Chaulk16d23972017-07-14 12:32:57 -0400233 setVrMode(true, mDefaultVrService, 0, -1, null);
Steven Thomas68cc84f2017-06-08 16:55:04 -0700234 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700235 } else {
Zak Cohen56345f42017-01-26 13:54:28 -0800236 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
237 // exit persistent VR mode when screen is turned off.
Zak Cohen732aeb02017-01-29 14:19:52 -0800238 setPersistentModeAndNotifyListenersLocked(false);
Zak Cohen56345f42017-01-26 13:54:28 -0800239
Ruben Brunk040484c2016-10-28 20:18:57 -0700240 // Set pending state to current state.
241 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
Albert Chaulk16d23972017-07-14 12:32:57 -0400242 ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
243 mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
Ruben Brunk040484c2016-10-28 20:18:57 -0700244 : null;
245
246 // Unbind current VR service and do necessary callbacks.
Albert Chaulk16d23972017-07-14 12:32:57 -0400247 updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
Ruben Brunk040484c2016-10-28 20:18:57 -0700248 }
249 }
250 }
251
Ruben Brunk040484c2016-10-28 20:18:57 -0700252 private void setScreenOn(boolean isScreenOn) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700253 setSystemState(FLAG_SCREEN_ON, isScreenOn);
254 }
255
Jeff Sharkey9765e442017-12-14 22:15:14 -0700256 @Override
257 public void onAwakeStateChanged(boolean isAwake) {
258 setSystemState(FLAG_AWAKE, isAwake);
259 }
260
261 @Override
262 public void onKeyguardStateChanged(boolean isShowing) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700263 setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
264 }
265
266 private void setSystemState(int flags, boolean isOn) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700267 synchronized(mLock) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700268 int oldState = mSystemSleepFlags;
269 if (isOn) {
270 mSystemSleepFlags |= flags;
Ruben Brunk040484c2016-10-28 20:18:57 -0700271 } else {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700272 mSystemSleepFlags &= ~flags;
Ruben Brunk040484c2016-10-28 20:18:57 -0700273 }
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700274 if (oldState != mSystemSleepFlags) {
275 if (DBG) Slog.d(TAG, "System state: " + getStateAsString());
276 updateVrModeAllowedLocked();
277 }
Steven Thomas68cc84f2017-06-08 16:55:04 -0700278 }
279 }
280
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700281 private String getStateAsString() {
282 return new StringBuilder()
283 .append((mSystemSleepFlags & FLAG_AWAKE) != 0 ? "awake, " : "")
284 .append((mSystemSleepFlags & FLAG_SCREEN_ON) != 0 ? "screen_on, " : "")
285 .append((mSystemSleepFlags & FLAG_KEYGUARD_UNLOCKED) != 0 ? "keyguard_off" : "")
286 .toString();
287 }
288
Steven Thomas68cc84f2017-06-08 16:55:04 -0700289 private void setUserUnlocked() {
290 synchronized(mLock) {
291 mUserUnlocked = true;
292 updateVrModeAllowedLocked();
Ruben Brunk040484c2016-10-28 20:18:57 -0700293 }
294 }
295
Steven Thomas1356ec92017-09-07 11:26:38 -0700296 private void setStandbyEnabled(boolean standby) {
297 synchronized(mLock) {
298 if (!mBootsToVr) {
299 Slog.e(TAG, "Attempting to set standby mode on a non-standalone device");
300 return;
301 }
302 mStandby = standby;
303 updateVrModeAllowedLocked();
304 }
305 }
306
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700307 private final Handler mHandler = new Handler() {
308 @Override
309 public void handleMessage(Message msg) {
310 switch(msg.what) {
311 case MSG_VR_STATE_CHANGE : {
312 boolean state = (msg.arg1 == 1);
Steven Thomasb70845c2017-03-16 14:32:37 -0700313 int i = mVrStateRemoteCallbacks.beginBroadcast();
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700314 while (i > 0) {
315 i--;
316 try {
Steven Thomasb70845c2017-03-16 14:32:37 -0700317 mVrStateRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700318 } catch (RemoteException e) {
319 // Noop
320 }
321 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700322 mVrStateRemoteCallbacks.finishBroadcast();
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700323 } break;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700324 case MSG_PENDING_VR_STATE_CHANGE : {
325 synchronized(mLock) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700326 if (mVrModeAllowed) {
327 VrManagerService.this.consumeAndApplyPendingStateLocked();
328 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700329 }
330 } break;
Zak Cohen732aeb02017-01-29 14:19:52 -0800331 case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : {
332 boolean state = (msg.arg1 == 1);
Steven Thomasb70845c2017-03-16 14:32:37 -0700333 int i = mPersistentVrStateRemoteCallbacks.beginBroadcast();
334 while (i > 0) {
335 i--;
336 try {
337 mPersistentVrStateRemoteCallbacks.getBroadcastItem(i)
338 .onPersistentVrStateChanged(state);
339 } catch (RemoteException e) {
340 // Noop
341 }
Zak Cohen732aeb02017-01-29 14:19:52 -0800342 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700343 mPersistentVrStateRemoteCallbacks.finishBroadcast();
Zak Cohen732aeb02017-01-29 14:19:52 -0800344 } break;
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700345 default :
346 throw new IllegalStateException("Unknown message type: " + msg.what);
347 }
348 }
349 };
350
Ruben Brunkd675f512017-10-03 15:39:41 -0700351 // Event used to log when settings are changed for dumpsys logs.
352 private static class SettingEvent implements LogFormattable {
353 public final long timestamp;
354 public final String what;
355
356 SettingEvent(String what) {
357 this.timestamp = System.currentTimeMillis();
358 this.what = what;
359 }
360
361 @Override
362 public String toLogString(SimpleDateFormat dateFormat) {
363 return dateFormat.format(new Date(timestamp)) + " " + what;
364 }
365 }
366
367 // Event used to track changes of the primary on-screen VR activity.
368 private static class VrState implements LogFormattable {
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700369 final boolean enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400370 final boolean running2dInVr;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700371 final int userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400372 final int processId;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700373 final ComponentName targetPackageName;
374 final ComponentName callingPackage;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700375 final long timestamp;
376 final boolean defaultPermissionsGranted;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700377
Albert Chaulk16d23972017-07-14 12:32:57 -0400378 VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
379 int processId, ComponentName callingPackage) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700380 this.enabled = enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400381 this.running2dInVr = running2dInVr;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700382 this.userId = userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400383 this.processId = processId;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700384 this.targetPackageName = targetPackageName;
385 this.callingPackage = callingPackage;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700386 this.defaultPermissionsGranted = false;
387 this.timestamp = System.currentTimeMillis();
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700388 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700389
Albert Chaulk16d23972017-07-14 12:32:57 -0400390 VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
391 int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700392 this.enabled = enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400393 this.running2dInVr = running2dInVr;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700394 this.userId = userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400395 this.processId = processId;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700396 this.targetPackageName = targetPackageName;
397 this.callingPackage = callingPackage;
398 this.defaultPermissionsGranted = defaultPermissionsGranted;
399 this.timestamp = System.currentTimeMillis();
400 }
Ruben Brunkd675f512017-10-03 15:39:41 -0700401
402 @Override
403 public String toLogString(SimpleDateFormat dateFormat) {
404 String tab = " ";
405 String newLine = "\n";
406 StringBuilder sb = new StringBuilder(dateFormat.format(new Date(timestamp)));
407 sb.append(tab);
408 sb.append("State changed to:");
409 sb.append(tab);
410 sb.append((enabled) ? "ENABLED" : "DISABLED");
411 sb.append(newLine);
412 if (enabled) {
413 sb.append(tab);
414 sb.append("User=");
415 sb.append(userId);
416 sb.append(newLine);
417 sb.append(tab);
418 sb.append("Current VR Activity=");
419 sb.append((callingPackage == null) ? "None" : callingPackage.flattenToString());
420 sb.append(newLine);
421 sb.append(tab);
422 sb.append("Bound VrListenerService=");
423 sb.append((targetPackageName == null) ? "None"
424 : targetPackageName.flattenToString());
425 sb.append(newLine);
426 if (defaultPermissionsGranted) {
427 sb.append(tab);
428 sb.append("Default permissions granted to the bound VrListenerService.");
429 sb.append(newLine);
430 }
431 }
432 return sb.toString();
433 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700434 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700435
Ruben Brunke24b9a62016-02-16 21:38:24 -0800436 private static final BinderChecker sBinderChecker = new BinderChecker() {
437 @Override
438 public IInterface asInterface(IBinder binder) {
439 return IVrListener.Stub.asInterface(binder);
440 }
441
442 @Override
443 public boolean checkType(IInterface service) {
444 return service instanceof IVrListener;
445 }
446 };
447
Ruben Brunk8820f942016-05-09 12:46:28 -0700448 private final class NotificationAccessManager {
449 private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>();
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700450 private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId =
451 new ArrayMap<>();
Ruben Brunk8820f942016-05-09 12:46:28 -0700452
453 public void update(Collection<String> packageNames) {
454 int currentUserId = ActivityManager.getCurrentUser();
455
Ruben Brunk8820f942016-05-09 12:46:28 -0700456 ArraySet<String> allowed = mAllowedPackages.get(currentUserId);
457 if (allowed == null) {
458 allowed = new ArraySet<>();
459 }
460
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700461 // Make sure we revoke notification access for listeners in other users
462 final int listenerCount = mNotificationAccessPackageToUserId.size();
463 for (int i = listenerCount - 1; i >= 0; i--) {
464 final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i);
465 if (grantUserId != currentUserId) {
466 String packageName = mNotificationAccessPackageToUserId.keyAt(i);
467 revokeNotificationListenerAccess(packageName, grantUserId);
468 revokeNotificationPolicyAccess(packageName);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000469 revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700470 mNotificationAccessPackageToUserId.removeAt(i);
471 }
472 }
473
Ruben Brunk8820f942016-05-09 12:46:28 -0700474 for (String pkg : allowed) {
475 if (!packageNames.contains(pkg)) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700476 revokeNotificationListenerAccess(pkg, currentUserId);
Ruben Brunk8820f942016-05-09 12:46:28 -0700477 revokeNotificationPolicyAccess(pkg);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000478 revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700479 mNotificationAccessPackageToUserId.remove(pkg);
Ruben Brunk8820f942016-05-09 12:46:28 -0700480 }
481 }
482 for (String pkg : packageNames) {
483 if (!allowed.contains(pkg)) {
484 grantNotificationPolicyAccess(pkg);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700485 grantNotificationListenerAccess(pkg, currentUserId);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000486 grantCoarseLocationPermissionIfNeeded(pkg, currentUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700487 mNotificationAccessPackageToUserId.put(pkg, currentUserId);
Ruben Brunk8820f942016-05-09 12:46:28 -0700488 }
489 }
490
491 allowed.clear();
492 allowed.addAll(packageNames);
493 mAllowedPackages.put(currentUserId, allowed);
494 }
495 }
496
Ruben Brunke24b9a62016-02-16 21:38:24 -0800497 /**
498 * Called when a user, package, or setting changes that could affect whether or not the
499 * currently bound VrListenerService is changed.
500 */
501 @Override
502 public void onEnabledComponentChanged() {
503 synchronized (mLock) {
Ruben Brunk8820f942016-05-09 12:46:28 -0700504 int currentUser = ActivityManager.getCurrentUser();
Ruben Brunk8820f942016-05-09 12:46:28 -0700505 // Update listeners
506 ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
507
508 ArraySet<String> enabledPackages = new ArraySet<>();
509 for (ComponentName n : enabledListeners) {
510 String pkg = n.getPackageName();
511 if (isDefaultAllowed(pkg)) {
512 enabledPackages.add(n.getPackageName());
513 }
514 }
515 mNotifAccessManager.update(enabledPackages);
516
Ruben Brunk040484c2016-10-28 20:18:57 -0700517 if (!mVrModeAllowed) {
518 return; // Don't do anything, we shouldn't be in VR mode.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800519 }
520
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700521 // If there is a pending state change, we'd better deal with that first
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800522 consumeAndApplyPendingStateLocked(false);
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700523
524 if (mCurrentVrService == null) {
525 return; // No active services
526 }
527
Ruben Brunke24b9a62016-02-16 21:38:24 -0800528 // There is an active service, update it if needed
Albert Chaulk16d23972017-07-14 12:32:57 -0400529 updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
530 mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
531 mVrAppProcessId, mCurrentVrModeComponent);
Ruben Brunke24b9a62016-02-16 21:38:24 -0800532 }
533 }
534
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700535 private final IVrManager mVrManager = new IVrManager.Stub() {
536
537 @Override
538 public void registerListener(IVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700539 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
540 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700541 if (cb == null) {
542 throw new IllegalArgumentException("Callback binder object is null.");
543 }
544
545 VrManagerService.this.addStateCallback(cb);
546 }
547
548 @Override
549 public void unregisterListener(IVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700550 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
551 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700552 if (cb == null) {
553 throw new IllegalArgumentException("Callback binder object is null.");
554 }
555
556 VrManagerService.this.removeStateCallback(cb);
557 }
558
559 @Override
Steven Thomasb70845c2017-03-16 14:32:37 -0700560 public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700561 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
562 Manifest.permission.ACCESS_VR_STATE);
Steven Thomasb70845c2017-03-16 14:32:37 -0700563 if (cb == null) {
564 throw new IllegalArgumentException("Callback binder object is null.");
565 }
566
567 VrManagerService.this.addPersistentStateCallback(cb);
568 }
569
570 @Override
571 public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700572 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
573 Manifest.permission.ACCESS_VR_STATE);
Steven Thomasb70845c2017-03-16 14:32:37 -0700574 if (cb == null) {
575 throw new IllegalArgumentException("Callback binder object is null.");
576 }
577
578 VrManagerService.this.removePersistentStateCallback(cb);
579 }
580
581 @Override
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700582 public boolean getVrModeState() {
Santos Cordone6d77232017-08-08 17:11:41 -0700583 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
584 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700585 return VrManagerService.this.getVrMode();
586 }
587
Dan Sandlerdc34df52016-04-07 21:04:46 -0400588 @Override
Santos Cordone6d77232017-08-08 17:11:41 -0700589 public boolean getPersistentVrModeEnabled() {
590 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
591 Manifest.permission.ACCESS_VR_STATE);
592 return VrManagerService.this.getPersistentVrMode();
593 }
594
595 @Override
Zak Cohen56345f42017-01-26 13:54:28 -0800596 public void setPersistentVrModeEnabled(boolean enabled) {
Santos Cordone6d77232017-08-08 17:11:41 -0700597 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
Zak Cohen56345f42017-01-26 13:54:28 -0800598 VrManagerService.this.setPersistentVrModeEnabled(enabled);
599 }
600
601 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700602 public void setVr2dDisplayProperties(
603 Vr2dDisplayProperties vr2dDisplayProp) {
Santos Cordone6d77232017-08-08 17:11:41 -0700604 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700605 VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -0700606 }
607
608 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700609 public int getVr2dDisplayId() {
610 return VrManagerService.this.getVr2dDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -0800611 }
612
613 @Override
Ruben Brunk52ea6622017-10-02 23:51:25 -0700614 public void setAndBindCompositor(String componentName) {
615 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
616 VrManagerService.this.setAndBindCompositor(
617 (componentName == null) ? null : ComponentName.unflattenFromString(componentName));
618 }
619
620 @Override
Steven Thomas1356ec92017-09-07 11:26:38 -0700621 public void setStandbyEnabled(boolean standby) {
622 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER);
623 VrManagerService.this.setStandbyEnabled(standby);
624 }
625
626 @Override
Tarandeep Singh89a6c482017-11-21 14:26:11 -0800627 public void setVrInputMethod(ComponentName componentName) {
628 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
629 InputMethodManagerInternal imm =
630 LocalServices.getService(InputMethodManagerInternal.class);
631 imm.startVrInputMethodNoCheck(componentName);
632 }
633
634 @Override
Dan Sandlerdc34df52016-04-07 21:04:46 -0400635 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600636 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
637
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700638 pw.println("********* Dump of VrManagerService *********");
Ruben Brunk040484c2016-10-28 20:18:57 -0700639 pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
Zak Cohen56345f42017-01-26 13:54:28 -0800640 pw.println("Persistent VR mode is currently: " +
641 ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
Ruben Brunkd675f512017-10-03 15:39:41 -0700642 pw.println("Currently bound VR listener service: "
Ruben Brunka25b93c2017-10-05 19:41:42 -0700643 + ((mCurrentVrService == null)
644 ? "None" : mCurrentVrService.getComponent().flattenToString()));
Ruben Brunk52ea6622017-10-02 23:51:25 -0700645 pw.println("Currently bound VR compositor service: "
646 + ((mCurrentVrCompositorService == null)
Ruben Brunkd675f512017-10-03 15:39:41 -0700647 ? "None" : mCurrentVrCompositorService.getComponent().flattenToString()));
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700648 pw.println("Previous state transitions:\n");
649 String tab = " ";
650 dumpStateTransitions(pw);
651 pw.println("\n\nRemote Callbacks:");
Steven Thomasb70845c2017-03-16 14:32:37 -0700652 int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
Dan Sandlerdc34df52016-04-07 21:04:46 -0400653 while(i-->0) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700654 pw.print(tab);
Steven Thomasb70845c2017-03-16 14:32:37 -0700655 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700656 if (i>0) pw.println(",");
Dan Sandlerdc34df52016-04-07 21:04:46 -0400657 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700658 mVrStateRemoteCallbacks.finishBroadcast();
659 pw.println("\n\nPersistent Vr State Remote Callbacks:");
660 i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
661 while(i-->0) {
662 pw.print(tab);
663 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
664 if (i>0) pw.println(",");
665 }
666 mPersistentVrStateRemoteCallbacks.finishBroadcast();
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700667 pw.println("\n");
668 pw.println("Installed VrListenerService components:");
669 int userId = mCurrentVrModeUser;
670 ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
671 if (installed == null || installed.size() == 0) {
672 pw.println("None");
673 } else {
674 for (ComponentName n : installed) {
675 pw.print(tab);
676 pw.println(n.flattenToString());
677 }
678 }
679 pw.println("Enabled VrListenerService components:");
680 ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
681 if (enabled == null || enabled.size() == 0) {
682 pw.println("None");
683 } else {
684 for (ComponentName n : enabled) {
685 pw.print(tab);
686 pw.println(n.flattenToString());
687 }
688 }
689 pw.println("\n");
690 pw.println("********* End of VrManagerService Dump *********");
Dan Sandlerdc34df52016-04-07 21:04:46 -0400691 }
692
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700693 };
694
Santos Cordone6d77232017-08-08 17:11:41 -0700695 /**
696 * Enforces that at lease one of the specified permissions is held by the caller.
697 * Throws SecurityException if none of the specified permissions are held.
698 *
699 * @param permissions One or more permissions to check against.
700 */
701 private void enforceCallerPermissionAnyOf(String... permissions) {
702 for (String permission : permissions) {
703 if (mContext.checkCallingOrSelfPermission(permission)
704 == PackageManager.PERMISSION_GRANTED) {
705 return;
706 }
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700707 }
Santos Cordone6d77232017-08-08 17:11:41 -0700708 throw new SecurityException("Caller does not hold at least one of the permissions: "
709 + Arrays.toString(permissions));
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700710 }
711
Ruben Brunke24b9a62016-02-16 21:38:24 -0800712 /**
713 * Implementation of VrManagerInternal. Callable only from system services.
714 */
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800715 private final class LocalService extends VrManagerInternal {
716 @Override
Albert Chaulk16d23972017-07-14 12:32:57 -0400717 public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800718 ComponentName callingPackage) {
Albert Chaulk16d23972017-07-14 12:32:57 -0400719 VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
Ruben Brunkaf9f0042016-06-15 17:08:35 -0700720 }
721
722 @Override
Ruben Brunk040484c2016-10-28 20:18:57 -0700723 public void onScreenStateChanged(boolean isScreenOn) {
724 VrManagerService.this.setScreenOn(isScreenOn);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800725 }
726
727 @Override
Ruben Brunk8f1d5cb2016-03-22 18:08:41 -0700728 public boolean isCurrentVrListener(String packageName, int userId) {
729 return VrManagerService.this.isCurrentVrListener(packageName, userId);
730 }
731
732 @Override
Ruben Brunke24b9a62016-02-16 21:38:24 -0800733 public int hasVrPackage(ComponentName packageName, int userId) {
734 return VrManagerService.this.hasVrPackage(packageName, userId);
735 }
Zak Cohen56345f42017-01-26 13:54:28 -0800736
737 @Override
738 public void setPersistentVrModeEnabled(boolean enabled) {
739 VrManagerService.this.setPersistentVrModeEnabled(enabled);
740 }
Zak Cohen732aeb02017-01-29 14:19:52 -0800741
742 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700743 public void setVr2dDisplayProperties(
744 Vr2dDisplayProperties compatDisplayProp) {
745 VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -0700746 }
747
748 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700749 public int getVr2dDisplayId() {
750 return VrManagerService.this.getVr2dDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -0800751 }
752
753 @Override
Steven Thomasb70845c2017-03-16 14:32:37 -0700754 public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
755 VrManagerService.this.addPersistentStateCallback(listener);
Zak Cohen732aeb02017-01-29 14:19:52 -0800756 }
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800757 }
758
759 public VrManagerService(Context context) {
760 super(context);
761 }
762
763 @Override
764 public void onStart() {
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800765 synchronized(mLock) {
766 initializeNative();
Ruben Brunke24b9a62016-02-16 21:38:24 -0800767 mContext = getContext();
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800768 }
769
Steven Thomas68cc84f2017-06-08 16:55:04 -0700770 mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
Steven Thomas1356ec92017-09-07 11:26:38 -0700771 mUseStandbyToExitVrMode = mBootsToVr
Steven Thomasd007c462017-11-13 16:31:37 -0800772 && SystemProperties.getBoolean("persist.vr.use_standby_to_exit_vr_mode", true);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800773 publishLocalService(VrManagerInternal.class, new LocalService());
Craig Donner8deb67c2017-02-07 18:10:32 -0800774 publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800775 }
776
Ruben Brunke24b9a62016-02-16 21:38:24 -0800777 @Override
778 public void onBootPhase(int phase) {
Ruben Brunk85070042016-03-21 12:10:38 -0700779 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Jeff Sharkey9765e442017-12-14 22:15:14 -0700780 LocalServices.getService(ActivityManagerInternal.class)
781 .registerScreenObserver(this);
782
Julia Reynoldsb852e562017-06-06 16:14:18 -0400783 mNotificationManager = INotificationManager.Stub.asInterface(
784 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800785 synchronized (mLock) {
786 Looper looper = Looper.getMainLooper();
787 Handler handler = new Handler(looper);
788 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
789 listeners.add(this);
790 mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
791 Settings.Secure.ENABLED_VR_LISTENERS, looper,
792 android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
793 VrListenerService.SERVICE_INTERFACE, mLock, listeners);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800794
Ruben Brunke24b9a62016-02-16 21:38:24 -0800795 mComponentObserver.rebuildAll();
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800796 }
Zak Cohen56345f42017-01-26 13:54:28 -0800797
798 //TODO: something more robust than picking the first one
799 ArraySet<ComponentName> defaultVrComponents =
800 SystemConfig.getInstance().getDefaultVrComponents();
801 if (defaultVrComponents.size() > 0) {
802 mDefaultVrService = defaultVrComponents.valueAt(0);
803 } else {
804 Slog.i(TAG, "No default vr listener service found.");
805 }
Santos Cordon2f22da72017-02-27 17:24:44 -0800806
807 DisplayManager dm =
808 (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700809 mVr2dDisplay = new Vr2dDisplay(
810 dm,
811 LocalServices.getService(ActivityManagerInternal.class),
812 LocalServices.getService(WindowManagerInternal.class),
813 mVrManager);
Santos Cordonc22c5632017-06-21 16:03:49 -0700814 mVr2dDisplay.init(getContext(), mBootsToVr);
Steven Thomas68cc84f2017-06-08 16:55:04 -0700815
816 IntentFilter intentFilter = new IntentFilter();
817 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
818 getContext().registerReceiver(new BroadcastReceiver() {
819 @Override
820 public void onReceive(Context context, Intent intent) {
821 if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
822 VrManagerService.this.setUserUnlocked();
823 }
824 }
825 }, intentFilter);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800826 }
827 }
828
Ruben Brunke24b9a62016-02-16 21:38:24 -0800829 @Override
830 public void onStartUser(int userHandle) {
831 synchronized (mLock) {
832 mComponentObserver.onUsersChanged();
833 }
834 }
835
836 @Override
837 public void onSwitchUser(int userHandle) {
Fyodor Kupolovab781c22017-12-19 16:44:26 -0800838 FgThread.getHandler().post(() -> {
839 synchronized (mLock) {
840 mComponentObserver.onUsersChanged();
841 }
842 });
Ruben Brunke24b9a62016-02-16 21:38:24 -0800843
844 }
845
846 @Override
847 public void onStopUser(int userHandle) {
848 synchronized (mLock) {
849 mComponentObserver.onUsersChanged();
850 }
851
852 }
853
854 @Override
855 public void onCleanupUser(int userHandle) {
856 synchronized (mLock) {
857 mComponentObserver.onUsersChanged();
858 }
859 }
860
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700861 private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
862 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
863
864 // If user changed drop restrictions for the old user.
865 if (oldUserId != newUserId) {
866 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
867 false, mOverlayToken, null, oldUserId);
868 }
869
870 // Apply the restrictions for the current user based on vr state
871 String[] exemptions = (exemptedPackage == null) ? new String[0] :
872 new String[] { exemptedPackage };
873
874 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
Ruben Brunk2781b412017-04-24 12:07:17 -0700875 mVrModeEnabled, mOverlayToken, exemptions, newUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700876 }
877
878 private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
879 String oldVrServicePackage, int oldUserId) {
880 // If VR state changed and we also have a VR service change.
881 if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
882 return;
883 }
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800884 final long identity = Binder.clearCallingIdentity();
885 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700886 // Set overlay exception state based on VR enabled and current service
887 updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800888 } finally {
889 Binder.restoreCallingIdentity(identity);
890 }
891 }
892
Ruben Brunke24b9a62016-02-16 21:38:24 -0800893 /**
894 * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
895 * the currently selected VR listener service. If the component selected for the VR listener
896 * service has changed, unbind the previous listener and bind the new listener (if enabled).
897 * <p/>
898 * Note: Must be called while holding {@code mLock}.
899 *
900 * @param enabled new state for VR mode.
Albert Chaulk16d23972017-07-14 12:32:57 -0400901 * @param running2dInVr true if we have a top-level 2D intent.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800902 * @param component new component to be bound as a VR listener.
903 * @param userId user owning the component to be bound.
Albert Chaulk16d23972017-07-14 12:32:57 -0400904 * @param processId the process hosting the activity specified by calling.
905 * @param calling the component currently using VR mode or a 2D intent.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800906 *
907 * @return {@code true} if the component/user combination specified is valid.
908 */
Albert Chaulk16d23972017-07-14 12:32:57 -0400909 private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
910 @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800911
912 boolean sendUpdatedCaller = false;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800913 final long identity = Binder.clearCallingIdentity();
914 try {
Ruben Brunke24b9a62016-02-16 21:38:24 -0800915
Ruben Brunk98576cf2016-03-07 18:54:28 -0800916 boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
917 EnabledComponentsObserver.NO_ERROR);
Ruben Brunk040484c2016-10-28 20:18:57 -0700918 boolean goingIntoVrMode = validUserComponent && enabled;
919 if (!mVrModeEnabled && !goingIntoVrMode) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700920 return validUserComponent; // Disabled -> Disabled transition does nothing.
921 }
Ruben Brunke24b9a62016-02-16 21:38:24 -0800922
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700923 String oldVrServicePackage = mCurrentVrService != null
924 ? mCurrentVrService.getComponent().getPackageName() : null;
925 final int oldUserId = mCurrentVrModeUser;
926
Ruben Brunk040484c2016-10-28 20:18:57 -0700927 // Notify system services and VR HAL of mode change.
928 changeVrModeLocked(goingIntoVrMode);
Ruben Brunk29931bc2016-03-11 00:24:26 -0800929
Ruben Brunk040484c2016-10-28 20:18:57 -0700930 boolean nothingChanged = false;
931 if (!goingIntoVrMode) {
932 // Not going into VR mode, unbind whatever is running
Ruben Brunk98576cf2016-03-07 18:54:28 -0800933 if (mCurrentVrService != null) {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800934 Slog.i(TAG, "Leaving VR mode, disconnecting "
935 + mCurrentVrService.getComponent() + " for user "
936 + mCurrentVrService.getUserId());
Ruben Brunk98576cf2016-03-07 18:54:28 -0800937 mCurrentVrService.disconnect();
Ruben Brunk52ea6622017-10-02 23:51:25 -0700938 updateCompositorServiceLocked(UserHandle.USER_NULL, null);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800939 mCurrentVrService = null;
Ruben Brunk040484c2016-10-28 20:18:57 -0700940 } else {
941 nothingChanged = true;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800942 }
943 } else {
Ruben Brunk040484c2016-10-28 20:18:57 -0700944 // Going into VR mode
Ruben Brunk98576cf2016-03-07 18:54:28 -0800945 if (mCurrentVrService != null) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700946 // Unbind any running service that doesn't match the latest component/user
947 // selection.
Ruben Brunk98576cf2016-03-07 18:54:28 -0800948 if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800949 Slog.i(TAG, "VR mode component changed to " + component
950 + ", disconnecting " + mCurrentVrService.getComponent()
951 + " for user " + mCurrentVrService.getUserId());
Ruben Brunk52ea6622017-10-02 23:51:25 -0700952 updateCompositorServiceLocked(UserHandle.USER_NULL, null);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800953 createAndConnectService(component, userId);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800954 sendUpdatedCaller = true;
Ruben Brunk040484c2016-10-28 20:18:57 -0700955 } else {
956 nothingChanged = true;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800957 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700958 // The service with the correct component/user is already bound, do nothing.
Ruben Brunk98576cf2016-03-07 18:54:28 -0800959 } else {
Ruben Brunk040484c2016-10-28 20:18:57 -0700960 // Nothing was previously running, bind a new service for the latest
961 // component/user selection.
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800962 createAndConnectService(component, userId);
963 sendUpdatedCaller = true;
964 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800965 }
966
Ruben Brunk666505e2017-05-04 16:54:46 -0700967 if ((calling != null || mPersistentVrModeEnabled)
Alex Sakhartchoukec4d3e42017-07-24 22:12:39 -0400968 && !Objects.equals(calling, mCurrentVrModeComponent)
969 || mRunning2dInVr != running2dInVr) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700970 sendUpdatedCaller = true;
971 }
Ruben Brunk7196a6b2017-03-22 15:43:24 -0700972 mCurrentVrModeComponent = calling;
Albert Chaulk16d23972017-07-14 12:32:57 -0400973 mRunning2dInVr = running2dInVr;
974 mVrAppProcessId = processId;
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700975
976 if (mCurrentVrModeUser != userId) {
Ruben Brunk98576cf2016-03-07 18:54:28 -0800977 mCurrentVrModeUser = userId;
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800978 sendUpdatedCaller = true;
979 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800980
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700981 String newVrServicePackage = mCurrentVrService != null
982 ? mCurrentVrService.getComponent().getPackageName() : null;
983 final int newUserId = mCurrentVrModeUser;
984
985 // Update AppOps settings that change state when entering/exiting VR mode, or changing
986 // the current VrListenerService.
987 updateDependentAppOpsLocked(newVrServicePackage, newUserId,
988 oldVrServicePackage, oldUserId);
989
Ruben Brunk98576cf2016-03-07 18:54:28 -0800990 if (mCurrentVrService != null && sendUpdatedCaller) {
Steven Thomas9aedfb12017-12-06 19:41:07 -0800991 callFocusedActivityChangedLocked();
Ruben Brunk98576cf2016-03-07 18:54:28 -0800992 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700993
994 if (!nothingChanged) {
995 logStateLocked();
996 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800997
998 return validUserComponent;
999 } finally {
1000 Binder.restoreCallingIdentity(identity);
1001 }
1002 }
1003
Steven Thomas9aedfb12017-12-06 19:41:07 -08001004 private void callFocusedActivityChangedLocked() {
1005 final ComponentName c = mCurrentVrModeComponent;
1006 final boolean b = mRunning2dInVr;
1007 final int pid = mVrAppProcessId;
1008 mCurrentVrService.sendEvent(new PendingEvent() {
1009 @Override
1010 public void runEvent(IInterface service) throws RemoteException {
1011 // Under specific (and unlikely) timing scenarios, when VrCore
1012 // crashes and is rebound, focusedActivityChanged() may be
1013 // called a 2nd time with the same arguments. IVrListeners
1014 // should make sure to handle that scenario gracefully.
1015 IVrListener l = (IVrListener) service;
1016 l.focusedActivityChanged(c, b, pid);
1017 }
1018 });
1019 }
1020
Ruben Brunk8820f942016-05-09 12:46:28 -07001021 private boolean isDefaultAllowed(String packageName) {
Craig Donner0568f282016-04-11 13:02:44 -07001022 PackageManager pm = mContext.getPackageManager();
Ruben Brunk8820f942016-05-09 12:46:28 -07001023
1024 ApplicationInfo info = null;
1025 try {
1026 info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
1027 } catch (NameNotFoundException e) {
1028 }
1029
1030 if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
1031 return false;
1032 }
1033 return true;
1034 }
1035
Ruben Brunk98576cf2016-03-07 18:54:28 -08001036 private void grantNotificationPolicyAccess(String pkg) {
1037 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk8820f942016-05-09 12:46:28 -07001038 nm.setNotificationPolicyAccessGranted(pkg, true);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001039 }
1040
1041 private void revokeNotificationPolicyAccess(String pkg) {
1042 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk8820f942016-05-09 12:46:28 -07001043 // Remove any DND zen rules possibly created by the package.
1044 nm.removeAutomaticZenRules(pkg);
1045 // Remove Notification Policy Access.
1046 nm.setNotificationPolicyAccessGranted(pkg, false);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001047 }
1048
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001049 private void grantNotificationListenerAccess(String pkg, int userId) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001050 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001051 PackageManager pm = mContext.getPackageManager();
1052 ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001053 userId, NotificationListenerService.SERVICE_INTERFACE,
Ruben Brunk98576cf2016-03-07 18:54:28 -08001054 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001055
Ruben Brunk98576cf2016-03-07 18:54:28 -08001056 for (ComponentName c : possibleServices) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001057 if (Objects.equals(c.getPackageName(), pkg)) {
1058 nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001059 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001060 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001061 }
1062
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001063 private void revokeNotificationListenerAccess(String pkg, int userId) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001064 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1065 List<ComponentName> current = nm.getEnabledNotificationListeners(userId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001066
Julia Reynoldsb852e562017-06-06 16:14:18 -04001067 for (ComponentName component : current) {
Ruben Brunk1f4f26b2016-08-02 14:21:36 -07001068 if (component != null && component.getPackageName().equals(pkg)) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001069 nm.setNotificationListenerAccessGrantedForUser(component, userId, false);
Ruben Brunk8820f942016-05-09 12:46:28 -07001070 }
1071 }
Ruben Brunk98576cf2016-03-07 18:54:28 -08001072 }
1073
Craig Donnercae8cdf2016-07-28 22:39:05 +00001074 private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1075 // Don't clobber the user if permission set in current state explicitly
1076 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
Ruben Brunk12ab5e12016-11-10 15:27:30 -08001077 try {
1078 mContext.getPackageManager().grantRuntimePermission(pkg,
1079 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1080 } catch (IllegalArgumentException e) {
1081 // Package was removed during update.
1082 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
1083 + " was removed.");
1084 }
Craig Donnercae8cdf2016-07-28 22:39:05 +00001085 }
1086 }
1087
1088 private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1089 // Don't clobber the user if permission set in current state explicitly
1090 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
Ruben Brunk12ab5e12016-11-10 15:27:30 -08001091 try {
1092 mContext.getPackageManager().revokeRuntimePermission(pkg,
1093 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1094 } catch (IllegalArgumentException e) {
1095 // Package was removed during update.
1096 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
1097 + " was removed.");
1098 }
Craig Donnercae8cdf2016-07-28 22:39:05 +00001099 }
1100 }
1101
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001102 private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
1103 final int flags = mContext.getPackageManager().getPermissionFlags(
1104 permission, pkg, new UserHandle(userId));
1105 return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
1106 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
1107 }
1108
1109 private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
1110 String flat = Settings.Secure.getStringForUser(resolver,
1111 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001112
1113 ArraySet<String> current = new ArraySet<>();
1114 if (flat != null) {
1115 String[] allowed = flat.split(":");
1116 for (String s : allowed) {
Ruben Brunk1f4f26b2016-08-02 14:21:36 -07001117 if (!TextUtils.isEmpty(s)) {
1118 current.add(s);
1119 }
Ruben Brunk98576cf2016-03-07 18:54:28 -08001120 }
1121 }
1122 return current;
1123 }
1124
1125 private static String formatSettings(Collection<String> c) {
1126 if (c == null || c.isEmpty()) {
1127 return "";
1128 }
1129
1130 StringBuilder b = new StringBuilder();
1131 boolean start = true;
1132 for (String s : c) {
1133 if ("".equals(s)) {
1134 continue;
1135 }
1136 if (!start) {
1137 b.append(':');
1138 }
1139 b.append(s);
1140 start = false;
1141 }
1142 return b.toString();
1143 }
1144
1145
1146
Ruben Brunkc7354fe2016-03-07 23:37:12 -08001147 private void createAndConnectService(@NonNull ComponentName component, int userId) {
Ruben Brunkd675f512017-10-03 15:39:41 -07001148 mCurrentVrService = createVrListenerService(component, userId);
Ruben Brunkc7354fe2016-03-07 23:37:12 -08001149 mCurrentVrService.connect();
1150 Slog.i(TAG, "Connecting " + component + " for user " + userId);
1151 }
1152
Ruben Brunke24b9a62016-02-16 21:38:24 -08001153 /**
1154 * Send VR mode change callbacks to HAL and system services if mode has actually changed.
1155 * <p/>
1156 * Note: Must be called while holding {@code mLock}.
1157 *
1158 * @param enabled new state of the VR mode.
1159 */
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001160 private void changeVrModeLocked(boolean enabled) {
Ruben Brunke24b9a62016-02-16 21:38:24 -08001161 if (mVrModeEnabled != enabled) {
1162 mVrModeEnabled = enabled;
1163
1164 // Log mode change event.
1165 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
1166 setVrModeNative(mVrModeEnabled);
1167
Ruben Brunke24b9a62016-02-16 21:38:24 -08001168 onVrModeChangedLocked();
1169 }
1170 }
1171
1172 /**
1173 * Notify system services of VR mode change.
1174 * <p/>
1175 * Note: Must be called while holding {@code mLock}.
1176 */
1177 private void onVrModeChangedLocked() {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001178 mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
1179 (mVrModeEnabled) ? 1 : 0, 0));
Ruben Brunke24b9a62016-02-16 21:38:24 -08001180 }
1181
1182 /**
Ruben Brunkd675f512017-10-03 15:39:41 -07001183 * Helper function for making ManagedApplicationService for VrListenerService instances.
Ruben Brunke24b9a62016-02-16 21:38:24 -08001184 */
Ruben Brunkd675f512017-10-03 15:39:41 -07001185 private ManagedApplicationService createVrListenerService(@NonNull ComponentName component,
1186 int userId) {
1187 int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1188 : ManagedApplicationService.RETRY_NEVER;
1189 return ManagedApplicationService.build(mContext, component, userId,
Ruben Brunke24b9a62016-02-16 21:38:24 -08001190 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
Ruben Brunkd675f512017-10-03 15:39:41 -07001191 sBinderChecker, /*isImportant*/true, retryType, mHandler, mEventCallback);
1192 }
1193
1194 /**
1195 * Helper function for making ManagedApplicationService for VR Compositor instances.
1196 */
1197 private ManagedApplicationService createVrCompositorService(@NonNull ComponentName component,
1198 int userId) {
1199 int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1200 : ManagedApplicationService.RETRY_BEST_EFFORT;
1201 return ManagedApplicationService.build(mContext, component, userId, /*clientLabel*/0,
1202 /*settingsAction*/null, /*binderChecker*/null, /*isImportant*/true, retryType,
1203 mHandler, /*disconnectCallback*/mEventCallback);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001204 }
1205
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001206 /**
1207 * Apply the pending VR state. If no state is pending, disconnect any currently bound
1208 * VR listener service.
1209 */
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001210 private void consumeAndApplyPendingStateLocked() {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001211 consumeAndApplyPendingStateLocked(true);
1212 }
1213
1214 /**
1215 * Apply the pending VR state.
1216 *
1217 * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
1218 * service will be disconnected if no state is pending. If this is {@code false} then the
1219 * nothing will be changed when there is no pending state.
1220 */
1221 private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001222 if (mPendingState != null) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001223 updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
1224 mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001225 mPendingState.callingPackage);
1226 mPendingState = null;
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001227 } else if (disconnectIfNoPendingState) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001228 updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001229 }
1230 }
1231
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001232 private void logStateLocked() {
1233 ComponentName currentBoundService = (mCurrentVrService == null) ? null :
Ruben Brunkd675f512017-10-03 15:39:41 -07001234 mCurrentVrService.getComponent();
1235 logEvent(new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
1236 mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted));
1237 }
1238
1239 private void logEvent(LogFormattable event) {
1240 synchronized (mLoggingDeque) {
1241 if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
1242 mLoggingDeque.removeFirst();
1243 mLogLimitHit = true;
1244 }
1245 mLoggingDeque.add(event);
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001246 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001247 }
1248
1249 private void dumpStateTransitions(PrintWriter pw) {
1250 SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
Ruben Brunkd675f512017-10-03 15:39:41 -07001251 synchronized (mLoggingDeque) {
1252 if (mLoggingDeque.size() == 0) {
1253 pw.print(" ");
1254 pw.println("None");
1255 }
1256
1257 if (mLogLimitHit) {
1258 pw.println("..."); // Indicates log overflow
1259 }
1260
1261 for (LogFormattable event : mLoggingDeque) {
1262 pw.println(event.toLogString(d));
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001263 }
1264 }
1265 }
1266
Ruben Brunke24b9a62016-02-16 21:38:24 -08001267 /*
1268 * Implementation of VrManagerInternal calls. These are callable from system services.
1269 */
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001270 private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
Albert Chaulk16d23972017-07-14 12:32:57 -04001271 int userId, int processId, @NonNull ComponentName callingPackage) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001272
Ruben Brunke24b9a62016-02-16 21:38:24 -08001273 synchronized (mLock) {
Zak Cohen56345f42017-01-26 13:54:28 -08001274 VrState pending;
1275 ComponentName targetListener;
Zak Cohen56345f42017-01-26 13:54:28 -08001276
1277 // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
1278 // and the system default VR listener is used.
1279 boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
Albert Chaulk16d23972017-07-14 12:32:57 -04001280 boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
1281 if (running2dInVr) {
Zak Cohen56345f42017-01-26 13:54:28 -08001282 targetListener = mDefaultVrService;
Zak Cohen56345f42017-01-26 13:54:28 -08001283 } else {
1284 targetListener = targetPackageName;
Zak Cohen56345f42017-01-26 13:54:28 -08001285 }
Albert Chaulk16d23972017-07-14 12:32:57 -04001286
1287 pending = new VrState(targetEnabledState, running2dInVr, targetListener,
1288 userId, processId, callingPackage);
Zak Cohen56345f42017-01-26 13:54:28 -08001289
Ruben Brunk040484c2016-10-28 20:18:57 -07001290 if (!mVrModeAllowed) {
1291 // We're not allowed to be in VR mode. Make this state pending. This will be
1292 // applied the next time we are allowed to enter VR mode unless it is superseded by
1293 // another call.
1294 mPendingState = pending;
1295 return;
1296 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001297
Zak Cohen56345f42017-01-26 13:54:28 -08001298 if (!targetEnabledState && mCurrentVrService != null) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001299 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
1300 // and service bind/unbind in case we are immediately switching to another VR app.
1301 if (mPendingState == null) {
1302 mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
1303 PENDING_STATE_DELAY_MS);
1304 }
1305
Ruben Brunk040484c2016-10-28 20:18:57 -07001306 mPendingState = pending;
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001307 return;
1308 } else {
1309 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
1310 mPendingState = null;
1311 }
1312
Albert Chaulk16d23972017-07-14 12:32:57 -04001313 updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
1314 userId, processId, callingPackage);
Zak Cohen56345f42017-01-26 13:54:28 -08001315 }
1316 }
1317
1318 private void setPersistentVrModeEnabled(boolean enabled) {
Zak Cohen732aeb02017-01-29 14:19:52 -08001319 synchronized(mLock) {
1320 setPersistentModeAndNotifyListenersLocked(enabled);
Alex Sakhartchouka26b4352017-07-25 17:08:43 -04001321 // Disabling persistent mode should disable the overall vr mode.
1322 if (!enabled) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001323 setVrMode(false, null, 0, -1, null);
Zak Cohen56345f42017-01-26 13:54:28 -08001324 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001325 }
1326 }
1327
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001328 public void setVr2dDisplayProperties(
1329 Vr2dDisplayProperties compatDisplayProp) {
1330 if (mVr2dDisplay != null) {
1331 mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -07001332 return;
1333 }
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001334 Slog.w(TAG, "Vr2dDisplay is null!");
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -07001335 }
1336
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001337 private int getVr2dDisplayId() {
1338 if (mVr2dDisplay != null) {
1339 return mVr2dDisplay.getVirtualDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -08001340 }
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001341 Slog.w(TAG, "Vr2dDisplay is null!");
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -08001342 return INVALID_DISPLAY;
1343 }
1344
Ruben Brunk52ea6622017-10-02 23:51:25 -07001345 private void setAndBindCompositor(ComponentName componentName) {
1346 final int userId = UserHandle.getCallingUserId();
1347 final long token = Binder.clearCallingIdentity();
1348 synchronized (mLock) {
1349 updateCompositorServiceLocked(userId, componentName);
1350 }
1351 Binder.restoreCallingIdentity(token);
1352 }
1353
1354 private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
1355 if (mCurrentVrCompositorService != null
1356 && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
Ruben Brunkd675f512017-10-03 15:39:41 -07001357 Slog.i(TAG, "Disconnecting compositor service: "
1358 + mCurrentVrCompositorService.getComponent());
Ruben Brunk52ea6622017-10-02 23:51:25 -07001359 // Check if existing service matches the requested one, if not (or if the requested
1360 // component is null) disconnect it.
1361 mCurrentVrCompositorService = null;
1362 }
1363
1364 if (componentName != null && mCurrentVrCompositorService == null) {
1365 // We don't have an existing service matching the requested component, so attempt to
1366 // connect one.
Ruben Brunkd675f512017-10-03 15:39:41 -07001367 Slog.i(TAG, "Connecting compositor service: " + componentName);
1368 mCurrentVrCompositorService = createVrCompositorService(componentName, userId);
Ruben Brunk52ea6622017-10-02 23:51:25 -07001369 mCurrentVrCompositorService.connect();
1370 }
1371 }
1372
Zak Cohen732aeb02017-01-29 14:19:52 -08001373 private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
1374 if (mPersistentVrModeEnabled == enabled) {
1375 return;
1376 }
Ruben Brunkd675f512017-10-03 15:39:41 -07001377 String eventName = "Persistent VR mode " + ((enabled) ? "enabled" : "disabled");
1378 Slog.i(TAG, eventName);
1379 logEvent(new SettingEvent(eventName));
Zak Cohen732aeb02017-01-29 14:19:52 -08001380 mPersistentVrModeEnabled = enabled;
1381
1382 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
1383 (mPersistentVrModeEnabled) ? 1 : 0, 0));
1384 }
1385
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001386 private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001387 synchronized (mLock) {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001388 return mComponentObserver.isValid(targetPackageName, userId);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001389 }
1390 }
1391
Ruben Brunk8f1d5cb2016-03-22 18:08:41 -07001392 private boolean isCurrentVrListener(String packageName, int userId) {
1393 synchronized (mLock) {
1394 if (mCurrentVrService == null) {
1395 return false;
1396 }
1397 return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1398 userId == mCurrentVrService.getUserId();
1399 }
1400 }
1401
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001402 /*
1403 * Implementation of IVrManager calls.
1404 */
1405
1406 private void addStateCallback(IVrStateCallbacks cb) {
Steven Thomasb70845c2017-03-16 14:32:37 -07001407 mVrStateRemoteCallbacks.register(cb);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001408 }
1409
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001410 private void removeStateCallback(IVrStateCallbacks cb) {
Steven Thomasb70845c2017-03-16 14:32:37 -07001411 mVrStateRemoteCallbacks.unregister(cb);
1412 }
1413
1414 private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
1415 mPersistentVrStateRemoteCallbacks.register(cb);
1416 }
1417
1418 private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
1419 mPersistentVrStateRemoteCallbacks.unregister(cb);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001420 }
1421
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001422 private boolean getVrMode() {
Ruben Brunke24b9a62016-02-16 21:38:24 -08001423 synchronized (mLock) {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001424 return mVrModeEnabled;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001425 }
1426 }
Santos Cordone6d77232017-08-08 17:11:41 -07001427
1428 private boolean getPersistentVrMode() {
1429 synchronized (mLock) {
1430 return mPersistentVrModeEnabled;
1431 }
1432 }
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001433}