| /* |
| * 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 android.annotation.IntDef; |
| import android.view.View; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * {@link Complication} is an interface for defining a complication, a visual component rendered |
| * above a dream. {@link Complication} instances encapsulate the logic for generating the view to be |
| * shown, along with the supporting control/logic. The decision for including the |
| * {@link Complication} is not the responsibility of the {@link Complication}. This is instead |
| * handled by domain logic and invocations to add and remove the {@link Complication} through |
| * {@link com.android.systemui.dreams.DreamOverlayStateController#addComplication(Complication)} and |
| * {@link com.android.systemui.dreams.DreamOverlayStateController#removeComplication(Complication)}. |
| * A {@link Complication} also does not represent a specific instance of the view. Instead, it |
| * should be viewed as a provider, where view instances are requested from it. The associated |
| * {@link ViewHolder} interface is requested for each view request. This object is retained for the |
| * view's lifetime, providing a container for any associated logic. The complication rendering |
| * system will consult this {@link ViewHolder} for {@link View} to show and |
| * {@link ComplicationLayoutParams} to position the view. {@link ComplicationLayoutParams} allow for |
| * specifying the sizing and position of the {@link Complication}. |
| * |
| * The following code sample exhibits the entities and lifecycle involved with a |
| * {@link Complication}. |
| * |
| * <pre>{@code |
| * // This component allows for the complication to generate a new ViewHolder for every request. |
| * @Subcomponent |
| * interface ExampleViewHolderComponent { |
| * @Subcomponent.Factory |
| * interface Factory { |
| * ExampleViewHolderComponent create(); |
| * } |
| * |
| * ExampleViewHolder getViewHolder(); |
| * } |
| * |
| * // An example entity that controls whether or not a complication should be included on dreams. |
| * // Note how the complication is tracked by reference for removal. |
| * public class ExampleComplicationProvider { |
| * private final DreamOverlayStateController mDreamOverlayStateController; |
| * private final ExampleComplication mComplication; |
| * @Inject |
| * public ExampleComplicationProvider( |
| * ExampleComplication complication, |
| * DreamOverlayStateController stateController) { |
| * mDreamOverlayStateController = stateController; |
| * mComplication = complication; |
| * } |
| * |
| * public void onShowConditionsMet(boolean met) { |
| * if (met) { |
| * mDreamOverlayStateController.addComplication(mComplication); |
| * } else { |
| * mDreamOverlayStateController.removeComplication(mComplication); |
| * } |
| * } |
| * } |
| * |
| * // An example complication. Note how a factory is created to supply a unique ViewHolder for each |
| * // request. Also, there is no particular view instance members defined in the complication. |
| * class ExampleComplication implements Complication { |
| * private final ExampleViewHolderComponent.Factory mFactory; |
| * @Inject |
| * public ExampleComplication(ExampleViewHolderComponent.Factory viewHolderComponentFactory) { |
| * mFactory = viewHolderComponentFactory; |
| * } |
| * |
| * @Override |
| * public ViewHolder createView(ComplicationViewModel model) { |
| * return mFactory.create().getViewHolder(); |
| * } |
| * } |
| * |
| * // Not every ViewHolder needs to include a view controller. It is included here as an example of |
| * // how such logic can be contained and associated with the ViewHolder lifecycle. |
| * class ExampleViewController extends ViewController<FrameLayout> { |
| * protected ExampleViewController(FrameLayout view) { |
| * super(view); |
| * } |
| * |
| * @Override |
| * protected void onViewAttached() { } |
| * |
| * @Override |
| * protected void onViewDetached() { } |
| * } |
| * |
| * // An example ViewHolder. This is the correct place to contain any value/logic associated with a |
| * // particular instance of the ComplicationView. |
| * class ExampleViewHolder implements Complication.ViewHolder { |
| * final FrameLayout mView; |
| * final ExampleViewController mController; |
| * |
| * @Inject |
| * public ExampleViewHolder(Context context) { |
| * mView = new FrameLayout(context); |
| * mController = new ExampleViewController(mView); |
| * } |
| * @Override |
| * public View getView() { |
| * return mView; |
| * } |
| * |
| * @Override |
| * public ComplicationLayoutParams getLayoutParams() { |
| * return new ComplicationLayoutParams( |
| * 200, |
| * 100, |
| * ComplicationLayoutParams.POSITION_TOP | ComplicationLayoutParams.DIRECTION_END, |
| * ComplicationLayoutParams.DIRECTION_DOWN, |
| * 4); |
| * } |
| * } |
| * } |
| * </pre> |
| */ |
| public interface Complication { |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = { "CATEGORY_" }, value = { |
| CATEGORY_STANDARD, |
| CATEGORY_SYSTEM, |
| }) |
| |
| @interface Category {} |
| /** |
| * {@code CATEGORY_STANDARD} indicates the complication is a normal component. Rules and |
| * settings, such as hiding all complications, will apply to this complication. |
| */ |
| int CATEGORY_STANDARD = 1 << 0; |
| /** |
| * {@code CATEGORY_SYSTEM} indicates complications driven by SystemUI. Usually, these are |
| * core components that are not user controlled. These can potentially deviate from given |
| * rule sets that would normally apply to {@code CATEGORY_STANDARD}. |
| */ |
| int CATEGORY_SYSTEM = 1 << 1; |
| |
| /** |
| * The type of dream complications which can be provided by a {@link Complication}. |
| */ |
| @IntDef(prefix = {"COMPLICATION_TYPE_"}, flag = true, value = { |
| COMPLICATION_TYPE_NONE, |
| COMPLICATION_TYPE_TIME, |
| COMPLICATION_TYPE_DATE, |
| COMPLICATION_TYPE_WEATHER, |
| COMPLICATION_TYPE_AIR_QUALITY, |
| COMPLICATION_TYPE_CAST_INFO, |
| COMPLICATION_TYPE_HOME_CONTROLS, |
| COMPLICATION_TYPE_SMARTSPACE |
| }) |
| @Retention(RetentionPolicy.SOURCE) |
| @interface ComplicationType {} |
| |
| int COMPLICATION_TYPE_NONE = 0; |
| int COMPLICATION_TYPE_TIME = 1; |
| int COMPLICATION_TYPE_DATE = 1 << 1; |
| int COMPLICATION_TYPE_WEATHER = 1 << 2; |
| int COMPLICATION_TYPE_AIR_QUALITY = 1 << 3; |
| int COMPLICATION_TYPE_CAST_INFO = 1 << 4; |
| int COMPLICATION_TYPE_HOME_CONTROLS = 1 << 5; |
| int COMPLICATION_TYPE_SMARTSPACE = 1 << 6; |
| |
| /** |
| * The {@link Host} interface specifies a way a {@link Complication} to communicate with its |
| * parent entity for information and actions. |
| */ |
| interface Host { |
| /** |
| * Called to signal a {@link Complication} has requested to exit the dream. |
| */ |
| void requestExitDream(); |
| } |
| |
| /** |
| * The implementation of this interface is in charge of managing the visible state of |
| * the shown complication. |
| */ |
| interface VisibilityController { |
| /** |
| * Called to set the visibility of all shown and future complications. |
| * @param visibility The desired future visibility. |
| * @param animate whether the change should be animated. |
| */ |
| void setVisibility(@View.Visibility int visibility, boolean animate); |
| } |
| |
| /** |
| * Returned through {@link Complication#createView(ComplicationViewModel)}, {@link ViewHolder} |
| * is a container for a single {@link Complication} instance. The {@link Host} guarantees that |
| * the {@link ViewHolder} will be retained for the lifetime of the {@link Complication} |
| * instance's user. The view is responsible for providing the view that represents the |
| * {@link Complication}. This object is the proper place to store any related entities, such as |
| * a {@link com.android.systemui.util.ViewController} for the view. |
| */ |
| interface ViewHolder { |
| /** |
| * Returns the {@link View} associated with the {@link ViewHolder}. This {@link View} should |
| * be stable and generated once. |
| * @return |
| */ |
| View getView(); |
| |
| /** |
| * Returns the {@link Category} associated with the {@link Complication}. {@link Category} |
| * is a grouping which helps define the relationship of the {@link Complication} to |
| * System UI and the rest of the system. It is used for presentation and other decisions. |
| */ |
| @Complication.Category |
| default int getCategory() { |
| return Complication.CATEGORY_STANDARD; |
| } |
| |
| /** |
| * Returns the {@link ComplicationLayoutParams} associated with this complication. The |
| * values expressed here are treated as preference rather than requirement. The hosting |
| * entity is free to modify/interpret the parameters as deemed fit. |
| */ |
| ComplicationLayoutParams getLayoutParams(); |
| } |
| |
| /** |
| * Generates a {@link ViewHolder} for the {@link Complication}. This captures both the view and |
| * control logic for a single instance of the complication. The {@link Complication} may be |
| * asked at any time to generate another view. |
| * @param model The {@link ComplicationViewModel} associated with this particular |
| * {@link Complication} instance. |
| * @return a {@link ViewHolder} for this {@link Complication} instance. |
| */ |
| ViewHolder createView(ComplicationViewModel model); |
| |
| /** |
| * Returns the types that must be present in order for this complication to participate on |
| * the dream overlay. By default, this method returns |
| * {@code Complication.COMPLICATION_TYPE_NONE} to indicate no types are required. |
| * @return |
| */ |
| @Complication.ComplicationType |
| default int getRequiredTypeAvailability() { |
| return Complication.COMPLICATION_TYPE_NONE; |
| } |
| } |