blob: 7611527d2b995a61ed61a0d3d351b6d64daf5d18 [file] [log] [blame]
Ruben Brunkdd18a0b2015-12-04 16:16:31 -08001/*
2 * 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
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080018import android.app.AppOpsManager;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080019import android.content.Context;
20import android.content.Intent;
21import android.content.pm.PackageManager;
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080022import android.os.Binder;
23import android.os.IBinder;
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080024import android.os.UserHandle;
25import android.util.ArraySet;
26import android.util.Slog;
27
28import com.android.server.SystemService;
29
30import java.util.ArrayList;
31
32/**
33 * Service tracking whether VR mode is active, and notifying listening system services of state
34 * changes.
35 *
36 * {@hide}
37 */
38public class VrManagerService extends SystemService {
39
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080040 public static final String TAG = "VrManagerService";
41
Ruben Brunkbaa4b552016-02-02 16:27:37 -080042 private static native void initializeNative();
43 private static native void setVrModeNative(boolean enabled);
44
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080045 private final Object mLock = new Object();
Svetoslav Ganov47d98de2016-03-01 15:01:14 -080046
47 private final IBinder mOverlayToken = new Binder();
48
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080049 private boolean mVrModeEnabled = false;
50 private ArraySet<VrStateListener> mListeners = new ArraySet<>();
51
52 private final class LocalService extends VrManagerInternal {
53 @Override
54 public boolean isInVrMode() {
55 return VrManagerService.this.getVrMode();
56 }
57
58 @Override
59 public void setVrMode(boolean enabled) {
60 VrManagerService.this.setVrMode(enabled);
61 }
62
63 @Override
64 public void registerListener(VrStateListener listener) {
65 VrManagerService.this.addListener(listener);
66 }
67
68 @Override
69 public void unregisterListener(VrStateListener listener) {
70 VrManagerService.this.removeListener(listener);
71 }
72 }
73
74 public VrManagerService(Context context) {
75 super(context);
76 }
77
78 @Override
79 public void onStart() {
Ruben Brunkbaa4b552016-02-02 16:27:37 -080080 synchronized(mLock) {
81 initializeNative();
82 }
83
Ruben Brunkdd18a0b2015-12-04 16:16:31 -080084 publishLocalService(VrManagerInternal.class, new LocalService());
85 }
86
87 private void addListener(VrStateListener listener) {
88 synchronized (mLock) {
89 mListeners.add(listener);
90 }
91 }
92
93 private void removeListener(VrStateListener listener) {
94 synchronized (mLock) {
95 mListeners.remove(listener);
96 }
97 }
98
99 private void setVrMode(boolean enabled) {
100 synchronized (mLock) {
101 if (mVrModeEnabled != enabled) {
102 mVrModeEnabled = enabled;
Ruben Brunk87112f72016-01-22 12:48:26 -0800103 // Log mode change event.
104 Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled"));
Ruben Brunkbaa4b552016-02-02 16:27:37 -0800105 setVrModeNative(mVrModeEnabled);
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800106 updateOverlayStateLocked();
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800107 onVrModeChangedLocked();
108 }
109 }
110 }
111
Svetoslav Ganov47d98de2016-03-01 15:01:14 -0800112 private void updateOverlayStateLocked() {
113 final long identity = Binder.clearCallingIdentity();
114 try {
115 AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
116 if (appOpsManager != null) {
117 appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
118 mVrModeEnabled, mOverlayToken);
119 }
120 } finally {
121 Binder.restoreCallingIdentity(identity);
122 }
123 }
124
Ruben Brunkdd18a0b2015-12-04 16:16:31 -0800125 private boolean getVrMode() {
126 synchronized (mLock) {
127 return mVrModeEnabled;
128 }
129 }
130
131 /**
132 * Notify system services of VR mode change.
133 */
134 private void onVrModeChangedLocked() {
135 for (VrStateListener l : mListeners) {
136 l.onVrStateChanged(mVrModeEnabled);
137 }
138 }
139}