Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c765c2c4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Bind VR compositor service from VrManagerService." into oc-mr1-dev

parents 3ea0acac 52ea6622
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -6308,6 +6308,7 @@ package android.app {
  }
  public class VrManager {
    method public void setAndBindVrCompositor(android.content.ComponentName);
    method public void setPersistentVrModeEnabled(boolean);
  }
+17 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Handler;
import android.os.RemoteException;
@@ -181,4 +182,20 @@ public class VrManager {
            e.rethrowFromSystemServer();
        }
    }

    /**
     * Set the component name of the compositor service to bind.
     *
     * @param componentName ComponentName of a Service in the application's compositor process to
     * bind to, or null to clear the current binding.
     */
    @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
    public void setAndBindVrCompositor(ComponentName componentName) {
        try {
            mService.setAndBindCompositor(
                    (componentName == null) ? null : componentName.flattenToString());
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -93,5 +93,13 @@ interface IVrManager {
     * currently, else return the display id of the virtual display
     */
    int getVr2dDisplayId();

    /**
     * Set the component name of the compositor service to bind.
     *
     * @param componentName flattened string representing a ComponentName of a Service in the
     * application's compositor process to bind to, or null to clear the current binding.
     */
    void setAndBindCompositor(in String componentName);
}
+30 −21
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.utils;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -97,21 +98,23 @@ public class ManagedApplicationService {
     * @param component the {@link ComponentName} of the application service to bind.
     * @param userId the user ID of user to bind the application service as.
     * @param clientLabel the resource ID of a label displayed to the user indicating the
     *      binding service.
     *      binding service, or 0 if none is desired.
     * @param settingsAction an action that can be used to open the Settings UI to enable/disable
     *      binding to these services.
     * @param binderChecker an interface used to validate the returned binder object.
     *      binding to these services, or null if none is desired.
     * @param binderChecker an interface used to validate the returned binder object, or null if
     *      this interface is unchecked.
     * @param isImportant bind the user service with BIND_IMPORTANT.
     * @return a ManagedApplicationService instance.
     */
    public static ManagedApplicationService build(@NonNull final Context context,
        @NonNull final ComponentName component, final int userId, @NonNull int clientLabel,
        @NonNull String settingsAction, @NonNull BinderChecker binderChecker,
            @NonNull final ComponentName component, final int userId, int clientLabel,
            @Nullable String settingsAction, @Nullable BinderChecker binderChecker,
            boolean isImportant) {
        return new ManagedApplicationService(context, component, userId, clientLabel,
            settingsAction, binderChecker, isImportant);
    }


    /**
     * @return the user ID of the user that owns the bound service.
     */
@@ -194,11 +197,14 @@ public class ManagedApplicationService {
                return;
            }

            final PendingIntent pendingIntent = PendingIntent.getActivity(
                    mContext, 0, new Intent(mSettingsAction), 0);
            final Intent intent = new Intent().setComponent(mComponent).
                    putExtra(Intent.EXTRA_CLIENT_LABEL, mClientLabel).
                    putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
            Intent intent  = new Intent().setComponent(mComponent);
            if (mClientLabel != 0) {
                intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mClientLabel);
            }
            if (mSettingsAction != null) {
                intent.putExtra(Intent.EXTRA_CLIENT_INTENT,
                        PendingIntent.getActivity(mContext, 0, new Intent(mSettingsAction), 0));
            }

            final ServiceConnection serviceConnection = new ServiceConnection() {
                @Override
@@ -218,6 +224,8 @@ public class ManagedApplicationService {

                        try {
                            iBinder.linkToDeath(mDeathRecipient, 0);
                            mBoundInterface = null;
                            if (mChecker != null) {
                                mBoundInterface = mChecker.asInterface(iBinder);
                                if (!mChecker.checkType(mBoundInterface)) {
                                    // Received an invalid binder, disconnect
@@ -227,9 +235,10 @@ public class ManagedApplicationService {
                                iface = mBoundInterface;
                                pendingEvent = mPendingEvent;
                                mPendingEvent = null;
                            }
                        } catch (RemoteException e) {
                            // DOA
                            Slog.w(TAG, "Unable to bind service: " + intent, e);
                            Slog.w(TAG, "Unable to bind service: " + componentName, e);
                            mBoundInterface = null;
                        }
                    }
@@ -244,7 +253,7 @@ public class ManagedApplicationService {

                @Override
                public void onServiceDisconnected(ComponentName componentName) {
                    Slog.w(TAG, "Service disconnected: " + intent);
                    Slog.w(TAG, "Service disconnected: " + componentName);
                    mConnection = null;
                    mBoundInterface = null;
                }
+40 −0
Original line number Diff line number Diff line
@@ -134,6 +134,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
    private int mVrAppProcessId;
    private EnabledComponentsObserver mComponentObserver;
    private ManagedApplicationService mCurrentVrService;
    private ManagedApplicationService mCurrentVrCompositorService;
    private ComponentName mDefaultVrService;
    private Context mContext;
    private ComponentName mCurrentVrModeComponent;
@@ -489,6 +490,13 @@ public class VrManagerService extends SystemService implements EnabledComponentC
            return VrManagerService.this.getVr2dDisplayId();
        }

        @Override
        public void setAndBindCompositor(String componentName) {
            enforceCallerPermissionAnyOf(Manifest.permission.RESTRICTED_VR_ACCESS);
            VrManagerService.this.setAndBindCompositor(
                (componentName == null) ? null : ComponentName.unflattenFromString(componentName));
        }

        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
@@ -497,6 +505,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC
            pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
            pw.println("Persistent VR mode is currently: " +
                    ((mPersistentVrModeEnabled) ? "enabled" : "disabled"));
            pw.println("Currently bound VR compositor service: "
                    + ((mCurrentVrCompositorService == null)
                    ? "None" : mCurrentVrCompositorService.getComponent()));
            pw.println("Previous state transitions:\n");
            String tab = "  ";
            dumpStateTransitions(pw);
@@ -785,6 +796,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                        + mCurrentVrService.getComponent() + " for user "
                        + mCurrentVrService.getUserId());
                    mCurrentVrService.disconnect();
                    updateCompositorServiceLocked(UserHandle.USER_NULL, null);
                    mCurrentVrService = null;
                } else {
                    nothingChanged = true;
@@ -798,6 +810,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC
                        Slog.i(TAG, "VR mode component changed to " + component
                            + ", disconnecting " + mCurrentVrService.getComponent()
                            + " for user " + mCurrentVrService.getUserId());
                        updateCompositorServiceLocked(UserHandle.USER_NULL, null);
                        createAndConnectService(component, userId);
                        sendUpdatedCaller = true;
                    } else {
@@ -1177,6 +1190,33 @@ public class VrManagerService extends SystemService implements EnabledComponentC
        return INVALID_DISPLAY;
    }

    private void setAndBindCompositor(ComponentName componentName) {
        final int userId = UserHandle.getCallingUserId();
        final long token = Binder.clearCallingIdentity();
        synchronized (mLock) {
            updateCompositorServiceLocked(userId, componentName);
        }
        Binder.restoreCallingIdentity(token);
    }

    private void updateCompositorServiceLocked(int userId, ComponentName componentName) {
        if (mCurrentVrCompositorService != null
                && mCurrentVrCompositorService.disconnectIfNotMatching(componentName, userId)) {
            // Check if existing service matches the requested one, if not (or if the requested
            // component is null) disconnect it.
            mCurrentVrCompositorService = null;
        }

        if (componentName != null && mCurrentVrCompositorService == null) {
            // We don't have an existing service matching the requested component, so attempt to
            // connect one.
            mCurrentVrCompositorService = ManagedApplicationService.build(mContext,
                    componentName, userId, /*clientLabel*/0, /*settingsAction*/null,
                    /*binderChecker*/null, /*isImportant*/true);
            mCurrentVrCompositorService.connect();
        }
    }

    private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
        if (mPersistentVrModeEnabled == enabled) {
            return;