| /* |
| * Copyright (C) 2019 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; |
| |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.annotation.SuppressLint; |
| import android.app.PendingIntent; |
| import android.content.Intent; |
| import android.content.res.ColorStateList; |
| import android.graphics.drawable.Icon; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.service.controls.actions.ControlAction; |
| import android.service.controls.templates.ControlTemplate; |
| import android.service.controls.templates.ControlTemplateWrapper; |
| import android.util.Log; |
| |
| import com.android.internal.util.Preconditions; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * Represents a physical object that can be represented by a {@link ControlTemplate} and whose |
| * properties may be modified through a {@link ControlAction}. |
| * |
| * The information is provided by a {@link ControlsProviderService} and represents static |
| * information (not current status) about the device. |
| * <p> |
| * Each control needs a unique (per provider) identifier that is persistent across reboots of the |
| * system. |
| * <p> |
| * Each {@link Control} will have a name, a subtitle and will optionally belong to a structure |
| * and zone. Some of these values are defined by the user and/or the {@link ControlsProviderService} |
| * and will be used to display the control as well as group them for management. |
| * <p> |
| * Each object will have an associated {@link DeviceTypes.DeviceType}. This will determine the icons and colors |
| * used to display it. |
| * <p> |
| * An {@link Intent} linking to the provider Activity that expands on this {@link Control} and |
| * allows for further actions should be provided. |
| */ |
| public final class Control implements Parcelable { |
| private static final String TAG = "Control"; |
| |
| private static final int NUM_STATUS = 5; |
| /** |
| * @hide |
| */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef({ |
| STATUS_UNKNOWN, |
| STATUS_OK, |
| STATUS_NOT_FOUND, |
| STATUS_ERROR, |
| STATUS_DISABLED, |
| }) |
| public @interface Status {}; |
| |
| /** |
| * Reserved for use with the {@link StatelessBuilder}, and while loading. When state is |
| * requested via {@link ControlsProviderService#createPublisherFor}, use other status codes |
| * to indicate the proper device state. |
| */ |
| public static final int STATUS_UNKNOWN = 0; |
| |
| /** |
| * Used to indicate that the state of the device was successfully retrieved. This includes |
| * all scenarios where the device may have a warning for the user, such as "Lock jammed", |
| * or "Vacuum stuck". Any information for the user should be set through |
| * {@link StatefulBuilder#setStatusText}. |
| */ |
| public static final int STATUS_OK = 1; |
| |
| /** |
| * The device corresponding to the {@link Control} cannot be found or was removed. The user |
| * will be alerted and directed to the application to resolve. |
| */ |
| public static final int STATUS_NOT_FOUND = 2; |
| |
| /** |
| * Used to indicate that there was a temporary error while loading the device state. A default |
| * error message will be displayed in place of any custom text that was set through |
| * {@link StatefulBuilder#setStatusText}. |
| */ |
| public static final int STATUS_ERROR = 3; |
| |
| /** |
| * The {@link Control} is currently disabled. A default error message will be displayed in |
| * place of any custom text that was set through {@link StatefulBuilder#setStatusText}. |
| */ |
| public static final int STATUS_DISABLED = 4; |
| |
| private final @NonNull String mControlId; |
| private final @DeviceTypes.DeviceType int mDeviceType; |
| private final @NonNull CharSequence mTitle; |
| private final @NonNull CharSequence mSubtitle; |
| private final @Nullable CharSequence mStructure; |
| private final @Nullable CharSequence mZone; |
| private final @NonNull PendingIntent mAppIntent; |
| |
| private final @Nullable Icon mCustomIcon; |
| private final @Nullable ColorStateList mCustomColor; |
| |
| private final @Status int mStatus; |
| private final @NonNull ControlTemplate mControlTemplate; |
| private final @NonNull CharSequence mStatusText; |
| private final boolean mAuthRequired; |
| |
| /** |
| * @param controlId the unique persistent identifier for this object. |
| * @param deviceType the type of device for this control. This will determine icons and colors. |
| * @param title the user facing name of this control (e.g. "Bedroom thermostat"). |
| * @param subtitle a user facing subtitle with extra information about this control |
| * @param structure a user facing name for the structure containing the device associated with |
| * this control. |
| * @param zone |
| * @param appIntent a {@link PendingIntent} linking to a page to interact with the |
| * corresponding device. |
| * @param customIcon |
| * @param customColor |
| * @param status |
| * @param controlTemplate |
| * @param statusText |
| * @param authRequired true if the control can not be interacted with until the device is |
| * unlocked |
| */ |
| Control(@NonNull String controlId, |
| @DeviceTypes.DeviceType int deviceType, |
| @NonNull CharSequence title, |
| @NonNull CharSequence subtitle, |
| @Nullable CharSequence structure, |
| @Nullable CharSequence zone, |
| @NonNull PendingIntent appIntent, |
| @Nullable Icon customIcon, |
| @Nullable ColorStateList customColor, |
| @Status int status, |
| @NonNull ControlTemplate controlTemplate, |
| @NonNull CharSequence statusText, |
| boolean authRequired) { |
| Preconditions.checkNotNull(controlId); |
| Preconditions.checkNotNull(title); |
| Preconditions.checkNotNull(subtitle); |
| Preconditions.checkNotNull(appIntent); |
| Preconditions.checkNotNull(controlTemplate); |
| Preconditions.checkNotNull(statusText); |
| mControlId = controlId; |
| if (!DeviceTypes.validDeviceType(deviceType)) { |
| Log.e(TAG, "Invalid device type:" + deviceType); |
| mDeviceType = DeviceTypes.TYPE_UNKNOWN; |
| } else { |
| mDeviceType = deviceType; |
| } |
| mTitle = title; |
| mSubtitle = subtitle; |
| mStructure = structure; |
| mZone = zone; |
| mAppIntent = appIntent; |
| |
| mCustomColor = customColor; |
| mCustomIcon = customIcon; |
| |
| if (status < 0 || status >= NUM_STATUS) { |
| mStatus = STATUS_UNKNOWN; |
| Log.e(TAG, "Status unknown:" + status); |
| } else { |
| mStatus = status; |
| } |
| mControlTemplate = controlTemplate; |
| mStatusText = statusText; |
| mAuthRequired = authRequired; |
| } |
| |
| /** |
| * @param in |
| * @hide |
| */ |
| Control(Parcel in) { |
| mControlId = in.readString(); |
| mDeviceType = in.readInt(); |
| mTitle = in.readCharSequence(); |
| mSubtitle = in.readCharSequence(); |
| if (in.readByte() == (byte) 1) { |
| mStructure = in.readCharSequence(); |
| } else { |
| mStructure = null; |
| } |
| if (in.readByte() == (byte) 1) { |
| mZone = in.readCharSequence(); |
| } else { |
| mZone = null; |
| } |
| mAppIntent = PendingIntent.CREATOR.createFromParcel(in); |
| |
| if (in.readByte() == (byte) 1) { |
| mCustomIcon = Icon.CREATOR.createFromParcel(in); |
| } else { |
| mCustomIcon = null; |
| } |
| |
| if (in.readByte() == (byte) 1) { |
| mCustomColor = ColorStateList.CREATOR.createFromParcel(in); |
| } else { |
| mCustomColor = null; |
| } |
| |
| mStatus = in.readInt(); |
| ControlTemplateWrapper wrapper = ControlTemplateWrapper.CREATOR.createFromParcel(in); |
| mControlTemplate = wrapper.getWrappedTemplate(); |
| mStatusText = in.readCharSequence(); |
| mAuthRequired = in.readBoolean(); |
| } |
| |
| /** |
| * @return the identifier for the {@link Control} |
| */ |
| @NonNull |
| public String getControlId() { |
| return mControlId; |
| } |
| |
| |
| /** |
| * @return type of device represented by this {@link Control}, used to determine the default |
| * icon and color |
| */ |
| @DeviceTypes.DeviceType |
| public int getDeviceType() { |
| return mDeviceType; |
| } |
| |
| /** |
| * @return the user facing name of the {@link Control} |
| */ |
| @NonNull |
| public CharSequence getTitle() { |
| return mTitle; |
| } |
| |
| /** |
| * @return additional information about the {@link Control}, to appear underneath the title |
| */ |
| @NonNull |
| public CharSequence getSubtitle() { |
| return mSubtitle; |
| } |
| |
| /** |
| * Optional top-level group to help define the {@link Control}'s location, visible to the user. |
| * If not present, the application name will be used as the top-level group. A structure |
| * contains zones which contains controls. |
| * |
| * @return name of the structure containing the control |
| */ |
| @Nullable |
| public CharSequence getStructure() { |
| return mStructure; |
| } |
| |
| /** |
| * Optional group name to help define the {@link Control}'s location within a structure, |
| * visible to the user. A structure contains zones which contains controls. |
| * |
| * @return name of the zone containing the control |
| */ |
| @Nullable |
| public CharSequence getZone() { |
| return mZone; |
| } |
| |
| /** |
| * @return a {@link PendingIntent} linking to an Activity for the {@link Control} |
| */ |
| @NonNull |
| public PendingIntent getAppIntent() { |
| return mAppIntent; |
| } |
| |
| /** |
| * Optional icon to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the icon unless the default icon is not suitable. |
| * |
| * @return icon to show |
| */ |
| @Nullable |
| public Icon getCustomIcon() { |
| return mCustomIcon; |
| } |
| |
| /** |
| * Optional color to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the color unless the default is not suitable for the |
| * application. |
| * |
| * @return background color to use |
| */ |
| @Nullable |
| public ColorStateList getCustomColor() { |
| return mCustomColor; |
| } |
| |
| /** |
| * @return status of the {@link Control}, used to convey information about the attempt to |
| * fetch the current state |
| */ |
| @Status |
| public int getStatus() { |
| return mStatus; |
| } |
| |
| /** |
| * @return instance of {@link ControlTemplate}, that defines how the {@link Control} will |
| * behave and what interactions are available to the user |
| */ |
| @NonNull |
| public ControlTemplate getControlTemplate() { |
| return mControlTemplate; |
| } |
| |
| /** |
| * @return user-facing text description of the {@link Control}'s status, describing its current |
| * state |
| */ |
| @NonNull |
| public CharSequence getStatusText() { |
| return mStatusText; |
| } |
| |
| /** |
| * @return true if the control can not be interacted with until the device is unlocked |
| */ |
| public boolean isAuthRequired() { |
| return mAuthRequired; |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| dest.writeString(mControlId); |
| dest.writeInt(mDeviceType); |
| dest.writeCharSequence(mTitle); |
| dest.writeCharSequence(mSubtitle); |
| if (mStructure != null) { |
| dest.writeByte((byte) 1); |
| dest.writeCharSequence(mStructure); |
| } else { |
| dest.writeByte((byte) 0); |
| } |
| if (mZone != null) { |
| dest.writeByte((byte) 1); |
| dest.writeCharSequence(mZone); |
| } else { |
| dest.writeByte((byte) 0); |
| } |
| mAppIntent.writeToParcel(dest, flags); |
| if (mCustomIcon != null) { |
| dest.writeByte((byte) 1); |
| mCustomIcon.writeToParcel(dest, flags); |
| } else { |
| dest.writeByte((byte) 0); |
| } |
| if (mCustomColor != null) { |
| dest.writeByte((byte) 1); |
| mCustomColor.writeToParcel(dest, flags); |
| } else { |
| dest.writeByte((byte) 0); |
| } |
| |
| dest.writeInt(mStatus); |
| new ControlTemplateWrapper(mControlTemplate).writeToParcel(dest, flags); |
| dest.writeCharSequence(mStatusText); |
| dest.writeBoolean(mAuthRequired); |
| } |
| |
| public static final @NonNull Creator<Control> CREATOR = new Creator<Control>() { |
| @Override |
| public Control createFromParcel(@NonNull Parcel source) { |
| return new Control(source); |
| } |
| |
| @Override |
| public Control[] newArray(int size) { |
| return new Control[size]; |
| } |
| }; |
| |
| /** |
| * Builder class for {@link Control}. |
| * |
| * This class facilitates the creation of {@link Control} with no state. Must be used to |
| * provide controls for {@link ControlsProviderService#createPublisherForAllAvailable} and |
| * {@link ControlsProviderService#createPublisherForSuggested}. |
| * |
| * It provides the following defaults for non-optional parameters: |
| * <ul> |
| * <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN} |
| * <li> Title: {@code ""} |
| * <li> Subtitle: {@code ""} |
| * </ul> |
| * This fixes the values relating to state of the {@link Control} as required by |
| * {@link ControlsProviderService#createPublisherForAllAvailable}: |
| * <ul> |
| * <li> Status: {@link Status#STATUS_UNKNOWN} |
| * <li> Control template: {@link ControlTemplate#getNoTemplateObject} |
| * <li> Status text: {@code ""} |
| * <li> Auth Required: {@code true} |
| * </ul> |
| */ |
| @SuppressLint("MutableBareField") |
| public static final class StatelessBuilder { |
| private static final String TAG = "StatelessBuilder"; |
| private @NonNull String mControlId; |
| private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN; |
| private @NonNull CharSequence mTitle = ""; |
| private @NonNull CharSequence mSubtitle = ""; |
| private @Nullable CharSequence mStructure; |
| private @Nullable CharSequence mZone; |
| private @NonNull PendingIntent mAppIntent; |
| private @Nullable Icon mCustomIcon; |
| private @Nullable ColorStateList mCustomColor; |
| |
| /** |
| * @param controlId the identifier for the {@link Control} |
| * @param appIntent the pending intent linking to the device Activity |
| */ |
| public StatelessBuilder(@NonNull String controlId, |
| @NonNull PendingIntent appIntent) { |
| Preconditions.checkNotNull(controlId); |
| Preconditions.checkNotNull(appIntent); |
| mControlId = controlId; |
| mAppIntent = appIntent; |
| } |
| |
| /** |
| * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base. |
| * |
| * @param control base for the builder. |
| */ |
| public StatelessBuilder(@NonNull Control control) { |
| Preconditions.checkNotNull(control); |
| mControlId = control.mControlId; |
| mDeviceType = control.mDeviceType; |
| mTitle = control.mTitle; |
| mSubtitle = control.mSubtitle; |
| mStructure = control.mStructure; |
| mZone = control.mZone; |
| mAppIntent = control.mAppIntent; |
| mCustomIcon = control.mCustomIcon; |
| mCustomColor = control.mCustomColor; |
| } |
| |
| /** |
| * @param controlId the identifier for the {@link Control} |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setControlId(@NonNull String controlId) { |
| Preconditions.checkNotNull(controlId); |
| mControlId = controlId; |
| return this; |
| } |
| |
| /** |
| * @param deviceType type of device represented by this {@link Control}, used to |
| * determine the default icon and color |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) { |
| if (!DeviceTypes.validDeviceType(deviceType)) { |
| Log.e(TAG, "Invalid device type:" + deviceType); |
| mDeviceType = DeviceTypes.TYPE_UNKNOWN; |
| } else { |
| mDeviceType = deviceType; |
| } |
| return this; |
| } |
| |
| /** |
| * @param title the user facing name of the {@link Control} |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setTitle(@NonNull CharSequence title) { |
| Preconditions.checkNotNull(title); |
| mTitle = title; |
| return this; |
| } |
| |
| /** |
| * @param subtitle additional information about the {@link Control}, to appear underneath |
| * the title |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setSubtitle(@NonNull CharSequence subtitle) { |
| Preconditions.checkNotNull(subtitle); |
| mSubtitle = subtitle; |
| return this; |
| } |
| |
| /** |
| * Optional top-level group to help define the {@link Control}'s location, visible to the |
| * user. If not present, the application name will be used as the top-level group. A |
| * structure contains zones which contains controls. |
| * |
| * @param structure name of the structure containing the control |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setStructure(@Nullable CharSequence structure) { |
| mStructure = structure; |
| return this; |
| } |
| |
| /** |
| * Optional group name to help define the {@link Control}'s location within a structure, |
| * visible to the user. A structure contains zones which contains controls. |
| * |
| * @param zone name of the zone containing the control |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setZone(@Nullable CharSequence zone) { |
| mZone = zone; |
| return this; |
| } |
| |
| /** |
| * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control} |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setAppIntent(@NonNull PendingIntent appIntent) { |
| Preconditions.checkNotNull(appIntent); |
| mAppIntent = appIntent; |
| return this; |
| } |
| |
| /** |
| * Optional icon to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the icon unless the default icon is not suitable. |
| * |
| * @param customIcon icon to show |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setCustomIcon(@Nullable Icon customIcon) { |
| mCustomIcon = customIcon; |
| return this; |
| } |
| |
| /** |
| * Optional color to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the color unless the default is not suitable for the |
| * application. |
| * |
| * @param customColor background color to use |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatelessBuilder setCustomColor(@Nullable ColorStateList customColor) { |
| mCustomColor = customColor; |
| return this; |
| } |
| |
| /** |
| * @return a valid {@link Control} |
| */ |
| @NonNull |
| public Control build() { |
| return new Control(mControlId, |
| mDeviceType, |
| mTitle, |
| mSubtitle, |
| mStructure, |
| mZone, |
| mAppIntent, |
| mCustomIcon, |
| mCustomColor, |
| STATUS_UNKNOWN, |
| ControlTemplate.NO_TEMPLATE, |
| "", |
| true /* authRequired */); |
| } |
| } |
| |
| /** |
| * Builder class for {@link Control} that contains state information. |
| * |
| * State information is passed through an instance of a {@link ControlTemplate} and will |
| * determine how the user can interact with the {@link Control}. User interactions will |
| * be sent through the method call {@link ControlsProviderService#performControlAction} |
| * with an instance of {@link ControlAction} to convey any potential new value. |
| * |
| * Must be used to provide controls for {@link ControlsProviderService#createPublisherFor}. |
| * |
| * It provides the following defaults for non-optional parameters: |
| * <ul> |
| * <li> Device type: {@link DeviceTypes#TYPE_UNKNOWN} |
| * <li> Title: {@code ""} |
| * <li> Subtitle: {@code ""} |
| * <li> Status: {@link Status#STATUS_UNKNOWN} |
| * <li> Control template: {@link ControlTemplate#getNoTemplateObject} |
| * <li> Status text: {@code ""} |
| * <li> Auth Required: {@code true} |
| * </ul> |
| */ |
| public static final class StatefulBuilder { |
| private static final String TAG = "StatefulBuilder"; |
| private @NonNull String mControlId; |
| private @DeviceTypes.DeviceType int mDeviceType = DeviceTypes.TYPE_UNKNOWN; |
| private @NonNull CharSequence mTitle = ""; |
| private @NonNull CharSequence mSubtitle = ""; |
| private @Nullable CharSequence mStructure; |
| private @Nullable CharSequence mZone; |
| private @NonNull PendingIntent mAppIntent; |
| private @Nullable Icon mCustomIcon; |
| private @Nullable ColorStateList mCustomColor; |
| private @Status int mStatus = STATUS_UNKNOWN; |
| private @NonNull ControlTemplate mControlTemplate = ControlTemplate.NO_TEMPLATE; |
| private @NonNull CharSequence mStatusText = ""; |
| private boolean mAuthRequired = true; |
| |
| /** |
| * @param controlId the identifier for the {@link Control}. |
| * @param appIntent the pending intent linking to the device Activity. |
| */ |
| public StatefulBuilder(@NonNull String controlId, |
| @NonNull PendingIntent appIntent) { |
| Preconditions.checkNotNull(controlId); |
| Preconditions.checkNotNull(appIntent); |
| mControlId = controlId; |
| mAppIntent = appIntent; |
| } |
| |
| /** |
| * Creates a {@link StatelessBuilder} using an existing {@link Control} as a base. |
| * |
| * @param control base for the builder. |
| */ |
| public StatefulBuilder(@NonNull Control control) { |
| Preconditions.checkNotNull(control); |
| mControlId = control.mControlId; |
| mDeviceType = control.mDeviceType; |
| mTitle = control.mTitle; |
| mSubtitle = control.mSubtitle; |
| mStructure = control.mStructure; |
| mZone = control.mZone; |
| mAppIntent = control.mAppIntent; |
| mCustomIcon = control.mCustomIcon; |
| mCustomColor = control.mCustomColor; |
| mStatus = control.mStatus; |
| mControlTemplate = control.mControlTemplate; |
| mStatusText = control.mStatusText; |
| mAuthRequired = control.mAuthRequired; |
| } |
| |
| /** |
| * @param controlId the identifier for the {@link Control}. |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setControlId(@NonNull String controlId) { |
| Preconditions.checkNotNull(controlId); |
| mControlId = controlId; |
| return this; |
| } |
| |
| /** |
| * @param deviceType type of device represented by this {@link Control}, used to |
| * determine the default icon and color |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setDeviceType(@DeviceTypes.DeviceType int deviceType) { |
| if (!DeviceTypes.validDeviceType(deviceType)) { |
| Log.e(TAG, "Invalid device type:" + deviceType); |
| mDeviceType = DeviceTypes.TYPE_UNKNOWN; |
| } else { |
| mDeviceType = deviceType; |
| } |
| return this; |
| } |
| |
| /** |
| * @param title the user facing name of the {@link Control} |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setTitle(@NonNull CharSequence title) { |
| Preconditions.checkNotNull(title); |
| mTitle = title; |
| return this; |
| } |
| |
| /** |
| * @param subtitle additional information about the {@link Control}, to appear underneath |
| * the title |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setSubtitle(@NonNull CharSequence subtitle) { |
| Preconditions.checkNotNull(subtitle); |
| mSubtitle = subtitle; |
| return this; |
| } |
| |
| /** |
| * Optional top-level group to help define the {@link Control}'s location, visible to the |
| * user. If not present, the application name will be used as the top-level group. A |
| * structure contains zones which contains controls. |
| * |
| * @param structure name of the structure containing the control |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setStructure(@Nullable CharSequence structure) { |
| mStructure = structure; |
| return this; |
| } |
| |
| /** |
| * Optional group name to help define the {@link Control}'s location within a structure, |
| * visible to the user. A structure contains zones which contains controls. |
| * |
| * @param zone name of the zone containing the control |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setZone(@Nullable CharSequence zone) { |
| mZone = zone; |
| return this; |
| } |
| |
| /** |
| * @param appIntent a {@link PendingIntent} linking to an Activity for the {@link Control} |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setAppIntent(@NonNull PendingIntent appIntent) { |
| Preconditions.checkNotNull(appIntent); |
| mAppIntent = appIntent; |
| return this; |
| } |
| |
| /** |
| * Optional icon to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the icon unless the default icon is not suitable. |
| * |
| * @param customIcon icon to show |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setCustomIcon(@Nullable Icon customIcon) { |
| mCustomIcon = customIcon; |
| return this; |
| } |
| |
| /** |
| * Optional color to be shown with the {@link Control}. It is highly recommended |
| * to let the system default the color unless the default is not suitable for the |
| * application. |
| * |
| * @param customColor background color to use |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setCustomColor(@Nullable ColorStateList customColor) { |
| mCustomColor = customColor; |
| return this; |
| } |
| |
| /** |
| * @param status status of the {@link Control}, used to convey information about the |
| * attempt to fetch the current state |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setStatus(@Status int status) { |
| if (status < 0 || status >= NUM_STATUS) { |
| mStatus = STATUS_UNKNOWN; |
| Log.e(TAG, "Status unknown:" + status); |
| } else { |
| mStatus = status; |
| } |
| return this; |
| } |
| |
| /** |
| * Set the {@link ControlTemplate} to define the primary user interaction |
| * |
| * Devices may support a variety of user interactions, and all interactions cannot be |
| * represented with a single {@link ControlTemplate}. Therefore, the selected template |
| * should be most closely aligned with what the expected primary device action will be. |
| * Any secondary interactions can be done via the {@link #setAppIntent(PendingIntent)}. |
| * |
| * @param controlTemplate instance of {@link ControlTemplate}, that defines how the |
| * {@link Control} will behave and what interactions are |
| * available to the user |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setControlTemplate(@NonNull ControlTemplate controlTemplate) { |
| Preconditions.checkNotNull(controlTemplate); |
| mControlTemplate = controlTemplate; |
| return this; |
| } |
| |
| /** |
| * @param statusText user-facing text description of the {@link Control}'s status, |
| * describing its current state |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setStatusText(@NonNull CharSequence statusText) { |
| Preconditions.checkNotNull(statusText); |
| mStatusText = statusText; |
| return this; |
| } |
| |
| /** |
| * @param authRequired true if the control can not be interacted with until the device is |
| * unlocked |
| * @return {@code this} |
| */ |
| @NonNull |
| public StatefulBuilder setAuthRequired(boolean authRequired) { |
| mAuthRequired = authRequired; |
| return this; |
| } |
| |
| /** |
| * @return a valid {@link Control} |
| */ |
| @NonNull |
| public Control build() { |
| return new Control(mControlId, |
| mDeviceType, |
| mTitle, |
| mSubtitle, |
| mStructure, |
| mZone, |
| mAppIntent, |
| mCustomIcon, |
| mCustomColor, |
| mStatus, |
| mControlTemplate, |
| mStatusText, |
| mAuthRequired); |
| } |
| } |
| } |