blob: e8ebbe4dd8051a7d4f3d0361fc3b5e66ca3bebbf [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;
Ruben Brunk8820f942016-05-09 12:46:28 -070022import android.app.ActivityManager;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080023import android.app.AppOpsManager;
Julia Reynoldsb852e562017-06-06 16:14:18 -040024import android.app.INotificationManager;
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -070025import android.app.Vr2dDisplayProperties;
Ruben Brunk98576cf2016-03-07 18:54:28 -080026import android.app.NotificationManager;
Ruben Brunke24b9a62016-02-16 21:38:24 -080027import android.annotation.NonNull;
Steven Thomas68cc84f2017-06-08 16:55:04 -070028import android.content.BroadcastReceiver;
Ruben Brunke24b9a62016-02-16 21:38:24 -080029import android.content.ComponentName;
Ruben Brunk98576cf2016-03-07 18:54:28 -080030import android.content.ContentResolver;
31import android.content.Context;
Steven Thomas68cc84f2017-06-08 16:55:04 -070032import android.content.Intent;
33import android.content.IntentFilter;
Ruben Brunk98576cf2016-03-07 18:54:28 -080034import android.content.pm.ApplicationInfo;
35import android.content.pm.PackageManager;
36import android.content.pm.PackageManager.NameNotFoundException;
Santos Cordon2f22da72017-02-27 17:24:44 -080037import android.hardware.display.DisplayManager;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080038import android.os.Binder;
Ruben Brunke24b9a62016-02-16 21:38:24 -080039import android.os.Handler;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080040import android.os.IBinder;
Ruben Brunke24b9a62016-02-16 21:38:24 -080041import android.os.IInterface;
42import android.os.Looper;
Ruben Brunkc7be3be2016-04-01 17:07:51 -070043import android.os.Message;
44import android.os.RemoteCallbackList;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080045import android.os.RemoteException;
Julia Reynoldsb852e562017-06-06 16:14:18 -040046import android.os.ServiceManager;
Steven Thomas68cc84f2017-06-08 16:55:04 -070047import android.os.SystemProperties;
Ruben Brunk98576cf2016-03-07 18:54:28 -080048import android.os.UserHandle;
Ruben Brunke24b9a62016-02-16 21:38:24 -080049import android.provider.Settings;
Ruben Brunk98576cf2016-03-07 18:54:28 -080050import android.service.notification.NotificationListenerService;
Steven Thomasb70845c2017-03-16 14:32:37 -070051import android.service.vr.IPersistentVrStateCallbacks;
Ruben Brunke24b9a62016-02-16 21:38:24 -080052import android.service.vr.IVrListener;
Ruben Brunkc7be3be2016-04-01 17:07:51 -070053import android.service.vr.IVrManager;
54import android.service.vr.IVrStateCallbacks;
Ruben Brunke24b9a62016-02-16 21:38:24 -080055import android.service.vr.VrListenerService;
Ruben Brunk1f4f26b2016-08-02 14:21:36 -070056import android.text.TextUtils;
Svetoslav Ganove33f6132016-06-01 16:25:31 -070057import android.util.ArrayMap;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080058import android.util.ArraySet;
59import android.util.Slog;
Ruben Brunk8820f942016-05-09 12:46:28 -070060import android.util.SparseArray;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -070061import android.view.WindowManagerInternal;
Santos Cordonc14513d2016-12-14 14:52:59 -080062
Ruben Brunke24b9a62016-02-16 21:38:24 -080063import com.android.internal.R;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060064import com.android.internal.util.DumpUtils;
Karthik Ravi Shankar99493db2017-03-08 18:30:19 -080065import com.android.server.LocalServices;
Craig Donner99062592016-04-14 21:45:19 -070066import com.android.server.SystemConfig;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080067import com.android.server.SystemService;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080068import com.android.server.utils.ManagedApplicationService.PendingEvent;
Ruben Brunkd675f512017-10-03 15:39:41 -070069import com.android.server.utils.ManagedApplicationService.LogEvent;
70import com.android.server.utils.ManagedApplicationService.LogFormattable;
Ruben Brunke24b9a62016-02-16 21:38:24 -080071import com.android.server.vr.EnabledComponentsObserver.EnabledComponentChangeListener;
72import com.android.server.utils.ManagedApplicationService;
73import com.android.server.utils.ManagedApplicationService.BinderChecker;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080074
Dan Sandlerdc34df52016-04-07 21:04:46 -040075import java.io.FileDescriptor;
76import java.io.PrintWriter;
Ruben Brunk98576cf2016-03-07 18:54:28 -080077import java.lang.StringBuilder;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070078import java.text.SimpleDateFormat;
Santos Cordone6d77232017-08-08 17:11:41 -070079import java.util.Arrays;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070080import java.util.ArrayDeque;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080081import java.util.ArrayList;
Ruben Brunk98576cf2016-03-07 18:54:28 -080082import java.util.Collection;
Ruben Brunk2ff9c012016-04-28 10:58:29 -070083import java.util.Date;
Julia Reynoldsb852e562017-06-06 16:14:18 -040084import java.util.List;
Ruben Brunkc7354fe2016-03-07 23:37:12 -080085import java.util.Objects;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080086
87/**
Ruben Brunke24b9a62016-02-16 21:38:24 -080088 * Service tracking whether VR mode is active, and notifying listening services of state changes.
89 * <p/>
90 * Services running in system server may modify the state of VrManagerService via the interface in
91 * VrManagerInternal, and may register to receive callbacks when the system VR mode changes via the
92 * interface given in VrStateListener.
93 * <p/>
94 * Device vendors may choose to receive VR state changes by implementing the VR mode HAL, e.g.:
95 * hardware/libhardware/modules/vr
96 * <p/>
97 * In general applications may enable or disable VR mode by calling
Ruben Brunk98576cf2016-03-07 18:54:28 -080098 * {@link android.app.Activity#setVrModeEnabled)}. An application may also implement a service to
99 * be run while in VR mode by implementing {@link android.service.vr.VrListenerService}.
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800100 *
Elliot Waite54de7742017-01-11 15:30:35 -0800101 * @see android.service.vr.VrListenerService
102 * @see com.android.server.vr.VrManagerInternal
103 * @see com.android.server.vr.VrStateListener
Ruben Brunke24b9a62016-02-16 21:38:24 -0800104 *
105 * @hide
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800106 */
Ruben Brunke24b9a62016-02-16 21:38:24 -0800107public class VrManagerService extends SystemService implements EnabledComponentChangeListener{
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800108
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800109 public static final String TAG = "VrManagerService";
Joe Onorato82ba91d2017-04-27 16:18:05 -0700110 static final boolean DBG = false;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800111
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700112 private static final int PENDING_STATE_DELAY_MS = 300;
Ruben Brunkd675f512017-10-03 15:39:41 -0700113 private static final int EVENT_LOG_SIZE = 64;
Ruben Brunk8820f942016-05-09 12:46:28 -0700114 private static final int INVALID_APPOPS_MODE = -1;
Ruben Brunk040484c2016-10-28 20:18:57 -0700115 /** Null set of sleep sleep flags. */
116 private static final int FLAG_NONE = 0;
117 /** Flag set when the device is not sleeping. */
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700118 private static final int FLAG_AWAKE = 1 << 0;
Ruben Brunk040484c2016-10-28 20:18:57 -0700119 /** Flag set when the screen has been turned on. */
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700120 private static final int FLAG_SCREEN_ON = 1 << 1;
121 /** Flag set when the keyguard is not active. */
122 private static final int FLAG_KEYGUARD_UNLOCKED = 1 << 2;
Ruben Brunk040484c2016-10-28 20:18:57 -0700123 /** Flag indicating that all system sleep flags have been set.*/
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700124 private static final int FLAG_ALL = FLAG_AWAKE | FLAG_SCREEN_ON | FLAG_KEYGUARD_UNLOCKED;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700125
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800126 private static native void initializeNative();
127 private static native void setVrModeNative(boolean enabled);
128
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800129 private final Object mLock = new Object();
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800130
131 private final IBinder mOverlayToken = new Binder();
132
Ruben Brunke24b9a62016-02-16 21:38:24 -0800133 // State protected by mLock
Ruben Brunk040484c2016-10-28 20:18:57 -0700134 private boolean mVrModeAllowed;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800135 private boolean mVrModeEnabled;
Zak Cohen56345f42017-01-26 13:54:28 -0800136 private boolean mPersistentVrModeEnabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400137 private boolean mRunning2dInVr;
138 private int mVrAppProcessId;
Ruben Brunke24b9a62016-02-16 21:38:24 -0800139 private EnabledComponentsObserver mComponentObserver;
140 private ManagedApplicationService mCurrentVrService;
Ruben Brunk52ea6622017-10-02 23:51:25 -0700141 private ManagedApplicationService mCurrentVrCompositorService;
Zak Cohen56345f42017-01-26 13:54:28 -0800142 private ComponentName mDefaultVrService;
Ruben Brunke24b9a62016-02-16 21:38:24 -0800143 private Context mContext;
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800144 private ComponentName mCurrentVrModeComponent;
145 private int mCurrentVrModeUser;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800146 private boolean mWasDefaultGranted;
147 private boolean mGuard;
Steven Thomasb70845c2017-03-16 14:32:37 -0700148 private final RemoteCallbackList<IVrStateCallbacks> mVrStateRemoteCallbacks =
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700149 new RemoteCallbackList<>();
Steven Thomasb70845c2017-03-16 14:32:37 -0700150 private final RemoteCallbackList<IPersistentVrStateCallbacks>
151 mPersistentVrStateRemoteCallbacks = new RemoteCallbackList<>();
Ruben Brunk8820f942016-05-09 12:46:28 -0700152 private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
153 private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700154 private VrState mPendingState;
Ruben Brunkd675f512017-10-03 15:39:41 -0700155 private boolean mLogLimitHit;
156 private final ArrayDeque<LogFormattable> mLoggingDeque = new ArrayDeque<>(EVENT_LOG_SIZE);
Ruben Brunk8820f942016-05-09 12:46:28 -0700157 private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
Julia Reynoldsb852e562017-06-06 16:14:18 -0400158 private INotificationManager mNotificationManager;
Ruben Brunk040484c2016-10-28 20:18:57 -0700159 /** Tracks the state of the screen and keyguard UI.*/
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700160 private int mSystemSleepFlags = FLAG_AWAKE | FLAG_KEYGUARD_UNLOCKED;
Steven Thomas68cc84f2017-06-08 16:55:04 -0700161 /**
162 * Set when ACTION_USER_UNLOCKED is fired. We shouldn't try to bind to the
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700163 * vr service before then. This gets set only once the first time the user unlocks the device
164 * and stays true thereafter.
Steven Thomas68cc84f2017-06-08 16:55:04 -0700165 */
166 private boolean mUserUnlocked;
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700167 private Vr2dDisplay mVr2dDisplay;
Steven Thomas68cc84f2017-06-08 16:55:04 -0700168 private boolean mBootsToVr;
Steven Thomas1356ec92017-09-07 11:26:38 -0700169 private boolean mStandby;
170 private boolean mUseStandbyToExitVrMode;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800171
Ruben Brunkd675f512017-10-03 15:39:41 -0700172 // Handles events from the managed services (e.g. VrListenerService and any bound VR compositor
173 // service).
174 private final ManagedApplicationService.EventCallback mEventCallback
175 = new ManagedApplicationService.EventCallback() {
176 @Override
177 public void onServiceEvent(LogEvent event) {
178 logEvent(event);
179
180 ComponentName component = null;
181 synchronized (mLock) {
182 component = ((mCurrentVrService == null) ? null : mCurrentVrService.getComponent());
183 }
184
185 // If not on an AIO device and we permanently stopped trying to connect to the
186 // VrListenerService (or don't have one bound), leave persistent VR mode and VR mode.
187 if (!mBootsToVr && event.event == LogEvent.EVENT_STOPPED_PERMANENTLY &&
188 (component == null || component.equals(event.component))) {
189 Slog.e(TAG, "VrListenerSevice has died permanently, leaving system VR mode.");
190 // We're not a native VR device. Leave VR + persistent mode.
191 setPersistentVrModeEnabled(false);
192 }
193 }
194 };
195
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700196 private static final int MSG_VR_STATE_CHANGE = 0;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700197 private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
Zak Cohen732aeb02017-01-29 14:19:52 -0800198 private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2;
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700199
Ruben Brunk040484c2016-10-28 20:18:57 -0700200 /**
201 * Set whether VR mode may be enabled.
202 * <p/>
203 * If VR mode is not allowed to be enabled, calls to set VR mode will be cached. When VR mode
204 * is again allowed to be enabled, the most recent cached state will be applied.
205 *
Ruben Brunk040484c2016-10-28 20:18:57 -0700206 */
Steven Thomas68cc84f2017-06-08 16:55:04 -0700207 private void updateVrModeAllowedLocked() {
Steven Thomas1356ec92017-09-07 11:26:38 -0700208 boolean ignoreSleepFlags = mBootsToVr && mUseStandbyToExitVrMode;
209 boolean disallowedByStandby = mStandby && mUseStandbyToExitVrMode;
210 boolean allowed = (mSystemSleepFlags == FLAG_ALL || ignoreSleepFlags) && mUserUnlocked
211 && !disallowedByStandby;
Ruben Brunk040484c2016-10-28 20:18:57 -0700212 if (mVrModeAllowed != allowed) {
213 mVrModeAllowed = allowed;
Joe Onorato82ba91d2017-04-27 16:18:05 -0700214 if (DBG) Slog.d(TAG, "VR mode is " + ((allowed) ? "allowed" : "disallowed"));
Ruben Brunk040484c2016-10-28 20:18:57 -0700215 if (mVrModeAllowed) {
Steven Thomas68cc84f2017-06-08 16:55:04 -0700216 if (mBootsToVr) {
217 setPersistentVrModeEnabled(true);
218 }
Steven Thomas68cc84f2017-06-08 16:55:04 -0700219 if (mBootsToVr && !mVrModeEnabled) {
Albert Chaulk16d23972017-07-14 12:32:57 -0400220 setVrMode(true, mDefaultVrService, 0, -1, null);
Steven Thomas68cc84f2017-06-08 16:55:04 -0700221 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700222 } else {
Zak Cohen56345f42017-01-26 13:54:28 -0800223 // Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
224 // exit persistent VR mode when screen is turned off.
Zak Cohen732aeb02017-01-29 14:19:52 -0800225 setPersistentModeAndNotifyListenersLocked(false);
Zak Cohen56345f42017-01-26 13:54:28 -0800226
Ruben Brunk040484c2016-10-28 20:18:57 -0700227 // Set pending state to current state.
228 mPendingState = (mVrModeEnabled && mCurrentVrService != null)
Albert Chaulk16d23972017-07-14 12:32:57 -0400229 ? new VrState(mVrModeEnabled, mRunning2dInVr, mCurrentVrService.getComponent(),
230 mCurrentVrService.getUserId(), mVrAppProcessId, mCurrentVrModeComponent)
Ruben Brunk040484c2016-10-28 20:18:57 -0700231 : null;
232
233 // Unbind current VR service and do necessary callbacks.
Albert Chaulk16d23972017-07-14 12:32:57 -0400234 updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
Ruben Brunk040484c2016-10-28 20:18:57 -0700235 }
236 }
237 }
238
239 private void setSleepState(boolean isAsleep) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700240 setSystemState(FLAG_AWAKE, !isAsleep);
Ruben Brunk040484c2016-10-28 20:18:57 -0700241 }
242
243 private void setScreenOn(boolean isScreenOn) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700244 setSystemState(FLAG_SCREEN_ON, isScreenOn);
245 }
246
247 private void setKeyguardShowing(boolean isShowing) {
248 setSystemState(FLAG_KEYGUARD_UNLOCKED, !isShowing);
249 }
250
251 private void setSystemState(int flags, boolean isOn) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700252 synchronized(mLock) {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700253 int oldState = mSystemSleepFlags;
254 if (isOn) {
255 mSystemSleepFlags |= flags;
Ruben Brunk040484c2016-10-28 20:18:57 -0700256 } else {
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700257 mSystemSleepFlags &= ~flags;
Ruben Brunk040484c2016-10-28 20:18:57 -0700258 }
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700259 if (oldState != mSystemSleepFlags) {
260 if (DBG) Slog.d(TAG, "System state: " + getStateAsString());
261 updateVrModeAllowedLocked();
262 }
Steven Thomas68cc84f2017-06-08 16:55:04 -0700263 }
264 }
265
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700266 private String getStateAsString() {
267 return new StringBuilder()
268 .append((mSystemSleepFlags & FLAG_AWAKE) != 0 ? "awake, " : "")
269 .append((mSystemSleepFlags & FLAG_SCREEN_ON) != 0 ? "screen_on, " : "")
270 .append((mSystemSleepFlags & FLAG_KEYGUARD_UNLOCKED) != 0 ? "keyguard_off" : "")
271 .toString();
272 }
273
Steven Thomas68cc84f2017-06-08 16:55:04 -0700274 private void setUserUnlocked() {
275 synchronized(mLock) {
276 mUserUnlocked = true;
277 updateVrModeAllowedLocked();
Ruben Brunk040484c2016-10-28 20:18:57 -0700278 }
279 }
280
Steven Thomas1356ec92017-09-07 11:26:38 -0700281 private void setStandbyEnabled(boolean standby) {
282 synchronized(mLock) {
283 if (!mBootsToVr) {
284 Slog.e(TAG, "Attempting to set standby mode on a non-standalone device");
285 return;
286 }
287 mStandby = standby;
288 updateVrModeAllowedLocked();
289 }
290 }
291
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700292 private final Handler mHandler = new Handler() {
293 @Override
294 public void handleMessage(Message msg) {
295 switch(msg.what) {
296 case MSG_VR_STATE_CHANGE : {
297 boolean state = (msg.arg1 == 1);
Steven Thomasb70845c2017-03-16 14:32:37 -0700298 int i = mVrStateRemoteCallbacks.beginBroadcast();
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700299 while (i > 0) {
300 i--;
301 try {
Steven Thomasb70845c2017-03-16 14:32:37 -0700302 mVrStateRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700303 } catch (RemoteException e) {
304 // Noop
305 }
306 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700307 mVrStateRemoteCallbacks.finishBroadcast();
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700308 } break;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700309 case MSG_PENDING_VR_STATE_CHANGE : {
310 synchronized(mLock) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700311 if (mVrModeAllowed) {
312 VrManagerService.this.consumeAndApplyPendingStateLocked();
313 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700314 }
315 } break;
Zak Cohen732aeb02017-01-29 14:19:52 -0800316 case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : {
317 boolean state = (msg.arg1 == 1);
Steven Thomasb70845c2017-03-16 14:32:37 -0700318 int i = mPersistentVrStateRemoteCallbacks.beginBroadcast();
319 while (i > 0) {
320 i--;
321 try {
322 mPersistentVrStateRemoteCallbacks.getBroadcastItem(i)
323 .onPersistentVrStateChanged(state);
324 } catch (RemoteException e) {
325 // Noop
326 }
Zak Cohen732aeb02017-01-29 14:19:52 -0800327 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700328 mPersistentVrStateRemoteCallbacks.finishBroadcast();
Zak Cohen732aeb02017-01-29 14:19:52 -0800329 } break;
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700330 default :
331 throw new IllegalStateException("Unknown message type: " + msg.what);
332 }
333 }
334 };
335
Ruben Brunkd675f512017-10-03 15:39:41 -0700336 // Event used to log when settings are changed for dumpsys logs.
337 private static class SettingEvent implements LogFormattable {
338 public final long timestamp;
339 public final String what;
340
341 SettingEvent(String what) {
342 this.timestamp = System.currentTimeMillis();
343 this.what = what;
344 }
345
346 @Override
347 public String toLogString(SimpleDateFormat dateFormat) {
348 return dateFormat.format(new Date(timestamp)) + " " + what;
349 }
350 }
351
352 // Event used to track changes of the primary on-screen VR activity.
353 private static class VrState implements LogFormattable {
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700354 final boolean enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400355 final boolean running2dInVr;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700356 final int userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400357 final int processId;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700358 final ComponentName targetPackageName;
359 final ComponentName callingPackage;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700360 final long timestamp;
361 final boolean defaultPermissionsGranted;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700362
Albert Chaulk16d23972017-07-14 12:32:57 -0400363 VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
364 int processId, ComponentName callingPackage) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700365 this.enabled = enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400366 this.running2dInVr = running2dInVr;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700367 this.userId = userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400368 this.processId = processId;
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700369 this.targetPackageName = targetPackageName;
370 this.callingPackage = callingPackage;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700371 this.defaultPermissionsGranted = false;
372 this.timestamp = System.currentTimeMillis();
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700373 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700374
Albert Chaulk16d23972017-07-14 12:32:57 -0400375 VrState(boolean enabled, boolean running2dInVr, ComponentName targetPackageName, int userId,
376 int processId, ComponentName callingPackage, boolean defaultPermissionsGranted) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700377 this.enabled = enabled;
Albert Chaulk16d23972017-07-14 12:32:57 -0400378 this.running2dInVr = running2dInVr;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700379 this.userId = userId;
Albert Chaulk16d23972017-07-14 12:32:57 -0400380 this.processId = processId;
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700381 this.targetPackageName = targetPackageName;
382 this.callingPackage = callingPackage;
383 this.defaultPermissionsGranted = defaultPermissionsGranted;
384 this.timestamp = System.currentTimeMillis();
385 }
Ruben Brunkd675f512017-10-03 15:39:41 -0700386
387 @Override
388 public String toLogString(SimpleDateFormat dateFormat) {
389 String tab = " ";
390 String newLine = "\n";
391 StringBuilder sb = new StringBuilder(dateFormat.format(new Date(timestamp)));
392 sb.append(tab);
393 sb.append("State changed to:");
394 sb.append(tab);
395 sb.append((enabled) ? "ENABLED" : "DISABLED");
396 sb.append(newLine);
397 if (enabled) {
398 sb.append(tab);
399 sb.append("User=");
400 sb.append(userId);
401 sb.append(newLine);
402 sb.append(tab);
403 sb.append("Current VR Activity=");
404 sb.append((callingPackage == null) ? "None" : callingPackage.flattenToString());
405 sb.append(newLine);
406 sb.append(tab);
407 sb.append("Bound VrListenerService=");
408 sb.append((targetPackageName == null) ? "None"
409 : targetPackageName.flattenToString());
410 sb.append(newLine);
411 if (defaultPermissionsGranted) {
412 sb.append(tab);
413 sb.append("Default permissions granted to the bound VrListenerService.");
414 sb.append(newLine);
415 }
416 }
417 return sb.toString();
418 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700419 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700420
Ruben Brunke24b9a62016-02-16 21:38:24 -0800421 private static final BinderChecker sBinderChecker = new BinderChecker() {
422 @Override
423 public IInterface asInterface(IBinder binder) {
424 return IVrListener.Stub.asInterface(binder);
425 }
426
427 @Override
428 public boolean checkType(IInterface service) {
429 return service instanceof IVrListener;
430 }
431 };
432
Ruben Brunk8820f942016-05-09 12:46:28 -0700433 private final class NotificationAccessManager {
434 private final SparseArray<ArraySet<String>> mAllowedPackages = new SparseArray<>();
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700435 private final ArrayMap<String, Integer> mNotificationAccessPackageToUserId =
436 new ArrayMap<>();
Ruben Brunk8820f942016-05-09 12:46:28 -0700437
438 public void update(Collection<String> packageNames) {
439 int currentUserId = ActivityManager.getCurrentUser();
440
Ruben Brunk8820f942016-05-09 12:46:28 -0700441 ArraySet<String> allowed = mAllowedPackages.get(currentUserId);
442 if (allowed == null) {
443 allowed = new ArraySet<>();
444 }
445
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700446 // Make sure we revoke notification access for listeners in other users
447 final int listenerCount = mNotificationAccessPackageToUserId.size();
448 for (int i = listenerCount - 1; i >= 0; i--) {
449 final int grantUserId = mNotificationAccessPackageToUserId.valueAt(i);
450 if (grantUserId != currentUserId) {
451 String packageName = mNotificationAccessPackageToUserId.keyAt(i);
452 revokeNotificationListenerAccess(packageName, grantUserId);
453 revokeNotificationPolicyAccess(packageName);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000454 revokeCoarseLocationPermissionIfNeeded(packageName, grantUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700455 mNotificationAccessPackageToUserId.removeAt(i);
456 }
457 }
458
Ruben Brunk8820f942016-05-09 12:46:28 -0700459 for (String pkg : allowed) {
460 if (!packageNames.contains(pkg)) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700461 revokeNotificationListenerAccess(pkg, currentUserId);
Ruben Brunk8820f942016-05-09 12:46:28 -0700462 revokeNotificationPolicyAccess(pkg);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000463 revokeCoarseLocationPermissionIfNeeded(pkg, currentUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700464 mNotificationAccessPackageToUserId.remove(pkg);
Ruben Brunk8820f942016-05-09 12:46:28 -0700465 }
466 }
467 for (String pkg : packageNames) {
468 if (!allowed.contains(pkg)) {
469 grantNotificationPolicyAccess(pkg);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700470 grantNotificationListenerAccess(pkg, currentUserId);
Craig Donnercae8cdf2016-07-28 22:39:05 +0000471 grantCoarseLocationPermissionIfNeeded(pkg, currentUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700472 mNotificationAccessPackageToUserId.put(pkg, currentUserId);
Ruben Brunk8820f942016-05-09 12:46:28 -0700473 }
474 }
475
476 allowed.clear();
477 allowed.addAll(packageNames);
478 mAllowedPackages.put(currentUserId, allowed);
479 }
480 }
481
Ruben Brunke24b9a62016-02-16 21:38:24 -0800482 /**
483 * Called when a user, package, or setting changes that could affect whether or not the
484 * currently bound VrListenerService is changed.
485 */
486 @Override
487 public void onEnabledComponentChanged() {
488 synchronized (mLock) {
Ruben Brunk8820f942016-05-09 12:46:28 -0700489 int currentUser = ActivityManager.getCurrentUser();
Ruben Brunk8820f942016-05-09 12:46:28 -0700490 // Update listeners
491 ArraySet<ComponentName> enabledListeners = mComponentObserver.getEnabled(currentUser);
492
493 ArraySet<String> enabledPackages = new ArraySet<>();
494 for (ComponentName n : enabledListeners) {
495 String pkg = n.getPackageName();
496 if (isDefaultAllowed(pkg)) {
497 enabledPackages.add(n.getPackageName());
498 }
499 }
500 mNotifAccessManager.update(enabledPackages);
501
Ruben Brunk040484c2016-10-28 20:18:57 -0700502 if (!mVrModeAllowed) {
503 return; // Don't do anything, we shouldn't be in VR mode.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800504 }
505
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700506 // If there is a pending state change, we'd better deal with that first
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800507 consumeAndApplyPendingStateLocked(false);
Ruben Brunkb56b72a2016-04-15 11:53:09 -0700508
509 if (mCurrentVrService == null) {
510 return; // No active services
511 }
512
Ruben Brunke24b9a62016-02-16 21:38:24 -0800513 // There is an active service, update it if needed
Albert Chaulk16d23972017-07-14 12:32:57 -0400514 updateCurrentVrServiceLocked(mVrModeEnabled, mRunning2dInVr,
515 mCurrentVrService.getComponent(), mCurrentVrService.getUserId(),
516 mVrAppProcessId, mCurrentVrModeComponent);
Ruben Brunke24b9a62016-02-16 21:38:24 -0800517 }
518 }
519
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700520 private final IVrManager mVrManager = new IVrManager.Stub() {
521
522 @Override
523 public void registerListener(IVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700524 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
525 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700526 if (cb == null) {
527 throw new IllegalArgumentException("Callback binder object is null.");
528 }
529
530 VrManagerService.this.addStateCallback(cb);
531 }
532
533 @Override
534 public void unregisterListener(IVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700535 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
536 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700537 if (cb == null) {
538 throw new IllegalArgumentException("Callback binder object is null.");
539 }
540
541 VrManagerService.this.removeStateCallback(cb);
542 }
543
544 @Override
Steven Thomasb70845c2017-03-16 14:32:37 -0700545 public void registerPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700546 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
547 Manifest.permission.ACCESS_VR_STATE);
Steven Thomasb70845c2017-03-16 14:32:37 -0700548 if (cb == null) {
549 throw new IllegalArgumentException("Callback binder object is null.");
550 }
551
552 VrManagerService.this.addPersistentStateCallback(cb);
553 }
554
555 @Override
556 public void unregisterPersistentVrStateListener(IPersistentVrStateCallbacks cb) {
Santos Cordone6d77232017-08-08 17:11:41 -0700557 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
558 Manifest.permission.ACCESS_VR_STATE);
Steven Thomasb70845c2017-03-16 14:32:37 -0700559 if (cb == null) {
560 throw new IllegalArgumentException("Callback binder object is null.");
561 }
562
563 VrManagerService.this.removePersistentStateCallback(cb);
564 }
565
566 @Override
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700567 public boolean getVrModeState() {
Santos Cordone6d77232017-08-08 17:11:41 -0700568 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
569 Manifest.permission.ACCESS_VR_STATE);
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700570 return VrManagerService.this.getVrMode();
571 }
572
Dan Sandlerdc34df52016-04-07 21:04:46 -0400573 @Override
Santos Cordone6d77232017-08-08 17:11:41 -0700574 public boolean getPersistentVrModeEnabled() {
575 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER,
576 Manifest.permission.ACCESS_VR_STATE);
577 return VrManagerService.this.getPersistentVrMode();
578 }
579
580 @Override
Zak Cohen56345f42017-01-26 13:54:28 -0800581 public void setPersistentVrModeEnabled(boolean enabled) {
Santos Cordone6d77232017-08-08 17:11:41 -0700582 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
Zak Cohen56345f42017-01-26 13:54:28 -0800583 VrManagerService.this.setPersistentVrModeEnabled(enabled);
584 }
585
586 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700587 public void setVr2dDisplayProperties(
588 Vr2dDisplayProperties vr2dDisplayProp) {
Santos Cordone6d77232017-08-08 17:11:41 -0700589 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700590 VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -0700591 }
592
593 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700594 public int getVr2dDisplayId() {
595 return VrManagerService.this.getVr2dDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -0800596 }
597
598 @Override
Ruben Brunk52ea6622017-10-02 23:51:25 -0700599 public void setAndBindCompositor(String componentName) {
600 enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
601 VrManagerService.this.setAndBindCompositor(
602 (componentName == null) ? null : ComponentName.unflattenFromString(componentName));
603 }
604
605 @Override
Steven Thomas1356ec92017-09-07 11:26:38 -0700606 public void setStandbyEnabled(boolean standby) {
607 enforceCallerPermissionAnyOf(Manifest.permission.ACCESS_VR_MANAGER);
608 VrManagerService.this.setStandbyEnabled(standby);
609 }
610
611 @Override
Dan Sandlerdc34df52016-04-07 21:04:46 -0400612 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -0600613 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
614
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700615 pw.println("********* Dump of VrManagerService *********");
Ruben Brunk040484c2016-10-28 20:18:57 -0700616 pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
Zak Cohen56345f42017-01-26 13:54:28 -0800617 pw.println("Persistent VR mode is currently: " +
618 ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
Ruben Brunkd675f512017-10-03 15:39:41 -0700619 pw.println("Currently bound VR listener service: "
Ruben Brunka25b93c2017-10-05 19:41:42 -0700620 + ((mCurrentVrService == null)
621 ? "None" : mCurrentVrService.getComponent().flattenToString()));
Ruben Brunk52ea6622017-10-02 23:51:25 -0700622 pw.println("Currently bound VR compositor service: "
623 + ((mCurrentVrCompositorService == null)
Ruben Brunkd675f512017-10-03 15:39:41 -0700624 ? "None" : mCurrentVrCompositorService.getComponent().flattenToString()));
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700625 pw.println("Previous state transitions:\n");
626 String tab = " ";
627 dumpStateTransitions(pw);
628 pw.println("\n\nRemote Callbacks:");
Steven Thomasb70845c2017-03-16 14:32:37 -0700629 int i=mVrStateRemoteCallbacks.beginBroadcast(); // create the broadcast item array
Dan Sandlerdc34df52016-04-07 21:04:46 -0400630 while(i-->0) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700631 pw.print(tab);
Steven Thomasb70845c2017-03-16 14:32:37 -0700632 pw.print(mVrStateRemoteCallbacks.getBroadcastItem(i));
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700633 if (i>0) pw.println(",");
Dan Sandlerdc34df52016-04-07 21:04:46 -0400634 }
Steven Thomasb70845c2017-03-16 14:32:37 -0700635 mVrStateRemoteCallbacks.finishBroadcast();
636 pw.println("\n\nPersistent Vr State Remote Callbacks:");
637 i=mPersistentVrStateRemoteCallbacks.beginBroadcast();
638 while(i-->0) {
639 pw.print(tab);
640 pw.print(mPersistentVrStateRemoteCallbacks.getBroadcastItem(i));
641 if (i>0) pw.println(",");
642 }
643 mPersistentVrStateRemoteCallbacks.finishBroadcast();
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700644 pw.println("\n");
645 pw.println("Installed VrListenerService components:");
646 int userId = mCurrentVrModeUser;
647 ArraySet<ComponentName> installed = mComponentObserver.getInstalled(userId);
648 if (installed == null || installed.size() == 0) {
649 pw.println("None");
650 } else {
651 for (ComponentName n : installed) {
652 pw.print(tab);
653 pw.println(n.flattenToString());
654 }
655 }
656 pw.println("Enabled VrListenerService components:");
657 ArraySet<ComponentName> enabled = mComponentObserver.getEnabled(userId);
658 if (enabled == null || enabled.size() == 0) {
659 pw.println("None");
660 } else {
661 for (ComponentName n : enabled) {
662 pw.print(tab);
663 pw.println(n.flattenToString());
664 }
665 }
666 pw.println("\n");
667 pw.println("********* End of VrManagerService Dump *********");
Dan Sandlerdc34df52016-04-07 21:04:46 -0400668 }
669
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700670 };
671
Santos Cordone6d77232017-08-08 17:11:41 -0700672 /**
673 * Enforces that at lease one of the specified permissions is held by the caller.
674 * Throws SecurityException if none of the specified permissions are held.
675 *
676 * @param permissions One or more permissions to check against.
677 */
678 private void enforceCallerPermissionAnyOf(String... permissions) {
679 for (String permission : permissions) {
680 if (mContext.checkCallingOrSelfPermission(permission)
681 == PackageManager.PERMISSION_GRANTED) {
682 return;
683 }
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700684 }
Santos Cordone6d77232017-08-08 17:11:41 -0700685 throw new SecurityException("Caller does not hold at least one of the permissions: "
686 + Arrays.toString(permissions));
Ruben Brunkc7be3be2016-04-01 17:07:51 -0700687 }
688
Ruben Brunke24b9a62016-02-16 21:38:24 -0800689 /**
690 * Implementation of VrManagerInternal. Callable only from system services.
691 */
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800692 private final class LocalService extends VrManagerInternal {
693 @Override
Albert Chaulk16d23972017-07-14 12:32:57 -0400694 public void setVrMode(boolean enabled, ComponentName packageName, int userId, int processId,
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800695 ComponentName callingPackage) {
Albert Chaulk16d23972017-07-14 12:32:57 -0400696 VrManagerService.this.setVrMode(enabled, packageName, userId, processId, callingPackage);
Ruben Brunkaf9f0042016-06-15 17:08:35 -0700697 }
698
699 @Override
Ruben Brunk040484c2016-10-28 20:18:57 -0700700 public void onSleepStateChanged(boolean isAsleep) {
701 VrManagerService.this.setSleepState(isAsleep);
702 }
703
704 @Override
705 public void onScreenStateChanged(boolean isScreenOn) {
706 VrManagerService.this.setScreenOn(isScreenOn);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800707 }
708
709 @Override
Santos Cordonb5cbecb2017-10-05 11:31:15 -0700710 public void onKeyguardStateChanged(boolean isShowing) {
711 VrManagerService.this.setKeyguardShowing(isShowing);
712 }
713
714 @Override
Ruben Brunk8f1d5cb2016-03-22 18:08:41 -0700715 public boolean isCurrentVrListener(String packageName, int userId) {
716 return VrManagerService.this.isCurrentVrListener(packageName, userId);
717 }
718
719 @Override
Ruben Brunke24b9a62016-02-16 21:38:24 -0800720 public int hasVrPackage(ComponentName packageName, int userId) {
721 return VrManagerService.this.hasVrPackage(packageName, userId);
722 }
Zak Cohen56345f42017-01-26 13:54:28 -0800723
724 @Override
725 public void setPersistentVrModeEnabled(boolean enabled) {
726 VrManagerService.this.setPersistentVrModeEnabled(enabled);
727 }
Zak Cohen732aeb02017-01-29 14:19:52 -0800728
729 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700730 public void setVr2dDisplayProperties(
731 Vr2dDisplayProperties compatDisplayProp) {
732 VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -0700733 }
734
735 @Override
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -0700736 public int getVr2dDisplayId() {
737 return VrManagerService.this.getVr2dDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -0800738 }
739
740 @Override
Steven Thomasb70845c2017-03-16 14:32:37 -0700741 public void addPersistentVrModeStateListener(IPersistentVrStateCallbacks listener) {
742 VrManagerService.this.addPersistentStateCallback(listener);
Zak Cohen732aeb02017-01-29 14:19:52 -0800743 }
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800744 }
745
746 public VrManagerService(Context context) {
747 super(context);
748 }
749
750 @Override
751 public void onStart() {
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800752 synchronized(mLock) {
753 initializeNative();
Ruben Brunke24b9a62016-02-16 21:38:24 -0800754 mContext = getContext();
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800755 }
756
Steven Thomas68cc84f2017-06-08 16:55:04 -0700757 mBootsToVr = SystemProperties.getBoolean("ro.boot.vr", false);
Steven Thomas1356ec92017-09-07 11:26:38 -0700758 mUseStandbyToExitVrMode = mBootsToVr
759 && SystemProperties.getBoolean("persist.vr.use_standby_to_exit_vr_mode", false);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800760 publishLocalService(VrManagerInternal.class, new LocalService());
Craig Donner8deb67c2017-02-07 18:10:32 -0800761 publishBinderService(Context.VR_SERVICE, mVrManager.asBinder());
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800762 }
763
Ruben Brunke24b9a62016-02-16 21:38:24 -0800764 @Override
765 public void onBootPhase(int phase) {
Ruben Brunk85070042016-03-21 12:10:38 -0700766 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
Julia Reynoldsb852e562017-06-06 16:14:18 -0400767 mNotificationManager = INotificationManager.Stub.asInterface(
768 ServiceManager.getService(Context.NOTIFICATION_SERVICE));
Ruben Brunke24b9a62016-02-16 21:38:24 -0800769 synchronized (mLock) {
770 Looper looper = Looper.getMainLooper();
771 Handler handler = new Handler(looper);
772 ArrayList<EnabledComponentChangeListener> listeners = new ArrayList<>();
773 listeners.add(this);
774 mComponentObserver = EnabledComponentsObserver.build(mContext, handler,
775 Settings.Secure.ENABLED_VR_LISTENERS, looper,
776 android.Manifest.permission.BIND_VR_LISTENER_SERVICE,
777 VrListenerService.SERVICE_INTERFACE, mLock, listeners);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800778
Ruben Brunke24b9a62016-02-16 21:38:24 -0800779 mComponentObserver.rebuildAll();
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800780 }
Zak Cohen56345f42017-01-26 13:54:28 -0800781
782 //TODO: something more robust than picking the first one
783 ArraySet<ComponentName> defaultVrComponents =
784 SystemConfig.getInstance().getDefaultVrComponents();
785 if (defaultVrComponents.size() > 0) {
786 mDefaultVrService = defaultVrComponents.valueAt(0);
787 } else {
788 Slog.i(TAG, "No default vr listener service found.");
789 }
Santos Cordon2f22da72017-02-27 17:24:44 -0800790
791 DisplayManager dm =
792 (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700793 mVr2dDisplay = new Vr2dDisplay(
794 dm,
795 LocalServices.getService(ActivityManagerInternal.class),
796 LocalServices.getService(WindowManagerInternal.class),
797 mVrManager);
Santos Cordonc22c5632017-06-21 16:03:49 -0700798 mVr2dDisplay.init(getContext(), mBootsToVr);
Steven Thomas68cc84f2017-06-08 16:55:04 -0700799
800 IntentFilter intentFilter = new IntentFilter();
801 intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
802 getContext().registerReceiver(new BroadcastReceiver() {
803 @Override
804 public void onReceive(Context context, Intent intent) {
805 if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
806 VrManagerService.this.setUserUnlocked();
807 }
808 }
809 }, intentFilter);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800810 }
811 }
812
Ruben Brunke24b9a62016-02-16 21:38:24 -0800813 @Override
814 public void onStartUser(int userHandle) {
815 synchronized (mLock) {
816 mComponentObserver.onUsersChanged();
817 }
818 }
819
820 @Override
821 public void onSwitchUser(int userHandle) {
822 synchronized (mLock) {
823 mComponentObserver.onUsersChanged();
824 }
825
826 }
827
828 @Override
829 public void onStopUser(int userHandle) {
830 synchronized (mLock) {
831 mComponentObserver.onUsersChanged();
832 }
833
834 }
835
836 @Override
837 public void onCleanupUser(int userHandle) {
838 synchronized (mLock) {
839 mComponentObserver.onUsersChanged();
840 }
841 }
842
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700843 private void updateOverlayStateLocked(String exemptedPackage, int newUserId, int oldUserId) {
844 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
845
846 // If user changed drop restrictions for the old user.
847 if (oldUserId != newUserId) {
848 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
849 false, mOverlayToken, null, oldUserId);
850 }
851
852 // Apply the restrictions for the current user based on vr state
853 String[] exemptions = (exemptedPackage == null) ? new String[0] :
854 new String[] { exemptedPackage };
855
856 appOpsManager.setUserRestrictionForUser(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
Ruben Brunk2781b412017-04-24 12:07:17 -0700857 mVrModeEnabled, mOverlayToken, exemptions, newUserId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700858 }
859
860 private void updateDependentAppOpsLocked(String newVrServicePackage, int newUserId,
861 String oldVrServicePackage, int oldUserId) {
862 // If VR state changed and we also have a VR service change.
863 if (Objects.equals(newVrServicePackage, oldVrServicePackage)) {
864 return;
865 }
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800866 final long identity = Binder.clearCallingIdentity();
867 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700868 // Set overlay exception state based on VR enabled and current service
869 updateOverlayStateLocked(newVrServicePackage, newUserId, oldUserId);
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800870 } finally {
871 Binder.restoreCallingIdentity(identity);
872 }
873 }
874
Ruben Brunke24b9a62016-02-16 21:38:24 -0800875 /**
876 * Send VR mode changes (if the mode state has changed), and update the bound/unbound state of
877 * the currently selected VR listener service. If the component selected for the VR listener
878 * service has changed, unbind the previous listener and bind the new listener (if enabled).
879 * <p/>
880 * Note: Must be called while holding {@code mLock}.
881 *
882 * @param enabled new state for VR mode.
Albert Chaulk16d23972017-07-14 12:32:57 -0400883 * @param running2dInVr true if we have a top-level 2D intent.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800884 * @param component new component to be bound as a VR listener.
885 * @param userId user owning the component to be bound.
Albert Chaulk16d23972017-07-14 12:32:57 -0400886 * @param processId the process hosting the activity specified by calling.
887 * @param calling the component currently using VR mode or a 2D intent.
Ruben Brunke24b9a62016-02-16 21:38:24 -0800888 *
889 * @return {@code true} if the component/user combination specified is valid.
890 */
Albert Chaulk16d23972017-07-14 12:32:57 -0400891 private boolean updateCurrentVrServiceLocked(boolean enabled, boolean running2dInVr,
892 @NonNull ComponentName component, int userId, int processId, ComponentName calling) {
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800893
894 boolean sendUpdatedCaller = false;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800895 final long identity = Binder.clearCallingIdentity();
896 try {
Ruben Brunke24b9a62016-02-16 21:38:24 -0800897
Ruben Brunk98576cf2016-03-07 18:54:28 -0800898 boolean validUserComponent = (mComponentObserver.isValid(component, userId) ==
899 EnabledComponentsObserver.NO_ERROR);
Ruben Brunk040484c2016-10-28 20:18:57 -0700900 boolean goingIntoVrMode = validUserComponent && enabled;
901 if (!mVrModeEnabled && !goingIntoVrMode) {
Ruben Brunk2ff9c012016-04-28 10:58:29 -0700902 return validUserComponent; // Disabled -> Disabled transition does nothing.
903 }
Ruben Brunke24b9a62016-02-16 21:38:24 -0800904
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700905 String oldVrServicePackage = mCurrentVrService != null
906 ? mCurrentVrService.getComponent().getPackageName() : null;
907 final int oldUserId = mCurrentVrModeUser;
908
Ruben Brunk040484c2016-10-28 20:18:57 -0700909 // Notify system services and VR HAL of mode change.
910 changeVrModeLocked(goingIntoVrMode);
Ruben Brunk29931bc2016-03-11 00:24:26 -0800911
Ruben Brunk040484c2016-10-28 20:18:57 -0700912 boolean nothingChanged = false;
913 if (!goingIntoVrMode) {
914 // Not going into VR mode, unbind whatever is running
Ruben Brunk98576cf2016-03-07 18:54:28 -0800915 if (mCurrentVrService != null) {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800916 Slog.i(TAG, "Leaving VR mode, disconnecting "
917 + mCurrentVrService.getComponent() + " for user "
918 + mCurrentVrService.getUserId());
Ruben Brunk98576cf2016-03-07 18:54:28 -0800919 mCurrentVrService.disconnect();
Ruben Brunk52ea6622017-10-02 23:51:25 -0700920 updateCompositorServiceLocked(UserHandle.USER_NULL, null);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800921 mCurrentVrService = null;
Ruben Brunk040484c2016-10-28 20:18:57 -0700922 } else {
923 nothingChanged = true;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800924 }
925 } else {
Ruben Brunk040484c2016-10-28 20:18:57 -0700926 // Going into VR mode
Ruben Brunk98576cf2016-03-07 18:54:28 -0800927 if (mCurrentVrService != null) {
Ruben Brunk040484c2016-10-28 20:18:57 -0700928 // Unbind any running service that doesn't match the latest component/user
929 // selection.
Ruben Brunk98576cf2016-03-07 18:54:28 -0800930 if (mCurrentVrService.disconnectIfNotMatching(component, userId)) {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -0800931 Slog.i(TAG, "VR mode component changed to " + component
932 + ", disconnecting " + mCurrentVrService.getComponent()
933 + " for user " + mCurrentVrService.getUserId());
Ruben Brunk52ea6622017-10-02 23:51:25 -0700934 updateCompositorServiceLocked(UserHandle.USER_NULL, null);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800935 createAndConnectService(component, userId);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800936 sendUpdatedCaller = true;
Ruben Brunk040484c2016-10-28 20:18:57 -0700937 } else {
938 nothingChanged = true;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800939 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700940 // The service with the correct component/user is already bound, do nothing.
Ruben Brunk98576cf2016-03-07 18:54:28 -0800941 } else {
Ruben Brunk040484c2016-10-28 20:18:57 -0700942 // Nothing was previously running, bind a new service for the latest
943 // component/user selection.
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800944 createAndConnectService(component, userId);
945 sendUpdatedCaller = true;
946 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800947 }
948
Ruben Brunk666505e2017-05-04 16:54:46 -0700949 if ((calling != null || mPersistentVrModeEnabled)
Alex Sakhartchoukec4d3e42017-07-24 22:12:39 -0400950 && !Objects.equals(calling, mCurrentVrModeComponent)
951 || mRunning2dInVr != running2dInVr) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700952 sendUpdatedCaller = true;
953 }
Ruben Brunk7196a6b2017-03-22 15:43:24 -0700954 mCurrentVrModeComponent = calling;
Albert Chaulk16d23972017-07-14 12:32:57 -0400955 mRunning2dInVr = running2dInVr;
956 mVrAppProcessId = processId;
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700957
958 if (mCurrentVrModeUser != userId) {
Ruben Brunk98576cf2016-03-07 18:54:28 -0800959 mCurrentVrModeUser = userId;
Ruben Brunkc7354fe2016-03-07 23:37:12 -0800960 sendUpdatedCaller = true;
961 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800962
Svetoslav Ganove33f6132016-06-01 16:25:31 -0700963 String newVrServicePackage = mCurrentVrService != null
964 ? mCurrentVrService.getComponent().getPackageName() : null;
965 final int newUserId = mCurrentVrModeUser;
966
967 // Update AppOps settings that change state when entering/exiting VR mode, or changing
968 // the current VrListenerService.
969 updateDependentAppOpsLocked(newVrServicePackage, newUserId,
970 oldVrServicePackage, oldUserId);
971
Ruben Brunk98576cf2016-03-07 18:54:28 -0800972 if (mCurrentVrService != null && sendUpdatedCaller) {
973 final ComponentName c = mCurrentVrModeComponent;
Albert Chaulk16d23972017-07-14 12:32:57 -0400974 final boolean b = running2dInVr;
975 final int pid = processId;
Ruben Brunk98576cf2016-03-07 18:54:28 -0800976 mCurrentVrService.sendEvent(new PendingEvent() {
977 @Override
978 public void runEvent(IInterface service) throws RemoteException {
979 IVrListener l = (IVrListener) service;
Albert Chaulk16d23972017-07-14 12:32:57 -0400980 l.focusedActivityChanged(c, b, pid);
Ruben Brunk98576cf2016-03-07 18:54:28 -0800981 }
982 });
983 }
Ruben Brunk040484c2016-10-28 20:18:57 -0700984
985 if (!nothingChanged) {
986 logStateLocked();
987 }
Ruben Brunk98576cf2016-03-07 18:54:28 -0800988
989 return validUserComponent;
990 } finally {
991 Binder.restoreCallingIdentity(identity);
992 }
993 }
994
Ruben Brunk8820f942016-05-09 12:46:28 -0700995 private boolean isDefaultAllowed(String packageName) {
Craig Donner0568f282016-04-11 13:02:44 -0700996 PackageManager pm = mContext.getPackageManager();
Ruben Brunk8820f942016-05-09 12:46:28 -0700997
998 ApplicationInfo info = null;
999 try {
1000 info = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
1001 } catch (NameNotFoundException e) {
1002 }
1003
1004 if (info == null || !(info.isSystemApp() || info.isUpdatedSystemApp())) {
1005 return false;
1006 }
1007 return true;
1008 }
1009
Ruben Brunk98576cf2016-03-07 18:54:28 -08001010 private void grantNotificationPolicyAccess(String pkg) {
1011 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk8820f942016-05-09 12:46:28 -07001012 nm.setNotificationPolicyAccessGranted(pkg, true);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001013 }
1014
1015 private void revokeNotificationPolicyAccess(String pkg) {
1016 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk8820f942016-05-09 12:46:28 -07001017 // Remove any DND zen rules possibly created by the package.
1018 nm.removeAutomaticZenRules(pkg);
1019 // Remove Notification Policy Access.
1020 nm.setNotificationPolicyAccessGranted(pkg, false);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001021 }
1022
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001023 private void grantNotificationListenerAccess(String pkg, int userId) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001024 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001025 PackageManager pm = mContext.getPackageManager();
1026 ArraySet<ComponentName> possibleServices = EnabledComponentsObserver.loadComponentNames(pm,
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001027 userId, NotificationListenerService.SERVICE_INTERFACE,
Ruben Brunk98576cf2016-03-07 18:54:28 -08001028 android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001029
Ruben Brunk98576cf2016-03-07 18:54:28 -08001030 for (ComponentName c : possibleServices) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001031 if (Objects.equals(c.getPackageName(), pkg)) {
1032 nm.setNotificationListenerAccessGrantedForUser(c, userId, true);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001033 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001034 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001035 }
1036
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001037 private void revokeNotificationListenerAccess(String pkg, int userId) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001038 NotificationManager nm = mContext.getSystemService(NotificationManager.class);
1039 List<ComponentName> current = nm.getEnabledNotificationListeners(userId);
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001040
Julia Reynoldsb852e562017-06-06 16:14:18 -04001041 for (ComponentName component : current) {
Ruben Brunk1f4f26b2016-08-02 14:21:36 -07001042 if (component != null && component.getPackageName().equals(pkg)) {
Julia Reynoldsb852e562017-06-06 16:14:18 -04001043 nm.setNotificationListenerAccessGrantedForUser(component, userId, false);
Ruben Brunk8820f942016-05-09 12:46:28 -07001044 }
1045 }
Ruben Brunk98576cf2016-03-07 18:54:28 -08001046 }
1047
Craig Donnercae8cdf2016-07-28 22:39:05 +00001048 private void grantCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1049 // Don't clobber the user if permission set in current state explicitly
1050 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
Ruben Brunk12ab5e12016-11-10 15:27:30 -08001051 try {
1052 mContext.getPackageManager().grantRuntimePermission(pkg,
1053 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1054 } catch (IllegalArgumentException e) {
1055 // Package was removed during update.
1056 Slog.w(TAG, "Could not grant coarse location permission, package " + pkg
1057 + " was removed.");
1058 }
Craig Donnercae8cdf2016-07-28 22:39:05 +00001059 }
1060 }
1061
1062 private void revokeCoarseLocationPermissionIfNeeded(String pkg, int userId) {
1063 // Don't clobber the user if permission set in current state explicitly
1064 if (!isPermissionUserUpdated(Manifest.permission.ACCESS_COARSE_LOCATION, pkg, userId)) {
Ruben Brunk12ab5e12016-11-10 15:27:30 -08001065 try {
1066 mContext.getPackageManager().revokeRuntimePermission(pkg,
1067 Manifest.permission.ACCESS_COARSE_LOCATION, new UserHandle(userId));
1068 } catch (IllegalArgumentException e) {
1069 // Package was removed during update.
1070 Slog.w(TAG, "Could not revoke coarse location permission, package " + pkg
1071 + " was removed.");
1072 }
Craig Donnercae8cdf2016-07-28 22:39:05 +00001073 }
1074 }
1075
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001076 private boolean isPermissionUserUpdated(String permission, String pkg, int userId) {
1077 final int flags = mContext.getPackageManager().getPermissionFlags(
1078 permission, pkg, new UserHandle(userId));
1079 return (flags & (PackageManager.FLAG_PERMISSION_USER_SET
1080 | PackageManager.FLAG_PERMISSION_USER_FIXED)) != 0;
1081 }
1082
1083 private ArraySet<String> getNotificationListeners(ContentResolver resolver, int userId) {
1084 String flat = Settings.Secure.getStringForUser(resolver,
1085 Settings.Secure.ENABLED_NOTIFICATION_LISTENERS, userId);
Ruben Brunk98576cf2016-03-07 18:54:28 -08001086
1087 ArraySet<String> current = new ArraySet<>();
1088 if (flat != null) {
1089 String[] allowed = flat.split(":");
1090 for (String s : allowed) {
Ruben Brunk1f4f26b2016-08-02 14:21:36 -07001091 if (!TextUtils.isEmpty(s)) {
1092 current.add(s);
1093 }
Ruben Brunk98576cf2016-03-07 18:54:28 -08001094 }
1095 }
1096 return current;
1097 }
1098
1099 private static String formatSettings(Collection<String> c) {
1100 if (c == null || c.isEmpty()) {
1101 return "";
1102 }
1103
1104 StringBuilder b = new StringBuilder();
1105 boolean start = true;
1106 for (String s : c) {
1107 if ("".equals(s)) {
1108 continue;
1109 }
1110 if (!start) {
1111 b.append(':');
1112 }
1113 b.append(s);
1114 start = false;
1115 }
1116 return b.toString();
1117 }
1118
1119
1120
Ruben Brunkc7354fe2016-03-07 23:37:12 -08001121 private void createAndConnectService(@NonNull ComponentName component, int userId) {
Ruben Brunkd675f512017-10-03 15:39:41 -07001122 mCurrentVrService = createVrListenerService(component, userId);
Ruben Brunkc7354fe2016-03-07 23:37:12 -08001123 mCurrentVrService.connect();
1124 Slog.i(TAG, "Connecting " + component + " for user " + userId);
1125 }
1126
Ruben Brunke24b9a62016-02-16 21:38:24 -08001127 /**
1128 * Send VR mode change callbacks to HAL and system services if mode has actually changed.
1129 * <p/>
1130 * Note: Must be called while holding {@code mLock}.
1131 *
1132 * @param enabled new state of the VR mode.
1133 */
Svetoslav Ganove33f6132016-06-01 16:25:31 -07001134 private void changeVrModeLocked(boolean enabled) {
Ruben Brunke24b9a62016-02-16 21:38:24 -08001135 if (mVrModeEnabled != enabled) {
1136 mVrModeEnabled = enabled;
1137
1138 // Log mode change event.
1139 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
1140 setVrModeNative(mVrModeEnabled);
1141
Ruben Brunke24b9a62016-02-16 21:38:24 -08001142 onVrModeChangedLocked();
1143 }
1144 }
1145
1146 /**
1147 * Notify system services of VR mode change.
1148 * <p/>
1149 * Note: Must be called while holding {@code mLock}.
1150 */
1151 private void onVrModeChangedLocked() {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001152 mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE,
1153 (mVrModeEnabled) ? 1 : 0, 0));
Ruben Brunke24b9a62016-02-16 21:38:24 -08001154 }
1155
1156 /**
Ruben Brunkd675f512017-10-03 15:39:41 -07001157 * Helper function for making ManagedApplicationService for VrListenerService instances.
Ruben Brunke24b9a62016-02-16 21:38:24 -08001158 */
Ruben Brunkd675f512017-10-03 15:39:41 -07001159 private ManagedApplicationService createVrListenerService(@NonNull ComponentName component,
1160 int userId) {
1161 int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1162 : ManagedApplicationService.RETRY_NEVER;
1163 return ManagedApplicationService.build(mContext, component, userId,
Ruben Brunke24b9a62016-02-16 21:38:24 -08001164 R.string.vr_listener_binding_label, Settings.ACTION_VR_LISTENER_SETTINGS,
Ruben Brunkd675f512017-10-03 15:39:41 -07001165 sBinderChecker, /*isImportant*/true, retryType, mHandler, mEventCallback);
1166 }
1167
1168 /**
1169 * Helper function for making ManagedApplicationService for VR Compositor instances.
1170 */
1171 private ManagedApplicationService createVrCompositorService(@NonNull ComponentName component,
1172 int userId) {
1173 int retryType = (mBootsToVr) ? ManagedApplicationService.RETRY_FOREVER
1174 : ManagedApplicationService.RETRY_BEST_EFFORT;
1175 return ManagedApplicationService.build(mContext, component, userId, /*clientLabel*/0,
1176 /*settingsAction*/null, /*binderChecker*/null, /*isImportant*/true, retryType,
1177 mHandler, /*disconnectCallback*/mEventCallback);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001178 }
1179
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001180 /**
1181 * Apply the pending VR state. If no state is pending, disconnect any currently bound
1182 * VR listener service.
1183 */
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001184 private void consumeAndApplyPendingStateLocked() {
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001185 consumeAndApplyPendingStateLocked(true);
1186 }
1187
1188 /**
1189 * Apply the pending VR state.
1190 *
1191 * @param disconnectIfNoPendingState if {@code true}, then any currently bound VR listener
1192 * service will be disconnected if no state is pending. If this is {@code false} then the
1193 * nothing will be changed when there is no pending state.
1194 */
1195 private void consumeAndApplyPendingStateLocked(boolean disconnectIfNoPendingState) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001196 if (mPendingState != null) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001197 updateCurrentVrServiceLocked(mPendingState.enabled, mPendingState.running2dInVr,
1198 mPendingState.targetPackageName, mPendingState.userId, mPendingState.processId,
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001199 mPendingState.callingPackage);
1200 mPendingState = null;
Ruben Brunk1ad4a2d2017-01-06 11:23:49 -08001201 } else if (disconnectIfNoPendingState) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001202 updateCurrentVrServiceLocked(false, false, null, 0, -1, null);
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001203 }
1204 }
1205
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001206 private void logStateLocked() {
1207 ComponentName currentBoundService = (mCurrentVrService == null) ? null :
Ruben Brunkd675f512017-10-03 15:39:41 -07001208 mCurrentVrService.getComponent();
1209 logEvent(new VrState(mVrModeEnabled, mRunning2dInVr, currentBoundService,
1210 mCurrentVrModeUser, mVrAppProcessId, mCurrentVrModeComponent, mWasDefaultGranted));
1211 }
1212
1213 private void logEvent(LogFormattable event) {
1214 synchronized (mLoggingDeque) {
1215 if (mLoggingDeque.size() == EVENT_LOG_SIZE) {
1216 mLoggingDeque.removeFirst();
1217 mLogLimitHit = true;
1218 }
1219 mLoggingDeque.add(event);
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001220 }
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001221 }
1222
1223 private void dumpStateTransitions(PrintWriter pw) {
1224 SimpleDateFormat d = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
Ruben Brunkd675f512017-10-03 15:39:41 -07001225 synchronized (mLoggingDeque) {
1226 if (mLoggingDeque.size() == 0) {
1227 pw.print(" ");
1228 pw.println("None");
1229 }
1230
1231 if (mLogLimitHit) {
1232 pw.println("..."); // Indicates log overflow
1233 }
1234
1235 for (LogFormattable event : mLoggingDeque) {
1236 pw.println(event.toLogString(d));
Ruben Brunk2ff9c012016-04-28 10:58:29 -07001237 }
1238 }
1239 }
1240
Ruben Brunke24b9a62016-02-16 21:38:24 -08001241 /*
1242 * Implementation of VrManagerInternal calls. These are callable from system services.
1243 */
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001244 private void setVrMode(boolean enabled, @NonNull ComponentName targetPackageName,
Albert Chaulk16d23972017-07-14 12:32:57 -04001245 int userId, int processId, @NonNull ComponentName callingPackage) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001246
Ruben Brunke24b9a62016-02-16 21:38:24 -08001247 synchronized (mLock) {
Zak Cohen56345f42017-01-26 13:54:28 -08001248 VrState pending;
1249 ComponentName targetListener;
Zak Cohen56345f42017-01-26 13:54:28 -08001250
1251 // If the device is in persistent VR mode, then calls to disable VR mode are ignored,
1252 // and the system default VR listener is used.
1253 boolean targetEnabledState = enabled || mPersistentVrModeEnabled;
Albert Chaulk16d23972017-07-14 12:32:57 -04001254 boolean running2dInVr = !enabled && mPersistentVrModeEnabled;
1255 if (running2dInVr) {
Zak Cohen56345f42017-01-26 13:54:28 -08001256 targetListener = mDefaultVrService;
Zak Cohen56345f42017-01-26 13:54:28 -08001257 } else {
1258 targetListener = targetPackageName;
Zak Cohen56345f42017-01-26 13:54:28 -08001259 }
Albert Chaulk16d23972017-07-14 12:32:57 -04001260
1261 pending = new VrState(targetEnabledState, running2dInVr, targetListener,
1262 userId, processId, callingPackage);
Zak Cohen56345f42017-01-26 13:54:28 -08001263
Ruben Brunk040484c2016-10-28 20:18:57 -07001264 if (!mVrModeAllowed) {
1265 // We're not allowed to be in VR mode. Make this state pending. This will be
1266 // applied the next time we are allowed to enter VR mode unless it is superseded by
1267 // another call.
1268 mPendingState = pending;
1269 return;
1270 }
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001271
Zak Cohen56345f42017-01-26 13:54:28 -08001272 if (!targetEnabledState && mCurrentVrService != null) {
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001273 // If we're transitioning out of VR mode, delay briefly to avoid expensive HAL calls
1274 // and service bind/unbind in case we are immediately switching to another VR app.
1275 if (mPendingState == null) {
1276 mHandler.sendEmptyMessageDelayed(MSG_PENDING_VR_STATE_CHANGE,
1277 PENDING_STATE_DELAY_MS);
1278 }
1279
Ruben Brunk040484c2016-10-28 20:18:57 -07001280 mPendingState = pending;
Ruben Brunkb56b72a2016-04-15 11:53:09 -07001281 return;
1282 } else {
1283 mHandler.removeMessages(MSG_PENDING_VR_STATE_CHANGE);
1284 mPendingState = null;
1285 }
1286
Albert Chaulk16d23972017-07-14 12:32:57 -04001287 updateCurrentVrServiceLocked(targetEnabledState, running2dInVr, targetListener,
1288 userId, processId, callingPackage);
Zak Cohen56345f42017-01-26 13:54:28 -08001289 }
1290 }
1291
1292 private void setPersistentVrModeEnabled(boolean enabled) {
Zak Cohen732aeb02017-01-29 14:19:52 -08001293 synchronized(mLock) {
1294 setPersistentModeAndNotifyListenersLocked(enabled);
Alex Sakhartchouka26b4352017-07-25 17:08:43 -04001295 // Disabling persistent mode should disable the overall vr mode.
1296 if (!enabled) {
Albert Chaulk16d23972017-07-14 12:32:57 -04001297 setVrMode(false, null, 0, -1, null);
Zak Cohen56345f42017-01-26 13:54:28 -08001298 }
Ruben Brunke24b9a62016-02-16 21:38:24 -08001299 }
1300 }
1301
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001302 public void setVr2dDisplayProperties(
1303 Vr2dDisplayProperties compatDisplayProp) {
1304 if (mVr2dDisplay != null) {
1305 mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -07001306 return;
1307 }
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001308 Slog.w(TAG, "Vr2dDisplay is null!");
Karthik Ravi Shankarcdf9ce72017-04-12 15:31:20 -07001309 }
1310
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001311 private int getVr2dDisplayId() {
1312 if (mVr2dDisplay != null) {
1313 return mVr2dDisplay.getVirtualDisplayId();
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -08001314 }
Karthik Ravi Shankar2b9aaed2017-05-01 01:34:19 -07001315 Slog.w(TAG, "Vr2dDisplay is null!");
Karthik Ravi Shankar3a47ec22017-03-08 18:09:35 -08001316 return INVALID_DISPLAY;
1317 }
1318
Ruben Brunk52ea6622017-10-02 23:51:25 -07001319 private void setAndBindCompositor(ComponentName componentName) {
1320 final int userId = UserHandle.getCallingUserId();
1321 final long token = Binder.clearCallingIdentity();
1322 synchronized (mLock) {
1323 updateCompositorServiceLocked(userId, componentName);
1324 }
1325 Binder.restoreCallingIdentity(token);
1326 }
1327
1328 private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
1329 if (mCurrentVrCompositorService != null
1330 && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
Ruben Brunkd675f512017-10-03 15:39:41 -07001331 Slog.i(TAG, "Disconnecting compositor service: "
1332 + mCurrentVrCompositorService.getComponent());
Ruben Brunk52ea6622017-10-02 23:51:25 -07001333 // Check if existing service matches the requested one, if not (or if the requested
1334 // component is null) disconnect it.
1335 mCurrentVrCompositorService = null;
1336 }
1337
1338 if (componentName != null && mCurrentVrCompositorService == null) {
1339 // We don't have an existing service matching the requested component, so attempt to
1340 // connect one.
Ruben Brunkd675f512017-10-03 15:39:41 -07001341 Slog.i(TAG, "Connecting compositor service: " + componentName);
1342 mCurrentVrCompositorService = createVrCompositorService(componentName, userId);
Ruben Brunk52ea6622017-10-02 23:51:25 -07001343 mCurrentVrCompositorService.connect();
1344 }
1345 }
1346
Zak Cohen732aeb02017-01-29 14:19:52 -08001347 private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
1348 if (mPersistentVrModeEnabled == enabled) {
1349 return;
1350 }
Ruben Brunkd675f512017-10-03 15:39:41 -07001351 String eventName = "Persistent VR mode " + ((enabled) ? "enabled" : "disabled");
1352 Slog.i(TAG, eventName);
1353 logEvent(new SettingEvent(eventName));
Zak Cohen732aeb02017-01-29 14:19:52 -08001354 mPersistentVrModeEnabled = enabled;
1355
1356 mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
1357 (mPersistentVrModeEnabled) ? 1 : 0, 0));
1358 }
1359
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001360 private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001361 synchronized (mLock) {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001362 return mComponentObserver.isValid(targetPackageName, userId);
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001363 }
1364 }
1365
Ruben Brunk8f1d5cb2016-03-22 18:08:41 -07001366 private boolean isCurrentVrListener(String packageName, int userId) {
1367 synchronized (mLock) {
1368 if (mCurrentVrService == null) {
1369 return false;
1370 }
1371 return mCurrentVrService.getComponent().getPackageName().equals(packageName) &&
1372 userId == mCurrentVrService.getUserId();
1373 }
1374 }
1375
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001376 /*
1377 * Implementation of IVrManager calls.
1378 */
1379
1380 private void addStateCallback(IVrStateCallbacks cb) {
Steven Thomasb70845c2017-03-16 14:32:37 -07001381 mVrStateRemoteCallbacks.register(cb);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001382 }
1383
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001384 private void removeStateCallback(IVrStateCallbacks cb) {
Steven Thomasb70845c2017-03-16 14:32:37 -07001385 mVrStateRemoteCallbacks.unregister(cb);
1386 }
1387
1388 private void addPersistentStateCallback(IPersistentVrStateCallbacks cb) {
1389 mPersistentVrStateRemoteCallbacks.register(cb);
1390 }
1391
1392 private void removePersistentStateCallback(IPersistentVrStateCallbacks cb) {
1393 mPersistentVrStateRemoteCallbacks.unregister(cb);
Ruben Brunke24b9a62016-02-16 21:38:24 -08001394 }
1395
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001396 private boolean getVrMode() {
Ruben Brunke24b9a62016-02-16 21:38:24 -08001397 synchronized (mLock) {
Ruben Brunkc7be3be2016-04-01 17:07:51 -07001398 return mVrModeEnabled;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001399 }
1400 }
Santos Cordone6d77232017-08-08 17:11:41 -07001401
1402 private boolean getPersistentVrMode() {
1403 synchronized (mLock) {
1404 return mPersistentVrModeEnabled;
1405 }
1406 }
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001407}