VrListenerService.java revision c7354fe2d4d73808929d2087f2d18ee3d8fa47fc
1/**
2 * Copyright (C) 2016 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 */
16
17package android.service.vr;
18
19import android.annotation.NonNull;
20import android.annotation.SdkConstant;
21import android.app.ActivityManager;
22import android.app.Service;
23import android.content.ComponentName;
24import android.content.Context;
25import android.content.Intent;
26import android.os.Handler;
27import android.os.IBinder;
28import android.os.Looper;
29import android.os.Message;
30
31/**
32 * A service that is bound from the system while running in virtual reality (VR) mode.
33 *
34 * <p>To extend this class, you must declare the service in your manifest file with
35 * the {@link android.Manifest.permission#BIND_VR_LISTENER_SERVICE} permission
36 * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
37 * <pre>
38 * &lt;service android:name=".VrListener"
39 *          android:label="&#64;string/service_name"
40 *          android:permission="android.permission.BIND_VR_LISTENER_SERVICE">
41 *     &lt;intent-filter>
42 *         &lt;action android:name="android.service.vr.VrListenerService" />
43 *     &lt;/intent-filter>
44 * &lt;/service>
45 * </pre>
46 *
47 * <p>
48 * This service is bound when the system enters VR mode and is unbound when the system leaves VR
49 * mode.
50 * {@see android.app.Activity#setVrMode(boolean)}
51 * </p>
52 */
53public abstract class VrListenerService extends Service {
54
55    /**
56     * The {@link Intent} that must be declared as handled by the service.
57     */
58    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
59    public static final String SERVICE_INTERFACE = "android.service.vr.VrListenerService";
60
61    private final Handler mHandler;
62
63    private static final int MSG_ON_CURRENT_VR_ACTIVITY_CHANGED = 1;
64
65    private final IVrListener.Stub mBinder = new IVrListener.Stub() {
66        @Override
67        public void focusedActivityChanged(ComponentName component) {
68            mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget();
69        }
70    };
71
72    private final class VrListenerHandler extends Handler {
73        public VrListenerHandler(Looper looper) {
74            super(looper);
75        }
76
77        @Override
78        public void handleMessage(Message msg) {
79            switch (msg.what) {
80                case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: {
81                    VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj);
82                } break;
83            }
84        }
85    }
86
87    @Override
88    public IBinder onBind(Intent intent) {
89        return mBinder;
90    }
91
92    public VrListenerService() {
93        mHandler = new VrListenerHandler(Looper.getMainLooper());
94    }
95
96    /**
97     * Called when the current activity using VR mode is changed.
98     * <p/>
99     * This will be called immediately when this service is initially bound, but is
100     * not guaranteed to be called before onUnbind.
101     *
102     * @param component the {@link ComponentName} of the new current VR activity.
103     */
104    public void onCurrentVrActivityChanged(ComponentName component) {
105        // Override to implement
106    }
107
108    /**
109     * Check if the given package is available to be enabled/disabled in VR mode settings.
110     *
111     * @param context the {@link Context} to use for looking up the requested component.
112     * @param requestedComponent the name of the component that implements
113     * {@link android.service.vr.VrListenerService} to check.
114     *
115     * @return {@code true} if this package is enabled in settings.
116     */
117    public static final boolean isVrModePackageEnabled(@NonNull Context context,
118            @NonNull ComponentName requestedComponent) {
119        ActivityManager am = context.getSystemService(ActivityManager.class);
120        if (am == null) {
121            return false;
122        }
123        return am.isVrModePackageEnabled(requestedComponent);
124    }
125}
126