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

Commit ea8cd100 authored by Xiaowen Lei's avatar Xiaowen Lei
Browse files

Add media entry Dream complication.

This implements using the entry chip to show/hide UMO, not yet the
timeout behavior. Also, the chip visual isn't updated when it's clicked.

The layout weight for the UMO complication is updated to ensure it's
placed below the Smartspace, not above it.

Also fixed a javadoc broken link in ComplicationUtils.java.

Bug: 242613318
Test: manual
Test: atest MediaDreamSentinelTest
Change-Id: Ic1eb7585007493be509ccce50c68e2d5a91583fe
parent 8e4783d3
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2022 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.
-->
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/media_entry_chip"
    android:layout_height="@dimen/keyguard_affordance_fixed_height"
    android:layout_width="@dimen/keyguard_affordance_fixed_width"
    android:layout_gravity="bottom|start"
    android:scaleType="center"
    android:tint="?android:attr/textColorPrimary"
    android:src="@drawable/ic_music_note"
    android:background="@drawable/keyguard_bottom_affordance_bg"
    android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
    android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
    android:contentDescription="@string/controls_media_title" />
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import java.util.Set;
public class ComplicationUtils {
    /**
     * Converts a {@link com.android.settingslib.dream.DreamBackend.ComplicationType} to
     * {@link ComplicationType}.
     * {@link Complication.ComplicationType}.
     */
    @Complication.ComplicationType
    public static int convertComplicationType(@DreamBackend.ComplicationType int type) {
+1 −1
Original line number Diff line number Diff line
@@ -151,8 +151,8 @@ public class DreamHomeControlsComplication implements Complication {
     * Controls behavior of the dream complication.
     */
    static class DreamHomeControlsChipViewController extends ViewController<ImageView> {
        private static final boolean DEBUG = false;
        private static final String TAG = "DreamHomeControlsCtrl";
        private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

        private final ActivityStarter mActivityStarter;
        private final Context mContext;
+135 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.complication;

import static com.android.systemui.dreams.complication.dagger.DreamMediaEntryComplicationComponent.DreamMediaEntryModule.DREAM_MEDIA_ENTRY_VIEW;
import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_MEDIA_ENTRY_LAYOUT_PARAMS;

import android.util.Log;
import android.view.View;

import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamMediaEntryComplicationComponent;
import com.android.systemui.media.dream.MediaDreamComplication;
import com.android.systemui.util.ViewController;

import javax.inject.Inject;
import javax.inject.Named;

/**
 * A dream complication that shows a media entry chip to launch media control view.
 */
public class DreamMediaEntryComplication implements Complication {
    private final DreamMediaEntryComplicationComponent.Factory mComponentFactory;

    @Inject
    public DreamMediaEntryComplication(
            DreamMediaEntryComplicationComponent.Factory componentFactory) {
        mComponentFactory = componentFactory;
    }

    @Override
    public ViewHolder createView(ComplicationViewModel model) {
        return mComponentFactory.create().getViewHolder();
    }

    /**
     * Contains values/logic associated with the dream complication view.
     */
    public static class DreamMediaEntryViewHolder implements ViewHolder {
        private final View mView;
        private final ComplicationLayoutParams mLayoutParams;
        private final DreamMediaEntryViewController mViewController;

        @Inject
        DreamMediaEntryViewHolder(
                DreamMediaEntryViewController dreamMediaEntryViewController,
                @Named(DREAM_MEDIA_ENTRY_VIEW) View view,
                @Named(DREAM_MEDIA_ENTRY_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams
        ) {
            mView = view;
            mLayoutParams = layoutParams;
            mViewController = dreamMediaEntryViewController;
            mViewController.init();
        }

        @Override
        public View getView() {
            return mView;
        }

        @Override
        public ComplicationLayoutParams getLayoutParams() {
            return mLayoutParams;
        }
    }

    /**
     * Controls behavior of the dream complication.
     */
    static class DreamMediaEntryViewController extends ViewController<View> {
        private static final String TAG = "DreamMediaEntryVwCtrl";
        private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

        private final DreamOverlayStateController mDreamOverlayStateController;
        private final MediaDreamComplication mMediaComplication;

        private boolean mMediaComplicationAdded;

        @Inject
        DreamMediaEntryViewController(
                @Named(DREAM_MEDIA_ENTRY_VIEW) View view,
                DreamOverlayStateController dreamOverlayStateController,
                MediaDreamComplication mediaComplication) {
            super(view);
            mDreamOverlayStateController = dreamOverlayStateController;
            mMediaComplication = mediaComplication;
            mView.setOnClickListener(this::onClickMediaEntry);
        }

        @Override
        protected void onViewAttached() {
        }

        @Override
        protected void onViewDetached() {
            removeMediaComplication();
        }

        private void onClickMediaEntry(View v) {
            if (DEBUG) Log.d(TAG, "media entry complication tapped");

            if (!mMediaComplicationAdded) {
                addMediaComplication();
            } else {
                removeMediaComplication();
            }
        }

        private void addMediaComplication() {
            mView.setSelected(true);
            mDreamOverlayStateController.addComplication(mMediaComplication);
            mMediaComplicationAdded = true;
        }

        private void removeMediaComplication() {
            mView.setSelected(false);
            mDreamOverlayStateController.removeComplication(mMediaComplication);
            mMediaComplicationAdded = false;
        }
    }
}
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.complication.dagger;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import android.view.LayoutInflater;
import android.view.View;

import com.android.systemui.R;
import com.android.systemui.dreams.complication.DreamMediaEntryComplication;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;

import javax.inject.Named;
import javax.inject.Scope;

import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;

/**
 * Responsible for generating dependencies for the {@link DreamMediaEntryComplication}.
 */
@Subcomponent(modules = DreamMediaEntryComplicationComponent.DreamMediaEntryModule.class)
@DreamMediaEntryComplicationComponent.DreamMediaEntryComplicationScope
public interface DreamMediaEntryComplicationComponent {
    /**
     * Creates a view holder for the media entry complication.
     */
    DreamMediaEntryComplication.DreamMediaEntryViewHolder getViewHolder();

    /**
     * Scope of the media entry complication.
     */
    @Documented
    @Retention(RUNTIME)
    @Scope
    @interface DreamMediaEntryComplicationScope {}

    /**
     * Factory that generates a {@link DreamMediaEntryComplicationComponent}.
     */
    @Subcomponent.Factory
    interface Factory {
        DreamMediaEntryComplicationComponent create();
    }

    /**
     * Scoped injected values for the {@link DreamMediaEntryComplicationComponent}.
     */
    @Module
    interface DreamMediaEntryModule {
        String DREAM_MEDIA_ENTRY_VIEW = "dream_media_entry_view";

        /**
         * Provides the dream media entry view.
         */
        @Provides
        @DreamMediaEntryComplicationScope
        @Named(DREAM_MEDIA_ENTRY_VIEW)
        static View provideMediaEntryView(LayoutInflater layoutInflater) {
            return (View) layoutInflater.inflate(R.layout.dream_overlay_media_entry_chip, null);
        }
    }
}
Loading