Merge "Add time related API to TimeManager." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d355fee300
@@ -1696,6 +1696,13 @@ package android.app.smartspace {
|
|||||||
|
|
||||||
package android.app.time {
|
package android.app.time {
|
||||||
|
|
||||||
|
public final class Capabilities {
|
||||||
|
field public static final int CAPABILITY_NOT_ALLOWED = 20; // 0x14
|
||||||
|
field public static final int CAPABILITY_NOT_APPLICABLE = 30; // 0x1e
|
||||||
|
field public static final int CAPABILITY_NOT_SUPPORTED = 10; // 0xa
|
||||||
|
field public static final int CAPABILITY_POSSESSED = 40; // 0x28
|
||||||
|
}
|
||||||
|
|
||||||
public final class TimeManager {
|
public final class TimeManager {
|
||||||
method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void addTimeZoneDetectorListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.time.TimeManager.TimeZoneDetectorListener);
|
method @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public void addTimeZoneDetectorListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.time.TimeManager.TimeZoneDetectorListener);
|
||||||
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public android.app.time.TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig();
|
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION) public android.app.time.TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig();
|
||||||
@@ -1712,10 +1719,6 @@ package android.app.time {
|
|||||||
method public int getConfigureAutoDetectionEnabledCapability();
|
method public int getConfigureAutoDetectionEnabledCapability();
|
||||||
method public int getConfigureGeoDetectionEnabledCapability();
|
method public int getConfigureGeoDetectionEnabledCapability();
|
||||||
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
method public void writeToParcel(@NonNull android.os.Parcel, int);
|
||||||
field public static final int CAPABILITY_NOT_ALLOWED = 20; // 0x14
|
|
||||||
field public static final int CAPABILITY_NOT_APPLICABLE = 30; // 0x1e
|
|
||||||
field public static final int CAPABILITY_NOT_SUPPORTED = 10; // 0xa
|
|
||||||
field public static final int CAPABILITY_POSSESSED = 40; // 0x28
|
|
||||||
field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilities> CREATOR;
|
field @NonNull public static final android.os.Parcelable.Creator<android.app.time.TimeZoneCapabilities> CREATOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
78
core/java/android/app/time/Capabilities.java
Normal file
78
core/java/android/app/time/Capabilities.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
|
import android.annotation.SystemApi;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A capability is the ability for the user to configure something or perform an action. This
|
||||||
|
* information is exposed so that system apps like SettingsUI can be dynamic, rather than
|
||||||
|
* hard-coding knowledge of when configuration or actions are applicable / available to the user.
|
||||||
|
*
|
||||||
|
* <p>Capabilities have states that users cannot change directly. They may influence some
|
||||||
|
* capabilities indirectly by agreeing to certain device-wide behaviors such as location sharing, or
|
||||||
|
* by changing the configuration. See the {@code CAPABILITY_} constants for details.
|
||||||
|
*
|
||||||
|
* <p>Actions have associated methods, see the documentation for each action for details.
|
||||||
|
*
|
||||||
|
* <p>Note: Capabilities are independent of app permissions required to call the associated APIs.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SystemApi
|
||||||
|
public final class Capabilities {
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@IntDef({ CAPABILITY_NOT_SUPPORTED, CAPABILITY_NOT_ALLOWED, CAPABILITY_NOT_APPLICABLE,
|
||||||
|
CAPABILITY_POSSESSED })
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface CapabilityState {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a capability is not supported on this device, e.g. because of form factor or
|
||||||
|
* hardware. The associated UI should usually not be shown to the user.
|
||||||
|
*/
|
||||||
|
public static final int CAPABILITY_NOT_SUPPORTED = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a capability is supported on this device, but not allowed for the user, e.g.
|
||||||
|
* if the capability relates to the ability to modify settings the user is not able to.
|
||||||
|
* This could be because of the user's type (e.g. maybe it applies to the primary user only) or
|
||||||
|
* device policy. Depending on the capability, this could mean the associated UI
|
||||||
|
* should be hidden, or displayed but disabled.
|
||||||
|
*/
|
||||||
|
public static final int CAPABILITY_NOT_ALLOWED = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a capability is possessed but not currently applicable, e.g. if the
|
||||||
|
* capability relates to the ability to modify settings, the user has the ability to modify
|
||||||
|
* it, but it is currently rendered irrelevant by other settings or other device state (flags,
|
||||||
|
* resource config, etc.). The associated UI may be hidden, disabled, or left visible (but
|
||||||
|
* ineffective) depending on requirements.
|
||||||
|
*/
|
||||||
|
public static final int CAPABILITY_NOT_APPLICABLE = 30;
|
||||||
|
|
||||||
|
/** Indicates that a capability is possessed by the user. */
|
||||||
|
public static final int CAPABILITY_POSSESSED = 40;
|
||||||
|
|
||||||
|
private Capabilities() {}
|
||||||
|
|
||||||
|
}
|
||||||
19
core/java/android/app/time/TimeCapabilities.aidl
Normal file
19
core/java/android/app/time/TimeCapabilities.aidl
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
parcelable TimeCapabilities;
|
||||||
186
core/java/android/app/time/TimeCapabilities.java
Normal file
186
core/java/android/app/time/TimeCapabilities.java
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.app.time.Capabilities.CapabilityState;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time-relate capabilities for a user.
|
||||||
|
*
|
||||||
|
* <p>For configuration settings capabilities, the associated settings value can be found via
|
||||||
|
* {@link TimeManager#getTimeCapabilitiesAndConfig()} and may be changed using {@link
|
||||||
|
* TimeManager#updateTimeConfiguration(TimeConfiguration)} (if the user's capabilities
|
||||||
|
* allow).
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TimeCapabilities implements Parcelable {
|
||||||
|
|
||||||
|
public static final @NonNull Creator<TimeCapabilities> CREATOR =
|
||||||
|
new Creator<TimeCapabilities>() {
|
||||||
|
public TimeCapabilities createFromParcel(Parcel in) {
|
||||||
|
return TimeCapabilities.createFromParcel(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeCapabilities[] newArray(int size) {
|
||||||
|
return new TimeCapabilities[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The user the capabilities are for. This is used for object equality and debugging but there
|
||||||
|
* is no accessor.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final UserHandle mUserHandle;
|
||||||
|
private final @CapabilityState int mConfigureAutoTimeDetectionEnabledCapability;
|
||||||
|
private final @CapabilityState int mSuggestTimeManuallyCapability;
|
||||||
|
|
||||||
|
private TimeCapabilities(@NonNull Builder builder) {
|
||||||
|
this.mUserHandle = Objects.requireNonNull(builder.mUserHandle);
|
||||||
|
this.mConfigureAutoTimeDetectionEnabledCapability =
|
||||||
|
builder.mConfigureAutoDetectionEnabledCapability;
|
||||||
|
this.mSuggestTimeManuallyCapability =
|
||||||
|
builder.mSuggestTimeManuallyCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static TimeCapabilities createFromParcel(Parcel in) {
|
||||||
|
UserHandle userHandle = UserHandle.readFromParcel(in);
|
||||||
|
return new TimeCapabilities.Builder(userHandle)
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(in.readInt())
|
||||||
|
.setSuggestTimeManuallyCapability(in.readInt())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
UserHandle.writeToParcel(mUserHandle, dest);
|
||||||
|
dest.writeInt(mConfigureAutoTimeDetectionEnabledCapability);
|
||||||
|
dest.writeInt(mSuggestTimeManuallyCapability);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the capability state associated with the user's ability to modify the automatic time
|
||||||
|
* detection setting.
|
||||||
|
*/
|
||||||
|
@CapabilityState
|
||||||
|
public int getConfigureAutoTimeDetectionEnabledCapability() {
|
||||||
|
return mConfigureAutoTimeDetectionEnabledCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the capability state associated with the user's ability to manually set time on a
|
||||||
|
* device.
|
||||||
|
*/
|
||||||
|
@CapabilityState
|
||||||
|
public int getSuggestTimeManuallyCapability() {
|
||||||
|
return mSuggestTimeManuallyCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
TimeCapabilities that = (TimeCapabilities) o;
|
||||||
|
return mConfigureAutoTimeDetectionEnabledCapability
|
||||||
|
== that.mConfigureAutoTimeDetectionEnabledCapability
|
||||||
|
&& mSuggestTimeManuallyCapability == that.mSuggestTimeManuallyCapability
|
||||||
|
&& mUserHandle.equals(that.mUserHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mUserHandle, mConfigureAutoTimeDetectionEnabledCapability,
|
||||||
|
mSuggestTimeManuallyCapability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TimeCapabilities{"
|
||||||
|
+ "mUserHandle=" + mUserHandle
|
||||||
|
+ ", mConfigureAutoTimeDetectionEnabledCapability="
|
||||||
|
+ mConfigureAutoTimeDetectionEnabledCapability
|
||||||
|
+ ", mSuggestTimeManuallyCapability=" + mSuggestTimeManuallyCapability
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder of {@link TimeCapabilities} objects.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
@NonNull private final UserHandle mUserHandle;
|
||||||
|
private @CapabilityState int mConfigureAutoDetectionEnabledCapability;
|
||||||
|
private @CapabilityState int mSuggestTimeManuallyCapability;
|
||||||
|
|
||||||
|
public Builder(@NonNull TimeCapabilities timeCapabilities) {
|
||||||
|
Objects.requireNonNull(timeCapabilities);
|
||||||
|
this.mUserHandle = timeCapabilities.mUserHandle;
|
||||||
|
this.mConfigureAutoDetectionEnabledCapability =
|
||||||
|
timeCapabilities.mConfigureAutoTimeDetectionEnabledCapability;
|
||||||
|
this.mSuggestTimeManuallyCapability =
|
||||||
|
timeCapabilities.mSuggestTimeManuallyCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(@NonNull UserHandle userHandle) {
|
||||||
|
this.mUserHandle = Objects.requireNonNull(userHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the state for automatic time detection config. */
|
||||||
|
public Builder setConfigureAutoTimeDetectionEnabledCapability(
|
||||||
|
@CapabilityState int setConfigureAutoTimeDetectionEnabledCapability) {
|
||||||
|
this.mConfigureAutoDetectionEnabledCapability =
|
||||||
|
setConfigureAutoTimeDetectionEnabledCapability;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the state for manual time change. */
|
||||||
|
public Builder setSuggestTimeManuallyCapability(
|
||||||
|
@CapabilityState int suggestTimeManuallyCapability) {
|
||||||
|
this.mSuggestTimeManuallyCapability = suggestTimeManuallyCapability;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the {@link TimeCapabilities}. */
|
||||||
|
public TimeCapabilities build() {
|
||||||
|
verifyCapabilitySet(mConfigureAutoDetectionEnabledCapability,
|
||||||
|
"configureAutoDetectionEnabledCapability");
|
||||||
|
verifyCapabilitySet(mSuggestTimeManuallyCapability, "suggestTimeManuallyCapability");
|
||||||
|
return new TimeCapabilities(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyCapabilitySet(int value, String name) {
|
||||||
|
if (value == 0) {
|
||||||
|
throw new IllegalStateException(name + " was not set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
core/java/android/app/time/TimeCapabilitiesAndConfig.aidl
Normal file
19
core/java/android/app/time/TimeCapabilitiesAndConfig.aidl
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
parcelable TimeCapabilitiesAndConfig;
|
||||||
119
core/java/android/app/time/TimeCapabilitiesAndConfig.java
Normal file
119
core/java/android/app/time/TimeCapabilitiesAndConfig.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A pair containing a user's {@link TimeCapabilities} and {@link TimeConfiguration}.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TimeCapabilitiesAndConfig implements Parcelable {
|
||||||
|
|
||||||
|
public static final @NonNull Creator<TimeCapabilitiesAndConfig> CREATOR =
|
||||||
|
new Creator<TimeCapabilitiesAndConfig>() {
|
||||||
|
@Override
|
||||||
|
public TimeCapabilitiesAndConfig createFromParcel(Parcel source) {
|
||||||
|
return TimeCapabilitiesAndConfig.readFromParcel(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeCapabilitiesAndConfig[] newArray(int size) {
|
||||||
|
return new TimeCapabilitiesAndConfig[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final TimeCapabilities mTimeCapabilities;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final TimeConfiguration mTimeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public TimeCapabilitiesAndConfig(@NonNull TimeCapabilities timeCapabilities,
|
||||||
|
@NonNull TimeConfiguration timeConfiguration) {
|
||||||
|
mTimeCapabilities = Objects.requireNonNull(timeCapabilities);
|
||||||
|
mTimeConfiguration = Objects.requireNonNull(timeConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static TimeCapabilitiesAndConfig readFromParcel(Parcel in) {
|
||||||
|
TimeCapabilities capabilities = in.readParcelable(null);
|
||||||
|
TimeConfiguration configuration = in.readParcelable(null);
|
||||||
|
return new TimeCapabilitiesAndConfig(capabilities, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's time behaviour capabilities.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public TimeCapabilities getTimeCapabilities() {
|
||||||
|
return mTimeCapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the user's time behaviour configuration.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public TimeConfiguration getTimeConfiguration() {
|
||||||
|
return mTimeConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeParcelable(mTimeCapabilities, flags);
|
||||||
|
dest.writeParcelable(mTimeConfiguration, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
TimeCapabilitiesAndConfig that = (TimeCapabilitiesAndConfig) o;
|
||||||
|
return mTimeCapabilities.equals(that.mTimeCapabilities)
|
||||||
|
&& mTimeConfiguration.equals(that.mTimeConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mTimeCapabilities, mTimeConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TimeCapabilitiesAndConfig{"
|
||||||
|
+ "mTimeCapabilities=" + mTimeCapabilities
|
||||||
|
+ ", mTimeConfiguration=" + mTimeConfiguration
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
19
core/java/android/app/time/TimeConfiguration.aidl
Normal file
19
core/java/android/app/time/TimeConfiguration.aidl
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
parcelable TimeConfiguration;
|
||||||
141
core/java/android/app/time/TimeConfiguration.java
Normal file
141
core/java/android/app/time/TimeConfiguration.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.StringDef;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User visible settings that control the behavior of the time zone detector / manual time zone
|
||||||
|
* entry.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final class TimeConfiguration implements Parcelable {
|
||||||
|
|
||||||
|
public static final @NonNull Creator<TimeConfiguration> CREATOR =
|
||||||
|
new Creator<TimeConfiguration>() {
|
||||||
|
@Override
|
||||||
|
public TimeConfiguration createFromParcel(Parcel source) {
|
||||||
|
return TimeConfiguration.readFromParcel(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeConfiguration[] newArray(int size) {
|
||||||
|
return new TimeConfiguration[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@StringDef(SETTING_AUTO_DETECTION_ENABLED)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@interface Setting {}
|
||||||
|
|
||||||
|
@Setting
|
||||||
|
private static final String SETTING_AUTO_DETECTION_ENABLED = "autoDetectionEnabled";
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final Bundle mBundle;
|
||||||
|
|
||||||
|
private TimeConfiguration(Builder builder) {
|
||||||
|
this.mBundle = builder.mBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the {@link #SETTING_AUTO_DETECTION_ENABLED} setting. This
|
||||||
|
* controls whether a device will attempt to determine the time automatically using
|
||||||
|
* contextual information if the device supports auto detection.
|
||||||
|
*/
|
||||||
|
public boolean isAutoDetectionEnabled() {
|
||||||
|
return mBundle.getBoolean(SETTING_AUTO_DETECTION_ENABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||||
|
dest.writeBundle(mBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TimeConfiguration readFromParcel(Parcel in) {
|
||||||
|
return new TimeConfiguration.Builder()
|
||||||
|
.merge(in.readBundle())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
TimeConfiguration that = (TimeConfiguration) o;
|
||||||
|
return mBundle.kindofEquals(that.mBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TimeConfiguration{"
|
||||||
|
+ "mBundle=" + mBundle
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder for {@link TimeConfiguration} objects.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final class Builder {
|
||||||
|
private final Bundle mBundle = new Bundle();
|
||||||
|
|
||||||
|
public Builder() {}
|
||||||
|
|
||||||
|
public Builder(@NonNull TimeConfiguration configuration) {
|
||||||
|
mBundle.putAll(configuration.mBundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets whether auto detection is enabled or not. */
|
||||||
|
@NonNull
|
||||||
|
public Builder setAutoDetectionEnabled(boolean enabled) {
|
||||||
|
mBundle.putBoolean(SETTING_AUTO_DETECTION_ENABLED, enabled);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder merge(@NonNull Bundle bundle) {
|
||||||
|
mBundle.putAll(bundle);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns {@link TimeConfiguration} object. */
|
||||||
|
@NonNull
|
||||||
|
public TimeConfiguration build() {
|
||||||
|
return new TimeConfiguration(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -75,7 +75,7 @@ public final class TimeManager {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig() {
|
public TimeZoneCapabilitiesAndConfig getTimeZoneCapabilitiesAndConfig() {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "getTimeZoneCapabilities called");
|
Log.d(TAG, "getTimeZoneCapabilitiesAndConfig called");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return mITimeZoneDetectorService.getCapabilitiesAndConfig();
|
return mITimeZoneDetectorService.getCapabilitiesAndConfig();
|
||||||
@@ -84,6 +84,44 @@ public final class TimeManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the calling user's time capabilities and configuration.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION)
|
||||||
|
@NonNull
|
||||||
|
public TimeCapabilitiesAndConfig getTimeCapabilitiesAndConfig() {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "getTimeCapabilitiesAndConfig called");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return mITimeDetectorService.getCapabilitiesAndConfig();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Modifies the time detection configuration.
|
||||||
|
*
|
||||||
|
* @return {@code true} if all the configuration settings specified have been set to the
|
||||||
|
* new values, {@code false} if none have
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@RequiresPermission(android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION)
|
||||||
|
public boolean updateTimeConfiguration(@NonNull TimeConfiguration configuration) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "updateTimeConfiguration called: " + configuration);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return mITimeDetectorService.updateConfiguration(configuration);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifies the time zone detection configuration.
|
* Modifies the time zone detection configuration.
|
||||||
*
|
*
|
||||||
@@ -97,11 +135,11 @@ public final class TimeManager {
|
|||||||
* capabilities.
|
* capabilities.
|
||||||
*
|
*
|
||||||
* <p>Attempts to modify configuration settings with capabilities that are {@link
|
* <p>Attempts to modify configuration settings with capabilities that are {@link
|
||||||
* TimeZoneCapabilities#CAPABILITY_NOT_SUPPORTED} or {@link
|
* Capabilities#CAPABILITY_NOT_SUPPORTED} or {@link
|
||||||
* TimeZoneCapabilities#CAPABILITY_NOT_ALLOWED} will have no effect and a {@code false}
|
* Capabilities#CAPABILITY_NOT_ALLOWED} will have no effect and a {@code false}
|
||||||
* will be returned. Modifying configuration settings with capabilities that are {@link
|
* will be returned. Modifying configuration settings with capabilities that are {@link
|
||||||
* TimeZoneCapabilities#CAPABILITY_NOT_APPLICABLE} or {@link
|
* Capabilities#CAPABILITY_NOT_APPLICABLE} or {@link
|
||||||
* TimeZoneCapabilities#CAPABILITY_POSSESSED} will succeed. See {@link
|
* Capabilities#CAPABILITY_POSSESSED} will succeed. See {@link
|
||||||
* TimeZoneCapabilities} for further details.
|
* TimeZoneCapabilities} for further details.
|
||||||
*
|
*
|
||||||
* <p>If the supplied configuration only has some values set, then only the specified settings
|
* <p>If the supplied configuration only has some values set, then only the specified settings
|
||||||
|
|||||||
@@ -16,77 +16,33 @@
|
|||||||
|
|
||||||
package android.app.time;
|
package android.app.time;
|
||||||
|
|
||||||
import android.annotation.IntDef;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.annotation.SystemApi;
|
import android.annotation.SystemApi;
|
||||||
|
import android.app.time.Capabilities.CapabilityState;
|
||||||
import android.app.timezonedetector.ManualTimeZoneSuggestion;
|
import android.app.timezonedetector.ManualTimeZoneSuggestion;
|
||||||
import android.app.timezonedetector.TimeZoneDetector;
|
import android.app.timezonedetector.TimeZoneDetector;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time zone-related capabilities for a user. A capability is the ability for the user to configure
|
* Time zone-related capabilities for a user.
|
||||||
* something or perform an action. This information is exposed so that system apps like SettingsUI
|
|
||||||
* can be dynamic, rather than hard-coding knowledge of when configuration or actions are applicable
|
|
||||||
* / available to the user.
|
|
||||||
*
|
|
||||||
* <p>Capabilities have states that users cannot change directly. They may influence some
|
|
||||||
* capabilities indirectly by agreeing to certain device-wide behaviors such as location sharing, or
|
|
||||||
* by changing the configuration. See the {@code CAPABILITY_} constants for details.
|
|
||||||
*
|
|
||||||
* <p>Actions have associated methods, see the documentation for each action for details.
|
|
||||||
*
|
*
|
||||||
* <p>For configuration settings capabilities, the associated settings value can be found via
|
* <p>For configuration settings capabilities, the associated settings value can be found via
|
||||||
* {@link TimeManager#getTimeZoneCapabilitiesAndConfig()} and may be changed using {@link
|
* {@link TimeManager#getTimeZoneCapabilitiesAndConfig()} and may be changed using {@link
|
||||||
* TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)} (if the user's capabilities
|
* TimeManager#updateTimeZoneConfiguration(TimeZoneConfiguration)} (if the user's capabilities
|
||||||
* allow).
|
* allow).
|
||||||
*
|
*
|
||||||
* <p>Note: Capabilities are independent of app permissions required to call the associated APIs.
|
|
||||||
*
|
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@SystemApi
|
@SystemApi
|
||||||
public final class TimeZoneCapabilities implements Parcelable {
|
public final class TimeZoneCapabilities implements Parcelable {
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
@IntDef({ CAPABILITY_NOT_SUPPORTED, CAPABILITY_NOT_ALLOWED, CAPABILITY_NOT_APPLICABLE,
|
|
||||||
CAPABILITY_POSSESSED })
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
public @interface CapabilityState {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that a capability is not supported on this device, e.g. because of form factor or
|
|
||||||
* hardware. The associated UI should usually not be shown to the user.
|
|
||||||
*/
|
|
||||||
public static final int CAPABILITY_NOT_SUPPORTED = 10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that a capability is supported on this device, but not allowed for the user, e.g.
|
|
||||||
* if the capability relates to the ability to modify settings the user is not able to.
|
|
||||||
* This could be because of the user's type (e.g. maybe it applies to the primary user only) or
|
|
||||||
* device policy. Depending on the capability, this could mean the associated UI
|
|
||||||
* should be hidden, or displayed but disabled.
|
|
||||||
*/
|
|
||||||
public static final int CAPABILITY_NOT_ALLOWED = 20;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that a capability is possessed but not currently applicable, e.g. if the
|
|
||||||
* capability relates to the ability to modify settings, the user has the ability to modify
|
|
||||||
* it, but it is currently rendered irrelevant by other settings or other device state (flags,
|
|
||||||
* resource config, etc.). The associated UI may be hidden, disabled, or left visible (but
|
|
||||||
* ineffective) depending on requirements.
|
|
||||||
*/
|
|
||||||
public static final int CAPABILITY_NOT_APPLICABLE = 30;
|
|
||||||
|
|
||||||
/** Indicates that a capability is possessed by the user. */
|
|
||||||
public static final int CAPABILITY_POSSESSED = 40;
|
|
||||||
|
|
||||||
public static final @NonNull Creator<TimeZoneCapabilities> CREATOR =
|
public static final @NonNull Creator<TimeZoneCapabilities> CREATOR =
|
||||||
new Creator<TimeZoneCapabilities>() {
|
new Creator<TimeZoneCapabilities>() {
|
||||||
public TimeZoneCapabilities createFromParcel(Parcel in) {
|
public TimeZoneCapabilities createFromParcel(Parcel in) {
|
||||||
@@ -159,7 +115,8 @@ public final class TimeZoneCapabilities implements Parcelable {
|
|||||||
* on a device via {@link TimeZoneDetector#suggestManualTimeZone(ManualTimeZoneSuggestion)}.
|
* on a device via {@link TimeZoneDetector#suggestManualTimeZone(ManualTimeZoneSuggestion)}.
|
||||||
*
|
*
|
||||||
* <p>The suggestion will be ignored in all cases unless the value is {@link
|
* <p>The suggestion will be ignored in all cases unless the value is {@link
|
||||||
* #CAPABILITY_POSSESSED}. See also {@link TimeZoneConfiguration#isAutoDetectionEnabled()}.
|
* Capabilities#CAPABILITY_POSSESSED}. See also
|
||||||
|
* {@link TimeZoneConfiguration#isAutoDetectionEnabled()}.
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public final class TimeZoneCapabilitiesAndConfig implements Parcelable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TimeZoneDetectorCapabilitiesAndConfig{"
|
return "TimeZoneCapabilitiesAndConfig{"
|
||||||
+ "mCapabilities=" + mCapabilities
|
+ "mCapabilities=" + mCapabilities
|
||||||
+ ", mConfiguration=" + mConfiguration
|
+ ", mConfiguration=" + mConfiguration
|
||||||
+ '}';
|
+ '}';
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package android.app.timedetector;
|
package android.app.timedetector;
|
||||||
|
|
||||||
import android.app.time.ExternalTimeSuggestion;
|
import android.app.time.ExternalTimeSuggestion;
|
||||||
|
import android.app.time.TimeCapabilitiesAndConfig;
|
||||||
|
import android.app.time.TimeConfiguration;
|
||||||
import android.app.timedetector.GnssTimeSuggestion;
|
import android.app.timedetector.GnssTimeSuggestion;
|
||||||
import android.app.timedetector.ManualTimeSuggestion;
|
import android.app.timedetector.ManualTimeSuggestion;
|
||||||
import android.app.timedetector.NetworkTimeSuggestion;
|
import android.app.timedetector.NetworkTimeSuggestion;
|
||||||
@@ -36,6 +38,9 @@ import android.app.timedetector.TelephonyTimeSuggestion;
|
|||||||
* {@hide}
|
* {@hide}
|
||||||
*/
|
*/
|
||||||
interface ITimeDetectorService {
|
interface ITimeDetectorService {
|
||||||
|
TimeCapabilitiesAndConfig getCapabilitiesAndConfig();
|
||||||
|
boolean updateConfiguration(in TimeConfiguration timeConfiguration);
|
||||||
|
|
||||||
void suggestExternalTime( in ExternalTimeSuggestion timeSuggestion);
|
void suggestExternalTime( in ExternalTimeSuggestion timeSuggestion);
|
||||||
void suggestGnssTime(in GnssTimeSuggestion timeSuggestion);
|
void suggestGnssTime(in GnssTimeSuggestion timeSuggestion);
|
||||||
boolean suggestManualTime(in ManualTimeSuggestion timeSuggestion);
|
boolean suggestManualTime(in ManualTimeSuggestion timeSuggestion);
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
|
||||||
|
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||||
|
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
|
||||||
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
|
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class TimeCapabilitiesTest {
|
||||||
|
|
||||||
|
private static final UserHandle USER_HANDLE = UserHandle.of(332211);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilder() {
|
||||||
|
TimeCapabilities capabilities = new TimeCapabilities.Builder(USER_HANDLE)
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_NOT_APPLICABLE)
|
||||||
|
.setSuggestTimeManuallyCapability(CAPABILITY_NOT_SUPPORTED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(capabilities.getConfigureAutoTimeDetectionEnabledCapability())
|
||||||
|
.isEqualTo(CAPABILITY_NOT_APPLICABLE);
|
||||||
|
assertThat(capabilities.getSuggestTimeManuallyCapability())
|
||||||
|
.isEqualTo(CAPABILITY_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
try {
|
||||||
|
new TimeCapabilities.Builder(USER_HANDLE)
|
||||||
|
.build();
|
||||||
|
fail("Should throw IllegalStateException");
|
||||||
|
} catch (IllegalStateException ignored) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new TimeCapabilities.Builder(USER_HANDLE)
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_NOT_APPLICABLE)
|
||||||
|
.build();
|
||||||
|
fail("Should throw IllegalStateException");
|
||||||
|
} catch (IllegalStateException ignored) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new TimeCapabilities.Builder(USER_HANDLE)
|
||||||
|
.setSuggestTimeManuallyCapability(CAPABILITY_NOT_APPLICABLE)
|
||||||
|
.build();
|
||||||
|
fail("Should throw IllegalStateException");
|
||||||
|
} catch (IllegalStateException ignored) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void userHandle_notIgnoredInEquals() {
|
||||||
|
TimeCapabilities firstUserCapabilities = new TimeCapabilities.Builder(UserHandle.of(1))
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_POSSESSED)
|
||||||
|
.setSuggestTimeManuallyCapability(CAPABILITY_POSSESSED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TimeCapabilities secondUserCapabilities = new TimeCapabilities.Builder(UserHandle.of(2))
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_POSSESSED)
|
||||||
|
.setSuggestTimeManuallyCapability(CAPABILITY_POSSESSED)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(firstUserCapabilities).isNotEqualTo(secondUserCapabilities);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParcelable() {
|
||||||
|
TimeCapabilities.Builder builder = new TimeCapabilities.Builder(USER_HANDLE)
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_NOT_SUPPORTED)
|
||||||
|
.setSuggestTimeManuallyCapability(CAPABILITY_NOT_SUPPORTED);
|
||||||
|
|
||||||
|
assertRoundTripParcelable(builder.build());
|
||||||
|
|
||||||
|
builder.setSuggestTimeManuallyCapability(CAPABILITY_POSSESSED);
|
||||||
|
assertRoundTripParcelable(builder.build());
|
||||||
|
|
||||||
|
builder.setConfigureAutoTimeDetectionEnabledCapability(CAPABILITY_POSSESSED);
|
||||||
|
assertRoundTripParcelable(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.app.time;
|
||||||
|
|
||||||
|
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest;
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
@SmallTest
|
||||||
|
public class TimeConfigurationTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuilder() {
|
||||||
|
TimeConfiguration first = new TimeConfiguration.Builder()
|
||||||
|
.setAutoDetectionEnabled(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(first.isAutoDetectionEnabled()).isTrue();
|
||||||
|
|
||||||
|
TimeConfiguration copyFromBuilderConfiguration = new TimeConfiguration.Builder(first)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(first).isEqualTo(copyFromBuilderConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParcelable() {
|
||||||
|
TimeConfiguration.Builder builder = new TimeConfiguration.Builder();
|
||||||
|
|
||||||
|
assertRoundTripParcelable(builder.setAutoDetectionEnabled(true).build());
|
||||||
|
|
||||||
|
assertRoundTripParcelable(builder.setAutoDetectionEnabled(false).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package android.app.time;
|
package android.app.time;
|
||||||
|
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.server.timedetector;
|
||||||
|
|
||||||
|
import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
|
||||||
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
|
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
|
import android.app.time.Capabilities.CapabilityState;
|
||||||
|
import android.app.time.TimeCapabilities;
|
||||||
|
import android.app.time.TimeCapabilitiesAndConfig;
|
||||||
|
import android.app.time.TimeConfiguration;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds configuration values that affect time behaviour.
|
||||||
|
*/
|
||||||
|
public final class ConfigurationInternal {
|
||||||
|
|
||||||
|
private final @UserIdInt int mUserId;
|
||||||
|
private final boolean mUserConfigAllowed;
|
||||||
|
private final boolean mAutoDetectionEnabled;
|
||||||
|
|
||||||
|
private ConfigurationInternal(Builder builder) {
|
||||||
|
mUserId = builder.mUserId;
|
||||||
|
mUserConfigAllowed = builder.mUserConfigAllowed;
|
||||||
|
mAutoDetectionEnabled = builder.mAutoDetectionEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a {@link TimeCapabilitiesAndConfig} objects based on configuration values. */
|
||||||
|
public TimeCapabilitiesAndConfig capabilitiesAndConfig() {
|
||||||
|
return new TimeCapabilitiesAndConfig(timeCapabilities(), timeConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeConfiguration timeConfiguration() {
|
||||||
|
return new TimeConfiguration.Builder()
|
||||||
|
.setAutoDetectionEnabled(mAutoDetectionEnabled)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeCapabilities timeCapabilities() {
|
||||||
|
@CapabilityState int configureAutoTimeDetectionEnabledCapability =
|
||||||
|
mUserConfigAllowed
|
||||||
|
? CAPABILITY_POSSESSED
|
||||||
|
: CAPABILITY_NOT_ALLOWED;
|
||||||
|
|
||||||
|
@CapabilityState int suggestTimeManuallyCapability =
|
||||||
|
mUserConfigAllowed
|
||||||
|
? CAPABILITY_POSSESSED
|
||||||
|
: CAPABILITY_NOT_ALLOWED;
|
||||||
|
|
||||||
|
return new TimeCapabilities.Builder(UserHandle.of(mUserId))
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(
|
||||||
|
configureAutoTimeDetectionEnabledCapability)
|
||||||
|
.setSuggestTimeManuallyCapability(suggestTimeManuallyCapability)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
ConfigurationInternal that = (ConfigurationInternal) o;
|
||||||
|
return mUserId == that.mUserId
|
||||||
|
&& mUserConfigAllowed == that.mUserConfigAllowed
|
||||||
|
&& mAutoDetectionEnabled == that.mAutoDetectionEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(mUserId, mUserConfigAllowed, mAutoDetectionEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ConfigurationInternal{"
|
||||||
|
+ "mUserId=" + mUserId
|
||||||
|
+ ", mUserConfigAllowed=" + mUserConfigAllowed
|
||||||
|
+ ", mAutoDetectionEnabled=" + mAutoDetectionEnabled
|
||||||
|
+ '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class Builder {
|
||||||
|
private final @UserIdInt int mUserId;
|
||||||
|
private boolean mUserConfigAllowed;
|
||||||
|
private boolean mAutoDetectionEnabled;
|
||||||
|
|
||||||
|
Builder(@UserIdInt int userId) {
|
||||||
|
mUserId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setUserConfigAllowed(boolean userConfigAllowed) {
|
||||||
|
mUserConfigAllowed = userConfigAllowed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder setAutoDetectionEnabled(boolean autoDetectionEnabled) {
|
||||||
|
mAutoDetectionEnabled = autoDetectionEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationInternal build() {
|
||||||
|
return new ConfigurationInternal(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import static com.android.server.timedetector.TimeDetectorStrategy.ORIGIN_TELEPH
|
|||||||
import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
|
import static com.android.server.timedetector.TimeDetectorStrategy.stringToOrigin;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -28,6 +29,8 @@ import android.os.Build;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
@@ -71,6 +74,7 @@ public final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environme
|
|||||||
@NonNull private final ContentResolver mContentResolver;
|
@NonNull private final ContentResolver mContentResolver;
|
||||||
@NonNull private final PowerManager.WakeLock mWakeLock;
|
@NonNull private final PowerManager.WakeLock mWakeLock;
|
||||||
@NonNull private final AlarmManager mAlarmManager;
|
@NonNull private final AlarmManager mAlarmManager;
|
||||||
|
@NonNull private final UserManager mUserManager;
|
||||||
@NonNull private final int[] mOriginPriorities;
|
@NonNull private final int[] mOriginPriorities;
|
||||||
|
|
||||||
public EnvironmentImpl(@NonNull Context context) {
|
public EnvironmentImpl(@NonNull Context context) {
|
||||||
@@ -83,6 +87,8 @@ public final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environme
|
|||||||
|
|
||||||
mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class));
|
mAlarmManager = Objects.requireNonNull(context.getSystemService(AlarmManager.class));
|
||||||
|
|
||||||
|
mUserManager = Objects.requireNonNull(context.getSystemService(UserManager.class));
|
||||||
|
|
||||||
mSystemClockUpdateThresholdMillis =
|
mSystemClockUpdateThresholdMillis =
|
||||||
SystemProperties.getInt("ro.sys.time_detector_update_diff",
|
SystemProperties.getInt("ro.sys.time_detector_update_diff",
|
||||||
SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
|
SYSTEM_CLOCK_UPDATE_THRESHOLD_MILLIS_DEFAULT);
|
||||||
@@ -114,6 +120,14 @@ public final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environme
|
|||||||
return mOriginPriorities;
|
return mOriginPriorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationInternal configurationInternal(@UserIdInt int userId) {
|
||||||
|
return new ConfigurationInternal.Builder(userId)
|
||||||
|
.setUserConfigAllowed(isUserConfigAllowed(userId))
|
||||||
|
.setAutoDetectionEnabled(isAutoTimeDetectionEnabled())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acquireWakeLock() {
|
public void acquireWakeLock() {
|
||||||
if (mWakeLock.isHeld()) {
|
if (mWakeLock.isHeld()) {
|
||||||
@@ -150,6 +164,11 @@ public final class EnvironmentImpl implements TimeDetectorStrategyImpl.Environme
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isUserConfigAllowed(@UserIdInt int userId) {
|
||||||
|
UserHandle userHandle = UserHandle.of(userId);
|
||||||
|
return !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME, userHandle);
|
||||||
|
}
|
||||||
|
|
||||||
private static int[] getOriginPriorities(@NonNull Context context) {
|
private static int[] getOriginPriorities(@NonNull Context context) {
|
||||||
String[] originStrings =
|
String[] originStrings =
|
||||||
context.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
|
context.getResources().getStringArray(R.array.config_autoTimeSourcesPriority);
|
||||||
|
|||||||
@@ -18,7 +18,10 @@ package com.android.server.timedetector;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.time.ExternalTimeSuggestion;
|
import android.app.time.ExternalTimeSuggestion;
|
||||||
|
import android.app.time.TimeCapabilitiesAndConfig;
|
||||||
|
import android.app.time.TimeConfiguration;
|
||||||
import android.app.timedetector.GnssTimeSuggestion;
|
import android.app.timedetector.GnssTimeSuggestion;
|
||||||
import android.app.timedetector.ITimeDetectorService;
|
import android.app.timedetector.ITimeDetectorService;
|
||||||
import android.app.timedetector.ManualTimeSuggestion;
|
import android.app.timedetector.ManualTimeSuggestion;
|
||||||
@@ -36,6 +39,7 @@ import com.android.internal.annotations.VisibleForTesting;
|
|||||||
import com.android.internal.util.DumpUtils;
|
import com.android.internal.util.DumpUtils;
|
||||||
import com.android.server.FgThread;
|
import com.android.server.FgThread;
|
||||||
import com.android.server.SystemService;
|
import com.android.server.SystemService;
|
||||||
|
import com.android.server.timezonedetector.CallerIdentityInjector;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -71,6 +75,7 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
|
|||||||
@NonNull private final Handler mHandler;
|
@NonNull private final Handler mHandler;
|
||||||
@NonNull private final Context mContext;
|
@NonNull private final Context mContext;
|
||||||
@NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
|
@NonNull private final TimeDetectorStrategy mTimeDetectorStrategy;
|
||||||
|
@NonNull private final CallerIdentityInjector mCallerIdentityInjector;
|
||||||
|
|
||||||
private static TimeDetectorService create(@NonNull Context context) {
|
private static TimeDetectorService create(@NonNull Context context) {
|
||||||
TimeDetectorStrategyImpl.Environment environment = new EnvironmentImpl(context);
|
TimeDetectorStrategyImpl.Environment environment = new EnvironmentImpl(context);
|
||||||
@@ -97,9 +102,42 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
|
public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
|
||||||
@NonNull TimeDetectorStrategy timeDetectorStrategy) {
|
@NonNull TimeDetectorStrategy timeDetectorStrategy) {
|
||||||
|
this(context, handler, timeDetectorStrategy, CallerIdentityInjector.REAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public TimeDetectorService(@NonNull Context context, @NonNull Handler handler,
|
||||||
|
@NonNull TimeDetectorStrategy timeDetectorStrategy,
|
||||||
|
@NonNull CallerIdentityInjector callerIdentityInjector) {
|
||||||
mContext = Objects.requireNonNull(context);
|
mContext = Objects.requireNonNull(context);
|
||||||
mHandler = Objects.requireNonNull(handler);
|
mHandler = Objects.requireNonNull(handler);
|
||||||
mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
|
mTimeDetectorStrategy = Objects.requireNonNull(timeDetectorStrategy);
|
||||||
|
mCallerIdentityInjector = Objects.requireNonNull(callerIdentityInjector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeCapabilitiesAndConfig getCapabilitiesAndConfig() {
|
||||||
|
int userId = mCallerIdentityInjector.getCallingUserId();
|
||||||
|
return getTimeCapabilitiesAndConfig(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeCapabilitiesAndConfig getTimeCapabilitiesAndConfig(@UserIdInt int userId) {
|
||||||
|
enforceManageTimeDetectorPermission();
|
||||||
|
|
||||||
|
final long token = mCallerIdentityInjector.clearCallingIdentity();
|
||||||
|
try {
|
||||||
|
ConfigurationInternal configurationInternal =
|
||||||
|
mTimeDetectorStrategy.getConfigurationInternal(userId);
|
||||||
|
return configurationInternal.capabilitiesAndConfig();
|
||||||
|
} finally {
|
||||||
|
mCallerIdentityInjector.restoreCallingIdentity(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateConfiguration(TimeConfiguration timeConfiguration) {
|
||||||
|
// TODO(b/172891783) Add actual logic
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -193,4 +231,11 @@ public final class TimeDetectorService extends ITimeDetectorService.Stub {
|
|||||||
android.Manifest.permission.SET_TIME,
|
android.Manifest.permission.SET_TIME,
|
||||||
"suggest time from external source");
|
"suggest time from external source");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void enforceManageTimeDetectorPermission() {
|
||||||
|
mContext.enforceCallingPermission(
|
||||||
|
android.Manifest.permission.MANAGE_TIME_AND_ZONE_DETECTION,
|
||||||
|
"manage time and time zone detection");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.server.timedetector;
|
|||||||
|
|
||||||
import android.annotation.IntDef;
|
import android.annotation.IntDef;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.time.ExternalTimeSuggestion;
|
import android.app.time.ExternalTimeSuggestion;
|
||||||
import android.app.timedetector.GnssTimeSuggestion;
|
import android.app.timedetector.GnssTimeSuggestion;
|
||||||
import android.app.timedetector.ManualTimeSuggestion;
|
import android.app.timedetector.ManualTimeSuggestion;
|
||||||
@@ -88,6 +89,9 @@ public interface TimeDetectorStrategy extends Dumpable {
|
|||||||
/** Processes the suggested time from external sources. */
|
/** Processes the suggested time from external sources. */
|
||||||
void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion);
|
void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion);
|
||||||
|
|
||||||
|
/** Returns the configuration that controls time detector behaviour for specified user. */
|
||||||
|
ConfigurationInternal getConfigurationInternal(@UserIdInt int userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the auto-time configuration changing For example, when the auto-time setting is
|
* Handles the auto-time configuration changing For example, when the auto-time setting is
|
||||||
* toggled on or off.
|
* toggled on or off.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import static java.util.stream.Collectors.joining;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.annotation.UserIdInt;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.time.ExternalTimeSuggestion;
|
import android.app.time.ExternalTimeSuggestion;
|
||||||
import android.app.timedetector.GnssTimeSuggestion;
|
import android.app.timedetector.GnssTimeSuggestion;
|
||||||
@@ -155,6 +156,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
|||||||
*/
|
*/
|
||||||
@Origin int[] autoOriginPriorities();
|
@Origin int[] autoOriginPriorities();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@link ConfigurationInternal} for specified user.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
ConfigurationInternal configurationInternal(@UserIdInt int userId);
|
||||||
|
|
||||||
/** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */
|
/** Acquire a suitable wake lock. Must be followed by {@link #releaseWakeLock()} */
|
||||||
void acquireWakeLock();
|
void acquireWakeLock();
|
||||||
|
|
||||||
@@ -266,6 +273,12 @@ public final class TimeDetectorStrategyImpl implements TimeDetectorStrategy {
|
|||||||
doAutoTimeDetection(reason);
|
doAutoTimeDetection(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public ConfigurationInternal getConfigurationInternal(@UserIdInt int userId) {
|
||||||
|
return mEnvironment.configurationInternal(userId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized void handleAutoTimeConfigChanged() {
|
public synchronized void handleAutoTimeConfigChanged() {
|
||||||
boolean enabled = mEnvironment.isAutoTimeDetectionEnabled();
|
boolean enabled = mEnvironment.isAutoTimeDetectionEnabled();
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.server.timezonedetector;
|
package com.android.server.timezonedetector;
|
||||||
|
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.UserIdInt;
|
import android.annotation.UserIdInt;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.server.timezonedetector;
|
package com.android.server.timezonedetector;
|
||||||
|
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
|
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_EMULATOR_ZONE_ID;
|
||||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
|
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
|
||||||
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
|
import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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.server.timedetector;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import android.app.time.Capabilities;
|
||||||
|
import android.app.time.TimeCapabilities;
|
||||||
|
import android.app.time.TimeCapabilitiesAndConfig;
|
||||||
|
import android.app.time.TimeConfiguration;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
|
||||||
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ConfigurationInternalTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void capabilitiesAndConfig() {
|
||||||
|
int userId = 112233;
|
||||||
|
ConfigurationInternal configurationInternal = new ConfigurationInternal.Builder(userId)
|
||||||
|
.setAutoDetectionEnabled(true)
|
||||||
|
.setUserConfigAllowed(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TimeCapabilities timeCapabilities = new TimeCapabilities.Builder(UserHandle.of(userId))
|
||||||
|
.setConfigureAutoTimeDetectionEnabledCapability(Capabilities.CAPABILITY_POSSESSED)
|
||||||
|
.setSuggestTimeManuallyCapability(Capabilities.CAPABILITY_POSSESSED)
|
||||||
|
.build();
|
||||||
|
TimeConfiguration timeConfiguration = new TimeConfiguration.Builder()
|
||||||
|
.setAutoDetectionEnabled(true)
|
||||||
|
.build();
|
||||||
|
TimeCapabilitiesAndConfig expected =
|
||||||
|
new TimeCapabilitiesAndConfig(timeCapabilities, timeConfiguration);
|
||||||
|
|
||||||
|
assertThat(configurationInternal.capabilitiesAndConfig()).isEqualTo(expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -327,6 +327,11 @@ public class TimeDetectorServiceTest {
|
|||||||
mLastExternalSuggestion = timeSuggestion;
|
mLastExternalSuggestion = timeSuggestion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationInternal getConfigurationInternal(int userId) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleAutoTimeConfigChanged() {
|
public void handleAutoTimeConfigChanged() {
|
||||||
mHandleAutoTimeDetectionChangedCalled = true;
|
mHandleAutoTimeDetectionChangedCalled = true;
|
||||||
|
|||||||
@@ -1157,6 +1157,11 @@ public class TimeDetectorStrategyImplTest {
|
|||||||
return mAutoOriginPriorities;
|
return mAutoOriginPriorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationInternal configurationInternal(int userId) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acquireWakeLock() {
|
public void acquireWakeLock() {
|
||||||
if (mWakeLockAcquired) {
|
if (mWakeLockAcquired) {
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.android.server.timezonedetector;
|
package com.android.server.timezonedetector;
|
||||||
|
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_ALLOWED;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_ALLOWED;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_APPLICABLE;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_APPLICABLE;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_NOT_SUPPORTED;
|
import static android.app.time.Capabilities.CAPABILITY_NOT_SUPPORTED;
|
||||||
import static android.app.time.TimeZoneCapabilities.CAPABILITY_POSSESSED;
|
import static android.app.time.Capabilities.CAPABILITY_POSSESSED;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|||||||
Reference in New Issue
Block a user