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

Commit 92fdf1d2 authored by Bryce Lee's avatar Bryce Lee
Browse files

SystemUI IDreamOverlay Implementation.

This changelist implements IDreamOverlay in the form of
the DreamOverlayService. DreamOverlayRegistrant is
responsible for registering this service with the system
as the dream overlay component. This changelist also
introduces a series of interfaces, such as OverlayProvider,
which define the entities DreamOverlayService interacts
with the generate overlay content.

Bug: 201676597
Test: atest DreamOverlayServiceTest
Change-Id: Idb14172672642580fdfa042449b6cad4bf68969b
parent 4219dcc2
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -673,6 +673,11 @@
            android:name=".keyguard.KeyguardService"
            android:exported="true" />

        <service
            android:name=".dreams.DreamOverlayService"
            android:enabled="@bool/config_dreamOverlayServiceEnabled"
            android:exported="true" />

        <activity android:name=".keyguard.WorkLockActivity"
                  android:label="@string/accessibility_desc_work_lock"
                  android:permission="android.permission.MANAGE_USERS"
+3 −0
Original line number Diff line number Diff line
@@ -715,4 +715,7 @@
    <!-- Flag to enable privacy dot views, it shall be true for normal case -->
    <bool name="config_enablePrivacyDot">true</bool>

    <!-- Flag to enable dream overlay service and its registration -->
    <bool name="config_dreamOverlayServiceEnabled">false</bool>

</resources>
+7 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.app.Service;
import com.android.systemui.ImageWallpaper;
import com.android.systemui.SystemUIService;
import com.android.systemui.doze.DozeService;
import com.android.systemui.dreams.DreamOverlayService;
import com.android.systemui.dump.SystemUIAuxiliaryDumpService;
import com.android.systemui.keyguard.KeyguardService;
import com.android.systemui.screenrecord.RecordingService;
@@ -53,6 +54,12 @@ public abstract class DefaultServiceBinder {
    @ClassKey(KeyguardService.class)
    public abstract Service bindKeyguardService(KeyguardService service);

    /** */
    @Binds
    @IntoMap
    @ClassKey(DreamOverlayService.class)
    public abstract Service bindDreamOverlayService(DreamOverlayService service);

    /** */
    @Binds
    @IntoMap
+8 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.SystemUI;
import com.android.systemui.accessibility.SystemActions;
import com.android.systemui.accessibility.WindowMagnification;
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.dreams.DreamOverlayRegistrant;
import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
@@ -188,4 +189,11 @@ public abstract class SystemUIBinder {
    @IntoMap
    @ClassKey(HomeSoundEffectController.class)
    public abstract SystemUI bindHomeSoundEffectController(HomeSoundEffectController sysui);

    /** Inject into DreamOverlay. */
    @Binds
    @IntoMap
    @ClassKey(DreamOverlayRegistrant.class)
    public abstract SystemUI bindDreamOverlayRegistrant(
            DreamOverlayRegistrant dreamOverlayRegistrant);
}
+128 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 com.android.systemui.dreams;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.util.Log;

import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.dagger.qualifiers.Main;

import javax.inject.Inject;

/**
 * {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
 * the designated dream overlay component.
 */
public class DreamOverlayRegistrant extends SystemUI {
    private static final String TAG = "DreamOverlayRegistrant";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private final IDreamManager mDreamManager;
    private final ComponentName mOverlayServiceComponent;
    private final Resources mResources;
    private boolean mCurrentRegisteredState = false;

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DEBUG) {
                Log.d(TAG, "package changed receiver - onReceive");
            }

            registerOverlayService();
        }
    };

    private void registerOverlayService() {
        // Check to see if the service has been disabled by the user. In this case, we should not
        // proceed modifying the enabled setting.
        final PackageManager packageManager = mContext.getPackageManager();
        final int enabledState =
                packageManager.getComponentEnabledSetting(mOverlayServiceComponent);


        // TODO(b/204626521): We should not have to set the component enabled setting if the
        // enabled config flag is properly applied based on the RRO.
        if (enabledState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
            final int overlayState = mResources.getBoolean(R.bool.config_dreamOverlayServiceEnabled)
                    ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;

            if (overlayState != enabledState) {
                packageManager
                        .setComponentEnabledSetting(mOverlayServiceComponent, overlayState, 0);
            }
        }

        // The overlay service is only registered when its component setting is enabled.
        boolean register = packageManager.getComponentEnabledSetting(mOverlayServiceComponent)
                == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;

        if (mCurrentRegisteredState == register) {
            return;
        }

        mCurrentRegisteredState = register;

        try {
            if (DEBUG) {
                Log.d(TAG, mCurrentRegisteredState
                        ? "registering dream overlay service:" + mOverlayServiceComponent
                        : "clearing dream overlay service");
            }

            mDreamManager.registerDreamOverlayService(
                    mCurrentRegisteredState ? mOverlayServiceComponent : null);
        } catch (RemoteException e) {
            Log.e(TAG, "could not register dream overlay service:" + e);
        }
    }

    @Inject
    public DreamOverlayRegistrant(Context context, @Main Resources resources) {
        super(context);
        mResources = resources;
        mDreamManager = IDreamManager.Stub.asInterface(
                ServiceManager.getService(DreamService.DREAM_SERVICE));
        mOverlayServiceComponent = new ComponentName(mContext, DreamOverlayService.class);
    }

    @Override
    public void start() {
        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
        filter.addDataScheme("package");
        filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(),
                PatternMatcher.PATTERN_LITERAL);
        // Note that we directly register the receiver here as data schemes are not supported by
        // BroadcastDispatcher.
        mContext.registerReceiver(mReceiver, filter);

        registerOverlayService();
    }
}
Loading