/** * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.service.vr; import android.annotation.NonNull; import android.annotation.SdkConstant; import android.app.ActivityManager; import android.app.Service; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; /** * A service that is bound from the system while running in virtual reality (VR) mode. * *

To extend this class, you must declare the service in your manifest file with * the {@link android.Manifest.permission#BIND_VR_LISTENER_SERVICE} permission * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:

*
 * <service android:name=".VrListener"
 *          android:label="@string/service_name"
 *          android:permission="android.permission.BIND_VR_LISTENER_SERVICE">
 *     <intent-filter>
 *         <action android:name="android.service.vr.VrListenerService" />
 *     </intent-filter>
 * </service>
 * 
* *

This service is bound when the system enters VR mode and is unbound when the system leaves VR * mode.

*

The system will enter VR mode when an application that has previously called * {@link android.app.Activity#setVrModeEnabled} gains user focus. The system will only start this * service if the VR application has specifically targeted this service by specifying * its {@link ComponentName} in the call to {@link android.app.Activity#setVrModeEnabled} and if * this service is installed and enabled in the current user's settings.

* * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS * @see android.app.Activity#setVrModeEnabled * @see android.R.attr#enableVrMode */ public abstract class VrListenerService extends Service { /** * The {@link Intent} that must be declared as handled by the service. */ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION) public static final String SERVICE_INTERFACE = "android.service.vr.VrListenerService"; private final Handler mHandler; private static final int MSG_ON_CURRENT_VR_ACTIVITY_CHANGED = 1; private final IVrListener.Stub mBinder = new IVrListener.Stub() { @Override public void focusedActivityChanged(ComponentName component) { mHandler.obtainMessage(MSG_ON_CURRENT_VR_ACTIVITY_CHANGED, component).sendToTarget(); } }; private final class VrListenerHandler extends Handler { public VrListenerHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_ON_CURRENT_VR_ACTIVITY_CHANGED: { VrListenerService.this.onCurrentVrActivityChanged((ComponentName) msg.obj); } break; } } } @Override public IBinder onBind(Intent intent) { return mBinder; } public VrListenerService() { mHandler = new VrListenerHandler(Looper.getMainLooper()); } /** * Called when the current activity using VR mode has changed. * *

This will be called when this service is initially bound, but is not * guaranteed to be called before onUnbind. In general, this is intended to be used to * determine when user focus has transitioned between two VR activities. If both activities * have declared {@link android.R.attr#enableVrMode} with this service (and this * service is present and enabled), this service will not be unbound during the activity * transition.

* * @param component the {@link ComponentName} of the VR activity that the system has * switched to, or null if the system is displaying a 2D activity in VR compatibility mode. * * @see android.app.Activity#setVrModeEnabled * @see android.R.attr#enableVrMode */ public void onCurrentVrActivityChanged(ComponentName component) { // Override to implement } /** * Checks if the given component is enabled in user settings. * *

If this component is not enabled in the user's settings, it will not be started when * the system enters VR mode. The user interface for enabling VrListenerService components * can be started by sending the {@link android.provider.Settings#ACTION_VR_LISTENER_SETTINGS} * intent.

* * @param context the {@link Context} to use for looking up the requested component. * @param requestedComponent the name of the component that implements * {@link android.service.vr.VrListenerService} to check. * * @return {@code true} if this component is enabled in settings. * * @see android.provider.Settings#ACTION_VR_LISTENER_SETTINGS */ public static final boolean isVrModePackageEnabled(@NonNull Context context, @NonNull ComponentName requestedComponent) { ActivityManager am = context.getSystemService(ActivityManager.class); if (am == null) { return false; } return am.isVrModePackageEnabled(requestedComponent); } }