1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app.time; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.os.ShellCommand; 25 26 import java.io.PrintWriter; 27 import java.util.Objects; 28 29 /** 30 * A snapshot of the system time state. 31 * 32 * <p>{@code unixEpochTime} contains a snapshot of the system clock time and elapsed realtime clock 33 * time. 34 * 35 * <p>{@code userShouldConfirmTime} is {@code true} if the system automatic time detection logic 36 * suggests that the user be asked to confirm the {@code unixEpochTime} value is correct via {@link 37 * TimeManager#confirmTime}. If it is not correct, the value can usually be changed via {@link 38 * TimeManager#setManualTime}. 39 * 40 * @hide 41 */ 42 @SystemApi 43 public final class TimeState implements Parcelable { 44 45 public static final @NonNull Creator<TimeState> CREATOR = new Creator<>() { 46 public TimeState createFromParcel(Parcel in) { 47 return TimeState.createFromParcel(in); 48 } 49 50 public TimeState[] newArray(int size) { 51 return new TimeState[size]; 52 } 53 }; 54 55 @NonNull private final UnixEpochTime mUnixEpochTime; 56 private final boolean mUserShouldConfirmTime; 57 58 /** @hide */ TimeState(@onNull UnixEpochTime unixEpochTime, boolean userShouldConfirmTime)59 public TimeState(@NonNull UnixEpochTime unixEpochTime, boolean userShouldConfirmTime) { 60 mUnixEpochTime = Objects.requireNonNull(unixEpochTime); 61 mUserShouldConfirmTime = userShouldConfirmTime; 62 } 63 createFromParcel(Parcel in)64 private static TimeState createFromParcel(Parcel in) { 65 UnixEpochTime unixEpochTime = in.readParcelable(null, UnixEpochTime.class); 66 boolean userShouldConfirmId = in.readBoolean(); 67 return new TimeState(unixEpochTime, userShouldConfirmId); 68 } 69 70 @Override writeToParcel(@onNull Parcel dest, int flags)71 public void writeToParcel(@NonNull Parcel dest, int flags) { 72 dest.writeParcelable(mUnixEpochTime, 0); 73 dest.writeBoolean(mUserShouldConfirmTime); 74 } 75 76 /** @hide */ 77 @Nullable parseCommandLineArgs(@onNull ShellCommand cmd)78 public static TimeState parseCommandLineArgs(@NonNull ShellCommand cmd) { 79 Long elapsedRealtimeMillis = null; 80 Long unixEpochTimeMillis = null; 81 Boolean userShouldConfirmTime = null; 82 String opt; 83 while ((opt = cmd.getNextArg()) != null) { 84 switch (opt) { 85 case "--elapsed_realtime": { 86 elapsedRealtimeMillis = Long.parseLong(cmd.getNextArgRequired()); 87 break; 88 } 89 case "--unix_epoch_time": { 90 unixEpochTimeMillis = Long.parseLong(cmd.getNextArgRequired()); 91 break; 92 } 93 case "--user_should_confirm_time": { 94 userShouldConfirmTime = Boolean.parseBoolean(cmd.getNextArgRequired()); 95 break; 96 } 97 default: { 98 throw new IllegalArgumentException("Unknown option: " + opt); 99 } 100 } 101 } 102 103 if (elapsedRealtimeMillis == null) { 104 throw new IllegalArgumentException("No elapsedRealtimeMillis specified."); 105 } 106 if (unixEpochTimeMillis == null) { 107 throw new IllegalArgumentException("No unixEpochTimeMillis specified."); 108 } 109 if (userShouldConfirmTime == null) { 110 throw new IllegalArgumentException("No userShouldConfirmTime specified."); 111 } 112 113 UnixEpochTime unixEpochTime = new UnixEpochTime(elapsedRealtimeMillis, unixEpochTimeMillis); 114 return new TimeState(unixEpochTime, userShouldConfirmTime); 115 } 116 117 /** @hide */ printCommandLineOpts(@onNull PrintWriter pw)118 public static void printCommandLineOpts(@NonNull PrintWriter pw) { 119 pw.println("TimeState options:"); 120 pw.println(" --elapsed_realtime <elapsed realtime millis>"); 121 pw.println(" --unix_epoch_time <Unix epoch time millis>"); 122 pw.println(" --user_should_confirm_time {true|false}"); 123 pw.println(); 124 pw.println("See " + TimeState.class.getName() + " for more information"); 125 } 126 127 @Override describeContents()128 public int describeContents() { 129 return 0; 130 } 131 132 @NonNull getUnixEpochTime()133 public UnixEpochTime getUnixEpochTime() { 134 return mUnixEpochTime; 135 } 136 getUserShouldConfirmTime()137 public boolean getUserShouldConfirmTime() { 138 return mUserShouldConfirmTime; 139 } 140 141 @Override equals(@ullable Object o)142 public boolean equals(@Nullable Object o) { 143 if (this == o) { 144 return true; 145 } 146 if (o == null || getClass() != o.getClass()) { 147 return false; 148 } 149 TimeState that = (TimeState) o; 150 return Objects.equals(mUnixEpochTime, that.mUnixEpochTime) 151 && mUserShouldConfirmTime == that.mUserShouldConfirmTime; 152 } 153 154 @Override hashCode()155 public int hashCode() { 156 return Objects.hash(mUnixEpochTime, mUserShouldConfirmTime); 157 } 158 159 @Override toString()160 public String toString() { 161 return "TimeState{" 162 + "mUnixEpochTime=" + mUnixEpochTime 163 + ", mUserShouldConfirmTime=" + mUserShouldConfirmTime 164 + '}'; 165 } 166 } 167