| /* |
| * 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 android.safetycenter; |
| |
| import static android.os.Build.VERSION_CODES.TIRAMISU; |
| |
| import static java.util.Objects.requireNonNull; |
| |
| import android.annotation.IntDef; |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.text.TextUtils; |
| |
| import androidx.annotation.RequiresApi; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.util.Objects; |
| |
| /** |
| * The overall status of the Safety Center. |
| * |
| * @hide |
| */ |
| @SystemApi |
| @RequiresApi(TIRAMISU) |
| public final class SafetyCenterStatus implements Parcelable { |
| |
| /** Indicates the overall severity level of the Safety Center is not currently known. */ |
| public static final int OVERALL_SEVERITY_LEVEL_UNKNOWN = 1000; |
| |
| /** |
| * Indicates the overall safety status of the device is OK and there are no actionable issues. |
| */ |
| public static final int OVERALL_SEVERITY_LEVEL_OK = 1100; |
| |
| /** Indicates the presence of safety recommendations which the user is encouraged to act on. */ |
| public static final int OVERALL_SEVERITY_LEVEL_RECOMMENDATION = 1200; |
| |
| /** Indicates the presence of critical safety warnings on the device. */ |
| public static final int OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING = 1300; |
| |
| /** |
| * All possible overall severity levels for the Safety Center. |
| * |
| * <p>The overall severity level is calculated from the severity level and statuses of all |
| * issues and entries in the Safety Center. |
| * |
| * @hide |
| * @see #getSeverityLevel() |
| * @see Builder#setSeverityLevel(int) |
| */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef( |
| prefix = "OVERALL_SEVERITY_LEVEL_", |
| value = { |
| OVERALL_SEVERITY_LEVEL_UNKNOWN, |
| OVERALL_SEVERITY_LEVEL_OK, |
| OVERALL_SEVERITY_LEVEL_RECOMMENDATION, |
| OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING, |
| }) |
| public @interface OverallSeverityLevel {} |
| |
| /** Indicates that no refresh is ongoing. */ |
| public static final int REFRESH_STATUS_NONE = 0; |
| |
| /** |
| * Indicates that a data fetch is ongoing, and Safety Sources are being asked for their current |
| * safety state. |
| * |
| * <p>If sources already have their safety data cached, they may provide it without triggering a |
| * process to fetch or recompute state which may be expensive and/or slow. |
| */ |
| public static final int REFRESH_STATUS_DATA_FETCH_IN_PROGRESS = 10100; |
| |
| /** |
| * Indicates that a full rescan is ongoing, and Safety Sources are being asked to fetch fresh |
| * data for their safety state. |
| * |
| * <p>The term "fresh" here means that the sources should ensure that the safety data is |
| * accurate as possible at the time of providing it to Safety Center, even if it involves |
| * performing an expensive and/or slow process. |
| */ |
| public static final int REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS = 10200; |
| |
| /** |
| * All possible refresh states for the Safety Center. |
| * |
| * @hide |
| * @see #getRefreshStatus() |
| * @see Builder#setRefreshStatus(int) |
| */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef( |
| prefix = "REFRESH_STATUS_", |
| value = { |
| REFRESH_STATUS_NONE, |
| REFRESH_STATUS_DATA_FETCH_IN_PROGRESS, |
| REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS, |
| }) |
| public @interface RefreshStatus {} |
| |
| @NonNull |
| public static final Creator<SafetyCenterStatus> CREATOR = |
| new Creator<SafetyCenterStatus>() { |
| @Override |
| public SafetyCenterStatus createFromParcel(Parcel in) { |
| CharSequence title = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); |
| CharSequence summary = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); |
| return new Builder(title, summary) |
| .setSeverityLevel(in.readInt()) |
| .setRefreshStatus(in.readInt()) |
| .build(); |
| } |
| |
| @Override |
| public SafetyCenterStatus[] newArray(int size) { |
| return new SafetyCenterStatus[size]; |
| } |
| }; |
| |
| @NonNull private final CharSequence mTitle; |
| @NonNull private final CharSequence mSummary; |
| @OverallSeverityLevel private final int mSeverityLevel; |
| @RefreshStatus private final int mRefreshStatus; |
| |
| private SafetyCenterStatus( |
| @NonNull CharSequence title, |
| @NonNull CharSequence summary, |
| @OverallSeverityLevel int severityLevel, |
| @RefreshStatus int refreshStatus) { |
| mTitle = title; |
| mSummary = summary; |
| mSeverityLevel = severityLevel; |
| mRefreshStatus = refreshStatus; |
| } |
| |
| /** Returns the title which describes the overall safety state of the device. */ |
| @NonNull |
| public CharSequence getTitle() { |
| return mTitle; |
| } |
| |
| /** Returns the summary text which adds detail to the overall safety state of the device. */ |
| @NonNull |
| public CharSequence getSummary() { |
| return mSummary; |
| } |
| |
| /** Returns the current {@link OverallSeverityLevel} of the Safety Center. */ |
| @OverallSeverityLevel |
| public int getSeverityLevel() { |
| return mSeverityLevel; |
| } |
| |
| /** Returns the current {@link RefreshStatus} of the Safety Center */ |
| @RefreshStatus |
| public int getRefreshStatus() { |
| return mRefreshStatus; |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) return true; |
| if (!(o instanceof SafetyCenterStatus)) return false; |
| SafetyCenterStatus that = (SafetyCenterStatus) o; |
| return mSeverityLevel == that.mSeverityLevel |
| && mRefreshStatus == that.mRefreshStatus |
| && TextUtils.equals(mTitle, that.mTitle) |
| && TextUtils.equals(mSummary, that.mSummary); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(mTitle, mSummary, mSeverityLevel, mRefreshStatus); |
| } |
| |
| @Override |
| public String toString() { |
| return "SafetyCenterStatus{" |
| + "mTitle=" |
| + mTitle |
| + ", mSummary=" |
| + mSummary |
| + ", mSeverityLevel=" |
| + mSeverityLevel |
| + ", mRefreshStatus=" |
| + mRefreshStatus |
| + '}'; |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull Parcel dest, int flags) { |
| TextUtils.writeToParcel(mTitle, dest, flags); |
| TextUtils.writeToParcel(mSummary, dest, flags); |
| dest.writeInt(mSeverityLevel); |
| dest.writeInt(mRefreshStatus); |
| } |
| |
| /** Builder class for {@link SafetyCenterStatus}. */ |
| public static final class Builder { |
| |
| @NonNull private CharSequence mTitle; |
| @NonNull private CharSequence mSummary; |
| @OverallSeverityLevel private int mSeverityLevel = OVERALL_SEVERITY_LEVEL_UNKNOWN; |
| @RefreshStatus private int mRefreshStatus = REFRESH_STATUS_NONE; |
| |
| /** |
| * Creates a new {@link Builder} for a {@link SafetyCenterStatus}. |
| * |
| * @param title an overall title for the status |
| * @param summary a summary for the status |
| */ |
| public Builder(@NonNull CharSequence title, @NonNull CharSequence summary) { |
| mTitle = requireNonNull(title); |
| mSummary = requireNonNull(summary); |
| } |
| |
| /** Creates a {@link Builder} with the values from the given {@link SafetyCenterStatus}. */ |
| public Builder(@NonNull SafetyCenterStatus safetyCenterStatus) { |
| mTitle = safetyCenterStatus.mTitle; |
| mSummary = safetyCenterStatus.mSummary; |
| mSeverityLevel = safetyCenterStatus.mSeverityLevel; |
| mRefreshStatus = safetyCenterStatus.mRefreshStatus; |
| } |
| |
| /** Sets the title for this status. */ |
| @NonNull |
| public Builder setTitle(@NonNull CharSequence title) { |
| mTitle = requireNonNull(title); |
| return this; |
| } |
| |
| /** Sets the summary text for this status. */ |
| @NonNull |
| public Builder setSummary(@NonNull CharSequence summary) { |
| mSummary = requireNonNull(summary); |
| return this; |
| } |
| |
| /** |
| * Sets the {@link OverallSeverityLevel} of this status. Defaults to {@link |
| * #OVERALL_SEVERITY_LEVEL_UNKNOWN}. |
| */ |
| @NonNull |
| public Builder setSeverityLevel(@OverallSeverityLevel int severityLevel) { |
| mSeverityLevel = validateOverallSeverityLevel(severityLevel); |
| return this; |
| } |
| |
| /** |
| * Sets the {@link RefreshStatus} of this status. Defaults to {@link #REFRESH_STATUS_NONE}. |
| */ |
| @NonNull |
| public Builder setRefreshStatus(@RefreshStatus int refreshStatus) { |
| mRefreshStatus = validateRefreshStatus(refreshStatus); |
| return this; |
| } |
| |
| /** Creates the {@link SafetyCenterStatus} defined by this {@link Builder}. */ |
| @NonNull |
| public SafetyCenterStatus build() { |
| return new SafetyCenterStatus(mTitle, mSummary, mSeverityLevel, mRefreshStatus); |
| } |
| } |
| |
| @OverallSeverityLevel |
| private static int validateOverallSeverityLevel(int value) { |
| switch (value) { |
| case OVERALL_SEVERITY_LEVEL_UNKNOWN: |
| case OVERALL_SEVERITY_LEVEL_OK: |
| case OVERALL_SEVERITY_LEVEL_RECOMMENDATION: |
| case OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING: |
| return value; |
| default: |
| } |
| throw new IllegalArgumentException( |
| "Unexpected OverallSeverityLevel for SafetyCenterStatus: " + value); |
| } |
| |
| @RefreshStatus |
| private static int validateRefreshStatus(int value) { |
| switch (value) { |
| case REFRESH_STATUS_NONE: |
| case REFRESH_STATUS_DATA_FETCH_IN_PROGRESS: |
| case REFRESH_STATUS_FULL_RESCAN_IN_PROGRESS: |
| return value; |
| default: |
| } |
| throw new IllegalArgumentException( |
| "Unexpected RefreshStatus for SafetyCenterStatus: " + value); |
| } |
| } |