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

Commit 47113cf2 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Add ThumbnailTemplate

Adds a template to support controls that display a thumbnail. There's an
active parameter that indicates whether it's a "live" feed.

Test: atest ControliTemplateTest ControlProviderServiceTest
Fixes: 170646657
Change-Id: Iaf5053920a34ab0b0b598be44a5482d832d48688
parent 05c11205
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -43836,6 +43836,7 @@ package android.service.controls.templates {
    field public static final int TYPE_RANGE = 2; // 0x2
    field public static final int TYPE_STATELESS = 8; // 0x8
    field public static final int TYPE_TEMPERATURE = 7; // 0x7
    field public static final int TYPE_THUMBNAIL = 3; // 0x3
    field public static final int TYPE_TOGGLE = 1; // 0x1
    field public static final int TYPE_TOGGLE_RANGE = 6; // 0x6
  }
@@ -43875,6 +43876,14 @@ package android.service.controls.templates {
    field public static final int MODE_UNKNOWN = 0; // 0x0
  }
  public final class ThumbnailTemplate extends android.service.controls.templates.ControlTemplate {
    ctor public ThumbnailTemplate(@NonNull String, boolean, @NonNull android.graphics.drawable.Icon, @NonNull CharSequence);
    method @NonNull public CharSequence getContentDescription();
    method public int getTemplateType();
    method @NonNull public android.graphics.drawable.Icon getThumbnail();
    method public boolean isActive();
  }
  public final class ToggleRangeTemplate extends android.service.controls.templates.ControlTemplate {
    ctor public ToggleRangeTemplate(@NonNull String, @NonNull android.service.controls.templates.ControlButton, @NonNull android.service.controls.templates.RangeTemplate);
    ctor public ToggleRangeTemplate(@NonNull String, boolean, @NonNull CharSequence, @NonNull android.service.controls.templates.RangeTemplate);
+12 −2
Original line number Diff line number Diff line
@@ -206,8 +206,8 @@ public abstract class ControlsProviderService extends Service {

                case MSG_SUBSCRIBE: {
                    final SubscribeMessage sMsg = (SubscribeMessage) msg.obj;
                    final SubscriberProxy proxy = new SubscriberProxy(false, mToken,
                            sMsg.mSubscriber);
                    final SubscriberProxy proxy = new SubscriberProxy(
                            ControlsProviderService.this, false, mToken, sMsg.mSubscriber);

                    ControlsProviderService.this.createPublisherFor(sMsg.mControlIds)
                            .subscribe(proxy);
@@ -251,6 +251,7 @@ public abstract class ControlsProviderService extends Service {
        private IBinder mToken;
        private IControlsSubscriber mCs;
        private boolean mEnforceStateless;
        private Context mContext;

        SubscriberProxy(boolean enforceStateless, IBinder token, IControlsSubscriber cs) {
            mEnforceStateless = enforceStateless;
@@ -258,6 +259,12 @@ public abstract class ControlsProviderService extends Service {
            mCs = cs;
        }

        SubscriberProxy(Context context, boolean enforceStateless, IBinder token,
                IControlsSubscriber cs) {
            this(enforceStateless, token, cs);
            mContext = context;
        }

        public void onSubscribe(Subscription subscription) {
            try {
                mCs.onSubscribe(mToken, new SubscriptionAdapter(subscription));
@@ -273,6 +280,9 @@ public abstract class ControlsProviderService extends Service {
                            + "Control.StatelessBuilder() to build the control.");
                    control = new Control.StatelessBuilder(control).build();
                }
                if (mContext != null) {
                    control.getControlTemplate().prepareTemplateForBinder(mContext);
                }
                mCs.onNext(mToken, control);
            } catch (RemoteException ex) {
                ex.rethrowAsRuntimeException();
+16 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Bundle;
import android.service.controls.Control;
import android.service.controls.actions.ControlAction;
@@ -78,6 +79,7 @@ public abstract class ControlTemplate {
            TYPE_NO_TEMPLATE,
            TYPE_TOGGLE,
            TYPE_RANGE,
            TYPE_THUMBNAIL,
            TYPE_TOGGLE_RANGE,
            TYPE_TEMPERATURE,
            TYPE_STATELESS
@@ -104,6 +106,11 @@ public abstract class ControlTemplate {
     */
    public static final @TemplateType int TYPE_RANGE = 2;

    /**
     * Type identifier of {@link ThumbnailTemplate}.
     */
    public static final @TemplateType int TYPE_THUMBNAIL = 3;

    /**
     * Type identifier of {@link ToggleRangeTemplate}.
     */
@@ -168,6 +175,13 @@ public abstract class ControlTemplate {
        mTemplateId = templateId;
    }

    /**
     * Call to prepare values for Binder transport.
     *
     * @hide
     */
    public void prepareTemplateForBinder(@NonNull Context context) {}

    /**
     *
     * @param bundle
@@ -187,6 +201,8 @@ public abstract class ControlTemplate {
                    return new ToggleTemplate(bundle);
                case TYPE_RANGE:
                    return new RangeTemplate(bundle);
                case TYPE_THUMBNAIL:
                    return new ThumbnailTemplate(bundle);
                case TYPE_TOGGLE_RANGE:
                    return new ToggleRangeTemplate(bundle);
                case TYPE_TEMPERATURE:
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.controls.templates;

import android.annotation.NonNull;
import android.content.Context;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.service.controls.Control;

import com.android.internal.R;
import com.android.internal.util.Preconditions;

/**
 * A template for a {@link Control} that displays an image.
 */
public final class ThumbnailTemplate extends ControlTemplate {

    private static final @TemplateType int TYPE = TYPE_THUMBNAIL;
    private static final String KEY_ICON = "key_icon";
    private static final String KEY_ACTIVE = "key_active";
    private static final String KEY_CONTENT_DESCRIPTION = "key_content_description";

    private final boolean mActive;
    private final @NonNull Icon mThumbnail;
    private final @NonNull CharSequence mContentDescription;

    /**
     * @param templateId the identifier for this template object
     * @param active whether the image corresponds to an active (live) stream.
     * @param thumbnail an image to display on the {@link Control}
     * @param contentDescription a description of the image for accessibility.
     */
    public ThumbnailTemplate(
            @NonNull String templateId,
            boolean active,
            @NonNull Icon thumbnail,
            @NonNull CharSequence contentDescription) {
        super(templateId);
        Preconditions.checkNotNull(thumbnail);
        Preconditions.checkNotNull(contentDescription);
        mActive = active;
        mThumbnail = thumbnail;
        mContentDescription = contentDescription;
    }

    /**
     * @param b
     * @hide
     */
    ThumbnailTemplate(Bundle b) {
        super(b);
        mActive = b.getBoolean(KEY_ACTIVE);
        mThumbnail = b.getParcelable(KEY_ICON);
        mContentDescription = b.getCharSequence(KEY_CONTENT_DESCRIPTION, "");
    }

    /*
     * @return {@code true} if the thumbnail corresponds to an active (live) stream.
     */
    public boolean isActive() {
        return mActive;
    }

    /**
     * The {@link Icon} (image) displayed by this template.
     */
    @NonNull
    public Icon getThumbnail() {
        return mThumbnail;
    }

    /**
     * The description of the image returned by {@link ThumbnailTemplate#getThumbnail()}
     */
    @NonNull
    public CharSequence getContentDescription() {
        return mContentDescription;
    }

    /**
     * @return {@link ControlTemplate#TYPE_THUMBNAIL}
     */
    @Override
    public int getTemplateType() {
        return TYPE;
    }

    /**
     * Rescales the image down if necessary (in the case of a Bitmap).
     *
     * @hide
     */
    @Override
    public void prepareTemplateForBinder(@NonNull Context context) {
        int width = context.getResources()
                .getDimensionPixelSize(R.dimen.controls_thumbnail_image_max_width);
        int height = context.getResources()
                .getDimensionPixelSize(R.dimen.controls_thumbnail_image_max_height);
        rescaleThumbnail(width, height);
    }

    private void rescaleThumbnail(int width, int height) {
        mThumbnail.scaleDownIfNecessary(width, height);
    }

    /**
     * @return
     * @hide
     */
    @Override
    @NonNull
    Bundle getDataBundle() {
        Bundle b = super.getDataBundle();
        b.putBoolean(KEY_ACTIVE, mActive);
        b.putObject(KEY_ICON, mThumbnail);
        b.putObject(KEY_CONTENT_DESCRIPTION, mContentDescription);
        return b;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -857,4 +857,9 @@
    <dimen name="waterfall_display_top_edge_size">0px</dimen>
    <dimen name="waterfall_display_right_edge_size">0px</dimen>
    <dimen name="waterfall_display_bottom_edge_size">0px</dimen>

    <!-- The maximum height of a thumbnail in a ThumbnailTemplate. The image will be reduced to that height in case they are bigger. -->
    <dimen name="controls_thumbnail_image_max_height">140dp</dimen>
    <!-- The maximum width of a thumbnail in a ThumbnailTemplate. The image will be reduced to that width in case they are bigger.-->
    <dimen name="controls_thumbnail_image_max_width">280dp</dimen>
</resources>
Loading