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

Commit 52ea6622 authored by Ruben Brunk's avatar Ruben Brunk
Browse files

Bind VR compositor service from VrManagerService.

- Allow VR system application to have VR manager service bind a
compositor process so that oom scoring for the compositor process can be
adjusted.

Bug: 38390640

Test: Check that the VrCore compositor process is -700 on AIO devices with:

  adb shell procrank -o

Change-Id: I7b5bce5eb87bd5ed0fdeadf4ec7bdd2b361ab875
parent 683064f6
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;