Merge "Clean-up after TZUvA feature removal." am: 06b9abf013
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2300422 Change-Id: I1d9b114c135f7e3c80613ae1f7b32346cd0b258f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -238,7 +238,7 @@ package android {
|
||||
field public static final String PROVIDE_TRUST_AGENT = "android.permission.PROVIDE_TRUST_AGENT";
|
||||
field public static final String PROVISION_DEMO_DEVICE = "android.permission.PROVISION_DEMO_DEVICE";
|
||||
field public static final String QUERY_ADMIN_POLICY = "android.permission.QUERY_ADMIN_POLICY";
|
||||
field public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
|
||||
field @Deprecated public static final String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
|
||||
field public static final String QUERY_USERS = "android.permission.QUERY_USERS";
|
||||
field public static final String RADIO_SCAN_WITHOUT_LOCATION = "android.permission.RADIO_SCAN_WITHOUT_LOCATION";
|
||||
field public static final String READ_ACTIVE_EMERGENCY_SESSION = "android.permission.READ_ACTIVE_EMERGENCY_SESSION";
|
||||
@@ -340,7 +340,7 @@ package android {
|
||||
field public static final String UPDATE_DOMAIN_VERIFICATION_USER_SELECTION = "android.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION";
|
||||
field public static final String UPDATE_FONTS = "android.permission.UPDATE_FONTS";
|
||||
field public static final String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
|
||||
field public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
|
||||
field @Deprecated public static final String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
|
||||
field public static final String UPGRADE_RUNTIME_PERMISSIONS = "android.permission.UPGRADE_RUNTIME_PERMISSIONS";
|
||||
field public static final String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
|
||||
field public static final String USE_COLORIZED_NOTIFICATIONS = "android.permission.USE_COLORIZED_NOTIFICATIONS";
|
||||
|
||||
@@ -42,7 +42,6 @@ import android.app.smartspace.SmartspaceManager;
|
||||
import android.app.time.TimeManager;
|
||||
import android.app.timedetector.TimeDetector;
|
||||
import android.app.timedetector.TimeDetectorImpl;
|
||||
import android.app.timezone.RulesManager;
|
||||
import android.app.timezonedetector.TimeZoneDetector;
|
||||
import android.app.timezonedetector.TimeZoneDetectorImpl;
|
||||
import android.app.trust.TrustManager;
|
||||
@@ -1254,13 +1253,6 @@ public final class SystemServiceRegistry {
|
||||
}
|
||||
});
|
||||
|
||||
registerService(Context.TIME_ZONE_RULES_MANAGER_SERVICE, RulesManager.class,
|
||||
new CachedServiceFetcher<RulesManager>() {
|
||||
@Override
|
||||
public RulesManager createService(ContextImpl ctx) {
|
||||
return new RulesManager(ctx.getOuterContext());
|
||||
}});
|
||||
|
||||
registerService(Context.CROSS_PROFILE_APPS_SERVICE, CrossProfileApps.class,
|
||||
new CachedServiceFetcher<CrossProfileApps>() {
|
||||
@Override
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Callback interface for receiving information about an async time zone operation.
|
||||
* The methods will be called on your application's main thread.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class Callback {
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "SUCCESS", "ERROR_" }, value = {
|
||||
SUCCESS,
|
||||
ERROR_UNKNOWN_FAILURE,
|
||||
ERROR_INSTALL_BAD_DISTRO_STRUCTURE,
|
||||
ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION,
|
||||
ERROR_INSTALL_RULES_TOO_OLD,
|
||||
ERROR_INSTALL_VALIDATION_ERROR
|
||||
})
|
||||
public @interface AsyncResultCode {}
|
||||
|
||||
/**
|
||||
* Indicates that an operation succeeded.
|
||||
*/
|
||||
public static final int SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Indicates an install / uninstall did not fully succeed for an unknown reason.
|
||||
*/
|
||||
public static final int ERROR_UNKNOWN_FAILURE = 1;
|
||||
|
||||
/**
|
||||
* Indicates an install failed because of a structural issue with the provided distro,
|
||||
* e.g. it wasn't in the right format or the contents were structured incorrectly.
|
||||
*/
|
||||
public static final int ERROR_INSTALL_BAD_DISTRO_STRUCTURE = 2;
|
||||
|
||||
/**
|
||||
* Indicates an install failed because of a versioning issue with the provided distro,
|
||||
* e.g. it was created for a different version of Android.
|
||||
*/
|
||||
public static final int ERROR_INSTALL_BAD_DISTRO_FORMAT_VERSION = 3;
|
||||
|
||||
/**
|
||||
* Indicates an install failed because the rules provided are too old for the device,
|
||||
* e.g. the Android device shipped with a newer rules version.
|
||||
*/
|
||||
public static final int ERROR_INSTALL_RULES_TOO_OLD = 4;
|
||||
|
||||
/**
|
||||
* Indicates an install failed because the distro contents failed validation.
|
||||
*/
|
||||
public static final int ERROR_INSTALL_VALIDATION_ERROR = 5;
|
||||
|
||||
/**
|
||||
* Reports the result of an async time zone operation.
|
||||
*/
|
||||
public abstract void onFinished(@AsyncResultCode int status);
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Versioning information about a distro's format or a device's supported format.
|
||||
*
|
||||
* <p>The following properties are included:
|
||||
* <dl>
|
||||
* <dt>majorVersion</dt>
|
||||
* <dd>the major distro format version. Major versions differences are not compatible - e.g.
|
||||
* 2 is not compatible with 1 or 3.</dd>
|
||||
* <dt>minorVersion</dt>
|
||||
* <dd>the minor distro format version. Minor versions should be backwards compatible iff the
|
||||
* major versions match exactly, i.e. version 2.2 will be compatible with 2.1 devices but not
|
||||
* 2.3 devices.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class DistroFormatVersion implements Parcelable {
|
||||
|
||||
private final int mMajorVersion;
|
||||
private final int mMinorVersion;
|
||||
|
||||
public DistroFormatVersion(int majorVersion, int minorVersion) {
|
||||
mMajorVersion = Utils.validateVersion("major", majorVersion);
|
||||
mMinorVersion = Utils.validateVersion("minor", minorVersion);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<DistroFormatVersion> CREATOR = new Creator<DistroFormatVersion>() {
|
||||
public DistroFormatVersion createFromParcel(Parcel in) {
|
||||
int majorVersion = in.readInt();
|
||||
int minorVersion = in.readInt();
|
||||
return new DistroFormatVersion(majorVersion, minorVersion);
|
||||
}
|
||||
|
||||
public DistroFormatVersion[] newArray(int size) {
|
||||
return new DistroFormatVersion[size];
|
||||
}
|
||||
};
|
||||
|
||||
public int getMajorVersion() {
|
||||
return mMajorVersion;
|
||||
}
|
||||
|
||||
public int getMinorVersion() {
|
||||
return mMinorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeInt(mMajorVersion);
|
||||
out.writeInt(mMinorVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this object describes a device's supported version and the parameter describes a distro's
|
||||
* version, this method returns whether the device would accept the distro.
|
||||
*/
|
||||
public boolean supports(DistroFormatVersion distroFormatVersion) {
|
||||
return mMajorVersion == distroFormatVersion.mMajorVersion
|
||||
&& mMinorVersion <= distroFormatVersion.mMinorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DistroFormatVersion that = (DistroFormatVersion) o;
|
||||
|
||||
if (mMajorVersion != that.mMajorVersion) {
|
||||
return false;
|
||||
}
|
||||
return mMinorVersion == that.mMinorVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = mMajorVersion;
|
||||
result = 31 * result + mMinorVersion;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DistroFormatVersion{"
|
||||
+ "mMajorVersion=" + mMajorVersion
|
||||
+ ", mMinorVersion=" + mMinorVersion
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static android.app.timezone.Utils.validateRulesVersion;
|
||||
import static android.app.timezone.Utils.validateVersion;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Versioning information about a set of time zone rules.
|
||||
*
|
||||
* <p>The following properties are included:
|
||||
* <dl>
|
||||
* <dt>rulesVersion</dt>
|
||||
* <dd>the IANA rules version. e.g. "2017a"</dd>
|
||||
* <dt>revision</dt>
|
||||
* <dd>the revision for the rules. Allows there to be several revisions for a given IANA rules
|
||||
* release. Numerically higher is newer.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class DistroRulesVersion implements Parcelable {
|
||||
|
||||
private final String mRulesVersion;
|
||||
private final int mRevision;
|
||||
|
||||
public DistroRulesVersion(String rulesVersion, int revision) {
|
||||
mRulesVersion = validateRulesVersion("rulesVersion", rulesVersion);
|
||||
mRevision = validateVersion("revision", revision);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Creator<DistroRulesVersion> CREATOR = new Creator<DistroRulesVersion>() {
|
||||
public DistroRulesVersion createFromParcel(Parcel in) {
|
||||
String rulesVersion = in.readString();
|
||||
int revision = in.readInt();
|
||||
return new DistroRulesVersion(rulesVersion, revision);
|
||||
}
|
||||
|
||||
public DistroRulesVersion[] newArray(int size) {
|
||||
return new DistroRulesVersion[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getRulesVersion() {
|
||||
return mRulesVersion;
|
||||
}
|
||||
|
||||
public int getRevision() {
|
||||
return mRevision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this DistroRulesVersion is older than the one supplied. It returns false if
|
||||
* it is the same or newer. This method compares the {@code rulesVersion} and the
|
||||
* {@code revision}.
|
||||
*/
|
||||
public boolean isOlderThan(DistroRulesVersion distroRulesVersion) {
|
||||
int rulesComparison = mRulesVersion.compareTo(distroRulesVersion.mRulesVersion);
|
||||
if (rulesComparison < 0) {
|
||||
return true;
|
||||
}
|
||||
if (rulesComparison > 0) {
|
||||
return false;
|
||||
}
|
||||
return mRevision < distroRulesVersion.mRevision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mRulesVersion);
|
||||
out.writeInt(mRevision);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DistroRulesVersion that = (DistroRulesVersion) o;
|
||||
|
||||
if (mRevision != that.mRevision) {
|
||||
return false;
|
||||
}
|
||||
return mRulesVersion.equals(that.mRulesVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = mRulesVersion.hashCode();
|
||||
result = 31 * result + mRevision;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DistroRulesVersion{"
|
||||
+ "mRulesVersion='" + mRulesVersion + '\''
|
||||
+ ", mRevision='" + mRevision + '\''
|
||||
+ '}';
|
||||
}
|
||||
|
||||
public String toDumpString() {
|
||||
return mRulesVersion + "," + mRevision;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
/**
|
||||
* Callback interface for a timezone updater to receive information about the success or failure of
|
||||
* an installation/uninstallation attempt.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
oneway interface ICallback {
|
||||
void onFinished(int error);
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import android.app.timezone.ICallback;
|
||||
import android.app.timezone.RulesState;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
/**
|
||||
* Interface to the TimeZone Rules Manager Service.
|
||||
*
|
||||
* <p>This interface is only intended for system apps to call. They should use the
|
||||
* {@link android.app.timezone.RulesManager} class rather than going through this
|
||||
* Binder interface directly. See {@link android.app.timezone.RulesManager} for more complete
|
||||
* documentation.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
interface IRulesManager {
|
||||
|
||||
/**
|
||||
* Returns information about the current time zone rules state such as the IANA version of
|
||||
* the system and any currently installed distro. This method is intended to allow clients to
|
||||
* determine if the current state can be improved; for example by passing the information to a
|
||||
* server that may provide a new distro for download.
|
||||
*/
|
||||
RulesState getRulesState();
|
||||
|
||||
/**
|
||||
* Requests installation of the supplied distro. The distro must have been checked for integrity
|
||||
* by the caller or have been received via a trusted mechanism.
|
||||
*
|
||||
* @param distroFileDescriptor the file descriptor for the distro
|
||||
* @param checkToken an optional token provided if the install was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param callback the {@link ICallback} to receive callbacks related to the
|
||||
* installation
|
||||
* @return zero if the installation will be attempted; nonzero on error
|
||||
*/
|
||||
int requestInstall(in ParcelFileDescriptor distroFileDescriptor, in byte[] checkToken,
|
||||
ICallback callback);
|
||||
|
||||
/**
|
||||
* Requests uninstallation of the currently installed distro (leaving the device with no
|
||||
* distro installed).
|
||||
*
|
||||
* @param checkToken an optional token provided if the uninstall was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param callback the {@link ICallback} to receive callbacks related to the
|
||||
* uninstall
|
||||
* @return zero if the uninstallation will be attempted; nonzero on error
|
||||
*/
|
||||
int requestUninstall(in byte[] checkToken, ICallback callback);
|
||||
|
||||
/**
|
||||
* Requests the system does not modify the currently installed time zone distro, if any. This
|
||||
* method records the fact that a time zone check operation triggered by the system is now
|
||||
* complete and there was nothing to do. The token passed should be the one presented when the
|
||||
* check was triggered.
|
||||
*
|
||||
* <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
|
||||
* should be careful not to pass false if the failure is unlikely to resolve by itself.
|
||||
*
|
||||
* @param checkToken an optional token provided if the install was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param success true if the check was successful, false if it was not successful but may
|
||||
* succeed if it is retried
|
||||
*/
|
||||
void requestNothing(in byte[] token, boolean success);
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# Bug component: 24949
|
||||
# Internal APIs related to APK-based time zone rule updates.
|
||||
# Deprecated, deletion tracked by b/148144561
|
||||
include /services/core/java/com/android/server/timezone/OWNERS
|
||||
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The interface through which a time zone update application interacts with the Android system
|
||||
* to handle time zone rule updates.
|
||||
*
|
||||
* <p>This interface is intended for use with the default APK-based time zone rules update
|
||||
* application but it can also be used by OEMs if that mechanism is turned off using configuration.
|
||||
* All callers must possess the {@link android.Manifest.permission#UPDATE_TIME_ZONE_RULES} system
|
||||
* permission unless otherwise stated.
|
||||
*
|
||||
* <p>When using the default mechanism, when properly configured the Android system will send a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with a
|
||||
* {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} extra to the time zone rules updater application
|
||||
* when it detects that it or the OEM's APK containing time zone rules data has been modified. The
|
||||
* updater application is then responsible for calling one of
|
||||
* {@link #requestInstall(ParcelFileDescriptor, byte[], Callback)},
|
||||
* {@link #requestUninstall(byte[], Callback)} or
|
||||
* {@link #requestNothing(byte[], boolean)}, indicating, respectively, whether a new time zone rules
|
||||
* distro should be installed, the current distro should be uninstalled, or there is nothing to do
|
||||
* (or that the correct operation could not be determined due to an error). In each case the updater
|
||||
* must pass the {@link RulesUpdaterContract#EXTRA_CHECK_TOKEN} value it received from the intent
|
||||
* back so the system in the {@code checkToken} parameter.
|
||||
*
|
||||
* <p>If OEMs want to handle their own time zone rules updates, perhaps via a server-side component
|
||||
* rather than an APK, then they should disable the default triggering mechanism in config and are
|
||||
* responsible for triggering their own update checks / installs / uninstalls. In this case the
|
||||
* "check token" parameter can be left null and there is never any need to call
|
||||
* {@link #requestNothing(byte[], boolean)}.
|
||||
*
|
||||
* <p>OEMs should not mix the default mechanism and their own as this could lead to conflicts and
|
||||
* unnecessary checks being triggered.
|
||||
*
|
||||
* <p>Applications obtain this using {@link android.app.Activity#getSystemService(String)} with
|
||||
* {@link Context#TIME_ZONE_RULES_MANAGER_SERVICE}.
|
||||
* @hide
|
||||
*/
|
||||
public final class RulesManager {
|
||||
private static final String TAG = "timezone.RulesManager";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* The action of the intent that the Android system will broadcast when a time zone rules update
|
||||
* operation has been successfully staged (i.e. to be applied next reboot) or unstaged.
|
||||
*
|
||||
* <p>See {@link #EXTRA_OPERATION_STAGED}
|
||||
*
|
||||
* <p>This is a protected intent that can only be sent by the system.
|
||||
*/
|
||||
public static final String ACTION_RULES_UPDATE_OPERATION =
|
||||
"com.android.intent.action.timezone.RULES_UPDATE_OPERATION";
|
||||
|
||||
/**
|
||||
* The key for a boolean extra for the {@link #ACTION_RULES_UPDATE_OPERATION} intent used to
|
||||
* indicate whether the operation was a "stage" or an "unstage".
|
||||
*/
|
||||
public static final String EXTRA_OPERATION_STAGED = "staged";
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "SUCCESS", "ERROR_" }, value = {
|
||||
SUCCESS,
|
||||
ERROR_UNKNOWN_FAILURE,
|
||||
ERROR_OPERATION_IN_PROGRESS
|
||||
})
|
||||
public @interface ResultCode {}
|
||||
|
||||
/**
|
||||
* Indicates that an operation succeeded.
|
||||
*/
|
||||
public static final int SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Indicates that an install/uninstall cannot be initiated because there is one already in
|
||||
* progress.
|
||||
*/
|
||||
public static final int ERROR_OPERATION_IN_PROGRESS = 1;
|
||||
|
||||
/**
|
||||
* Indicates an install / uninstall did not fully succeed for an unknown reason.
|
||||
*/
|
||||
public static final int ERROR_UNKNOWN_FAILURE = 2;
|
||||
|
||||
private final Context mContext;
|
||||
private final IRulesManager mIRulesManager;
|
||||
|
||||
public RulesManager(Context context) {
|
||||
mContext = context;
|
||||
mIRulesManager = IRulesManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.TIME_ZONE_RULES_MANAGER_SERVICE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns information about the current time zone rules state such as the IANA version of
|
||||
* the system and any currently installed distro. This method allows clients to determine the
|
||||
* current device state, perhaps to see if it can be improved; for example by passing the
|
||||
* information to a server that may provide a new distro for download.
|
||||
*
|
||||
* <p>Callers must possess the {@link android.Manifest.permission#QUERY_TIME_ZONE_RULES} system
|
||||
* permission.
|
||||
*/
|
||||
public RulesState getRulesState() {
|
||||
try {
|
||||
logDebug("mIRulesManager.getRulesState()");
|
||||
RulesState rulesState = mIRulesManager.getRulesState();
|
||||
logDebug("mIRulesManager.getRulesState() returned " + rulesState);
|
||||
return rulesState;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests installation of the supplied distro. The distro must have been checked for integrity
|
||||
* by the caller or have been received via a trusted mechanism.
|
||||
*
|
||||
* @param distroFileDescriptor the file descriptor for the distro
|
||||
* @param checkToken an optional token provided if the install was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param callback the {@link Callback} to receive callbacks related to the installation
|
||||
* @return {@link #SUCCESS} if the installation will be attempted
|
||||
*/
|
||||
@ResultCode
|
||||
public int requestInstall(
|
||||
ParcelFileDescriptor distroFileDescriptor, byte[] checkToken, Callback callback)
|
||||
throws IOException {
|
||||
|
||||
ICallback iCallback = new CallbackWrapper(mContext, callback);
|
||||
try {
|
||||
logDebug("mIRulesManager.requestInstall()");
|
||||
return mIRulesManager.requestInstall(distroFileDescriptor, checkToken, iCallback);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests uninstallation of the currently installed distro (leaving the device with no
|
||||
* distro installed).
|
||||
*
|
||||
* @param checkToken an optional token provided if the uninstall was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param callback the {@link Callback} to receive callbacks related to the uninstall
|
||||
* @return {@link #SUCCESS} if the uninstallation will be attempted
|
||||
*/
|
||||
@ResultCode
|
||||
public int requestUninstall(byte[] checkToken, Callback callback) {
|
||||
ICallback iCallback = new CallbackWrapper(mContext, callback);
|
||||
try {
|
||||
logDebug("mIRulesManager.requestUninstall()");
|
||||
return mIRulesManager.requestUninstall(checkToken, iCallback);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We wrap incoming binder calls with a private class implementation that
|
||||
* redirects them into main-thread actions. This serializes the backup
|
||||
* progress callbacks nicely within the usual main-thread lifecycle pattern.
|
||||
*/
|
||||
private class CallbackWrapper extends ICallback.Stub {
|
||||
final Handler mHandler;
|
||||
final Callback mCallback;
|
||||
|
||||
CallbackWrapper(Context context, Callback callback) {
|
||||
mCallback = callback;
|
||||
mHandler = new Handler(context.getMainLooper());
|
||||
}
|
||||
|
||||
// Binder calls into this object just enqueue on the main-thread handler
|
||||
@Override
|
||||
public void onFinished(int status) {
|
||||
logDebug("mCallback.onFinished(status), status=" + status);
|
||||
mHandler.post(() -> mCallback.onFinished(status));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests the system does not modify the currently installed time zone distro, if any. This
|
||||
* method records the fact that a time zone check operation triggered by the system is now
|
||||
* complete and there was nothing to do. The token passed should be the one presented when the
|
||||
* check was triggered.
|
||||
*
|
||||
* <p>Note: Passing {@code success == false} may result in more checks being triggered. Clients
|
||||
* should be careful not to pass false if the failure is unlikely to resolve by itself.
|
||||
*
|
||||
* @param checkToken an optional token provided if the install was triggered in response to a
|
||||
* {@link RulesUpdaterContract#ACTION_TRIGGER_RULES_UPDATE_CHECK} intent
|
||||
* @param succeeded true if the check was successful, false if it was not successful but may
|
||||
* succeed if it is retried
|
||||
*/
|
||||
public void requestNothing(byte[] checkToken, boolean succeeded) {
|
||||
try {
|
||||
logDebug("mIRulesManager.requestNothing() with token=" + Arrays.toString(checkToken));
|
||||
mIRulesManager.requestNothing(checkToken, succeeded);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
static void logDebug(String msg) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
parcelable RulesState;
|
||||
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static android.app.timezone.Utils.validateConditionalNull;
|
||||
import static android.app.timezone.Utils.validateNotNull;
|
||||
import static android.app.timezone.Utils.validateRulesVersion;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Description of the state of time zone rules on a device.
|
||||
*
|
||||
* <p>The following properties are included:
|
||||
* <dl>
|
||||
* <dt>baseRulesVersion</dt>
|
||||
* <dd>the IANA rules version that shipped with the OS. Always present. e.g. "2017a".</dd>
|
||||
* <dt>distroFormatVersionSupported</dt>
|
||||
* <dd>the distro format version supported by this device. Always present.</dd>
|
||||
* <dt>operationInProgress</dt>
|
||||
* <dd>{@code true} if there is an install / uninstall operation currently happening.</dd>
|
||||
* <dt>stagedOperationType</dt>
|
||||
* <dd>one of {@link #STAGED_OPERATION_UNKNOWN}, {@link #STAGED_OPERATION_NONE},
|
||||
* {@link #STAGED_OPERATION_UNINSTALL} and {@link #STAGED_OPERATION_INSTALL} indicating whether
|
||||
* there is a currently staged time zone distro operation. {@link #STAGED_OPERATION_UNKNOWN} is
|
||||
* used when {@link #isOperationInProgress()} is {@code true}. Staged operations currently
|
||||
* require a reboot to become active.</dd>
|
||||
* <dt>stagedDistroRulesVersion</dt>
|
||||
* <dd>[present if distroStagedState == STAGED_STATE_INSTALL], the rules version of the distro
|
||||
* currently staged for installation.</dd>
|
||||
* <dt>distroStatus</dt>
|
||||
* <dd>{@link #DISTRO_STATUS_INSTALLED} if there is a time zone distro installed and active,
|
||||
* {@link #DISTRO_STATUS_NONE} if there is no active installed distro.
|
||||
* {@link #DISTRO_STATUS_UNKNOWN} is used when {@link #isOperationInProgress()} is {@code true}.
|
||||
* </dd>
|
||||
* <dt>installedDistroRulesVersion</dt>
|
||||
* <dd>[present if distroStatus == {@link #DISTRO_STATUS_INSTALLED}], the rules version of the
|
||||
* installed and active distro.</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class RulesState implements Parcelable {
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "STAGED_OPERATION_" }, value = {
|
||||
STAGED_OPERATION_UNKNOWN,
|
||||
STAGED_OPERATION_NONE,
|
||||
STAGED_OPERATION_UNINSTALL,
|
||||
STAGED_OPERATION_INSTALL
|
||||
})
|
||||
private @interface StagedOperationType {}
|
||||
|
||||
/** Staged state could not be determined. */
|
||||
public static final int STAGED_OPERATION_UNKNOWN = 0;
|
||||
/** Nothing is staged. */
|
||||
public static final int STAGED_OPERATION_NONE = 1;
|
||||
/** An uninstall is staged. */
|
||||
public static final int STAGED_OPERATION_UNINSTALL = 2;
|
||||
/** An install is staged. */
|
||||
public static final int STAGED_OPERATION_INSTALL = 3;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(prefix = { "DISTRO_STATUS_" }, value = {
|
||||
DISTRO_STATUS_UNKNOWN,
|
||||
DISTRO_STATUS_NONE,
|
||||
DISTRO_STATUS_INSTALLED
|
||||
})
|
||||
private @interface DistroStatus {}
|
||||
|
||||
/** The current distro status could not be determined. */
|
||||
public static final int DISTRO_STATUS_UNKNOWN = 0;
|
||||
/** There is no active installed time zone distro. */
|
||||
public static final int DISTRO_STATUS_NONE = 1;
|
||||
/** The is an active, installed time zone distro. */
|
||||
public static final int DISTRO_STATUS_INSTALLED = 2;
|
||||
|
||||
private static final byte BYTE_FALSE = 0;
|
||||
private static final byte BYTE_TRUE = 1;
|
||||
|
||||
private final String mBaseRulesVersion;
|
||||
private final DistroFormatVersion mDistroFormatVersionSupported;
|
||||
private final boolean mOperationInProgress;
|
||||
@StagedOperationType private final int mStagedOperationType;
|
||||
@Nullable private final DistroRulesVersion mStagedDistroRulesVersion;
|
||||
@DistroStatus private final int mDistroStatus;
|
||||
@Nullable private final DistroRulesVersion mInstalledDistroRulesVersion;
|
||||
|
||||
public RulesState(String baseRulesVersion, DistroFormatVersion distroFormatVersionSupported,
|
||||
boolean operationInProgress,
|
||||
@StagedOperationType int stagedOperationType,
|
||||
@Nullable DistroRulesVersion stagedDistroRulesVersion,
|
||||
@DistroStatus int distroStatus,
|
||||
@Nullable DistroRulesVersion installedDistroRulesVersion) {
|
||||
this.mBaseRulesVersion = validateRulesVersion("baseRulesVersion", baseRulesVersion);
|
||||
this.mDistroFormatVersionSupported =
|
||||
validateNotNull("distroFormatVersionSupported", distroFormatVersionSupported);
|
||||
this.mOperationInProgress = operationInProgress;
|
||||
|
||||
if (operationInProgress && stagedOperationType != STAGED_OPERATION_UNKNOWN) {
|
||||
throw new IllegalArgumentException(
|
||||
"stagedOperationType != STAGED_OPERATION_UNKNOWN");
|
||||
}
|
||||
this.mStagedOperationType = validateStagedOperation(stagedOperationType);
|
||||
this.mStagedDistroRulesVersion = validateConditionalNull(
|
||||
mStagedOperationType == STAGED_OPERATION_INSTALL /* requireNotNull */,
|
||||
"stagedDistroRulesVersion", stagedDistroRulesVersion);
|
||||
|
||||
this.mDistroStatus = validateDistroStatus(distroStatus);
|
||||
this.mInstalledDistroRulesVersion = validateConditionalNull(
|
||||
mDistroStatus == DISTRO_STATUS_INSTALLED/* requireNotNull */,
|
||||
"installedDistroRulesVersion", installedDistroRulesVersion);
|
||||
}
|
||||
|
||||
public String getBaseRulesVersion() {
|
||||
return mBaseRulesVersion;
|
||||
}
|
||||
|
||||
public boolean isOperationInProgress() {
|
||||
return mOperationInProgress;
|
||||
}
|
||||
|
||||
public @StagedOperationType int getStagedOperationType() {
|
||||
return mStagedOperationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the staged rules version when {@link #getStagedOperationType()} is
|
||||
* {@link #STAGED_OPERATION_INSTALL}.
|
||||
*/
|
||||
public @Nullable DistroRulesVersion getStagedDistroRulesVersion() {
|
||||
return mStagedDistroRulesVersion;
|
||||
}
|
||||
|
||||
public @DistroStatus int getDistroStatus() {
|
||||
return mDistroStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the installed rules version when {@link #getDistroStatus()} is
|
||||
* {@link #DISTRO_STATUS_INSTALLED}.
|
||||
*/
|
||||
public @Nullable DistroRulesVersion getInstalledDistroRulesVersion() {
|
||||
return mInstalledDistroRulesVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a distro in the specified format is supported on this device.
|
||||
*/
|
||||
public boolean isDistroFormatVersionSupported(DistroFormatVersion distroFormatVersion) {
|
||||
return mDistroFormatVersionSupported.supports(distroFormatVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the base data files contain IANA rules data that are newer than the
|
||||
* distro IANA rules version supplied, i.e. true when the version specified would be "worse"
|
||||
* than the one that is in the base data. Returns false if the base version is the
|
||||
* same or older, i.e. false when the version specified would be "better" than the one that is
|
||||
* in the base set.
|
||||
*/
|
||||
public boolean isBaseVersionNewerThan(DistroRulesVersion distroRulesVersion) {
|
||||
return mBaseRulesVersion.compareTo(distroRulesVersion.getRulesVersion()) > 0;
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<RulesState> CREATOR =
|
||||
new Parcelable.Creator<RulesState>() {
|
||||
public RulesState createFromParcel(Parcel in) {
|
||||
return RulesState.createFromParcel(in);
|
||||
}
|
||||
|
||||
public RulesState[] newArray(int size) {
|
||||
return new RulesState[size];
|
||||
}
|
||||
};
|
||||
|
||||
private static RulesState createFromParcel(Parcel in) {
|
||||
String baseRulesVersion = in.readString();
|
||||
DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null, android.app.timezone.DistroFormatVersion.class);
|
||||
boolean operationInProgress = in.readByte() == BYTE_TRUE;
|
||||
int distroStagedState = in.readByte();
|
||||
DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class);
|
||||
int installedDistroStatus = in.readByte();
|
||||
DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class);
|
||||
return new RulesState(baseRulesVersion, distroFormatVersionSupported, operationInProgress,
|
||||
distroStagedState, stagedDistroRulesVersion,
|
||||
installedDistroStatus, installedDistroRulesVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeString(mBaseRulesVersion);
|
||||
out.writeParcelable(mDistroFormatVersionSupported, 0);
|
||||
out.writeByte(mOperationInProgress ? BYTE_TRUE : BYTE_FALSE);
|
||||
out.writeByte((byte) mStagedOperationType);
|
||||
out.writeParcelable(mStagedDistroRulesVersion, 0);
|
||||
out.writeByte((byte) mDistroStatus);
|
||||
out.writeParcelable(mInstalledDistroRulesVersion, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RulesState that = (RulesState) o;
|
||||
|
||||
if (mOperationInProgress != that.mOperationInProgress) {
|
||||
return false;
|
||||
}
|
||||
if (mStagedOperationType != that.mStagedOperationType) {
|
||||
return false;
|
||||
}
|
||||
if (mDistroStatus != that.mDistroStatus) {
|
||||
return false;
|
||||
}
|
||||
if (!mBaseRulesVersion.equals(that.mBaseRulesVersion)) {
|
||||
return false;
|
||||
}
|
||||
if (!mDistroFormatVersionSupported.equals(that.mDistroFormatVersionSupported)) {
|
||||
return false;
|
||||
}
|
||||
if (mStagedDistroRulesVersion != null ? !mStagedDistroRulesVersion
|
||||
.equals(that.mStagedDistroRulesVersion) : that.mStagedDistroRulesVersion != null) {
|
||||
return false;
|
||||
}
|
||||
return mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
|
||||
.equals(that.mInstalledDistroRulesVersion)
|
||||
: that.mInstalledDistroRulesVersion == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = mBaseRulesVersion.hashCode();
|
||||
result = 31 * result + mDistroFormatVersionSupported.hashCode();
|
||||
result = 31 * result + (mOperationInProgress ? 1 : 0);
|
||||
result = 31 * result + mStagedOperationType;
|
||||
result = 31 * result + (mStagedDistroRulesVersion != null ? mStagedDistroRulesVersion
|
||||
.hashCode()
|
||||
: 0);
|
||||
result = 31 * result + mDistroStatus;
|
||||
result = 31 * result + (mInstalledDistroRulesVersion != null ? mInstalledDistroRulesVersion
|
||||
.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RulesState{"
|
||||
+ "mBaseRulesVersion='" + mBaseRulesVersion + '\''
|
||||
+ ", mDistroFormatVersionSupported=" + mDistroFormatVersionSupported
|
||||
+ ", mOperationInProgress=" + mOperationInProgress
|
||||
+ ", mStagedOperationType=" + mStagedOperationType
|
||||
+ ", mStagedDistroRulesVersion=" + mStagedDistroRulesVersion
|
||||
+ ", mDistroStatus=" + mDistroStatus
|
||||
+ ", mInstalledDistroRulesVersion=" + mInstalledDistroRulesVersion
|
||||
+ '}';
|
||||
}
|
||||
|
||||
private static int validateStagedOperation(int stagedOperationType) {
|
||||
if (stagedOperationType < STAGED_OPERATION_UNKNOWN
|
||||
|| stagedOperationType > STAGED_OPERATION_INSTALL) {
|
||||
throw new IllegalArgumentException("Unknown operation type=" + stagedOperationType);
|
||||
}
|
||||
return stagedOperationType;
|
||||
}
|
||||
|
||||
private static int validateDistroStatus(int distroStatus) {
|
||||
if (distroStatus < DISTRO_STATUS_UNKNOWN || distroStatus > DISTRO_STATUS_INSTALLED) {
|
||||
throw new IllegalArgumentException("Unknown distro status=" + distroStatus);
|
||||
}
|
||||
return distroStatus;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.UserHandle;
|
||||
|
||||
/**
|
||||
* Constants related to the contract between the Android system and the privileged time zone updater
|
||||
* application.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public final class RulesUpdaterContract {
|
||||
|
||||
/**
|
||||
* The system permission possessed by the Android system that allows it to trigger time zone
|
||||
* update checks. The updater should be configured to require this permission when registering
|
||||
* for {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intents.
|
||||
*/
|
||||
public static final String TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION =
|
||||
android.Manifest.permission.TRIGGER_TIME_ZONE_RULES_CHECK;
|
||||
|
||||
/**
|
||||
* The system permission possessed by the time zone rules updater app that allows it to update
|
||||
* device time zone rules. The Android system requires this permission for calls made to
|
||||
* {@link RulesManager}.
|
||||
*/
|
||||
public static final String UPDATE_TIME_ZONE_RULES_PERMISSION =
|
||||
android.Manifest.permission.UPDATE_TIME_ZONE_RULES;
|
||||
|
||||
/**
|
||||
* The action of the intent that the Android system will broadcast. The intent will be targeted
|
||||
* at the configured updater application's package meaning the term "broadcast" only loosely
|
||||
* applies.
|
||||
*/
|
||||
public static final String ACTION_TRIGGER_RULES_UPDATE_CHECK =
|
||||
"com.android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK";
|
||||
|
||||
/**
|
||||
* The extra containing the {@code byte[]} that should be passed to
|
||||
* {@link RulesManager#requestInstall(ParcelFileDescriptor, byte[], Callback)},
|
||||
* {@link RulesManager#requestUninstall(byte[], Callback)} and
|
||||
* {@link RulesManager#requestNothing(byte[], boolean)} methods when the
|
||||
* {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent has been processed.
|
||||
*/
|
||||
public static final String EXTRA_CHECK_TOKEN =
|
||||
"com.android.intent.extra.timezone.CHECK_TOKEN";
|
||||
|
||||
/**
|
||||
* Creates an intent that would trigger a time zone rules update check.
|
||||
*/
|
||||
public static Intent createUpdaterIntent(String updaterPackageName) {
|
||||
Intent intent = new Intent(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK);
|
||||
intent.setPackage(updaterPackageName);
|
||||
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||
return intent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts an {@link #ACTION_TRIGGER_RULES_UPDATE_CHECK} intent with the
|
||||
* {@link #EXTRA_CHECK_TOKEN} that triggers an update check, including the required receiver
|
||||
* permission.
|
||||
*/
|
||||
public static void sendBroadcast(Context context, String updaterAppPackageName,
|
||||
byte[] checkTokenBytes) {
|
||||
Intent intent = createUpdaterIntent(updaterAppPackageName);
|
||||
intent.putExtra(EXTRA_CHECK_TOKEN, checkTokenBytes);
|
||||
context.sendBroadcastAsUser(
|
||||
intent, UserHandle.SYSTEM,
|
||||
RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
/**
|
||||
* Shared code for android.app.timezone classes.
|
||||
*/
|
||||
final class Utils {
|
||||
private Utils() {}
|
||||
|
||||
static int validateVersion(String type, int version) {
|
||||
if (version < 0 || version > 999) {
|
||||
throw new IllegalArgumentException("Invalid " + type + " version=" + version);
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
static String validateRulesVersion(String type, String rulesVersion) {
|
||||
validateNotNull(type, rulesVersion);
|
||||
|
||||
if (rulesVersion.isEmpty()) {
|
||||
throw new IllegalArgumentException(type + " must not be empty");
|
||||
}
|
||||
return rulesVersion;
|
||||
}
|
||||
|
||||
/** Validates that {@code object} is not null. Always returns {@code object}. */
|
||||
static <T> T validateNotNull(String type, T object) {
|
||||
if (object == null) {
|
||||
throw new NullPointerException(type + " == null");
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* If {@code requireNotNull} is {@code true} calls {@link #validateNotNull(String, Object)},
|
||||
* and {@link #validateNull(String, Object)} otherwise. Returns {@code object}.
|
||||
*/
|
||||
static <T> T validateConditionalNull(boolean requireNotNull, String type, T object) {
|
||||
if (requireNotNull) {
|
||||
return validateNotNull(type, object);
|
||||
} else {
|
||||
return validateNull(type, object);
|
||||
}
|
||||
}
|
||||
|
||||
/** Validates that {@code object} is null. Always returns null. */
|
||||
static <T> T validateNull(String type, T object) {
|
||||
if (object != null) {
|
||||
throw new IllegalArgumentException(type + " != null");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3821,7 +3821,6 @@ public abstract class Context {
|
||||
STORAGE_SERVICE,
|
||||
STORAGE_STATS_SERVICE,
|
||||
WALLPAPER_SERVICE,
|
||||
TIME_ZONE_RULES_MANAGER_SERVICE,
|
||||
VIBRATOR_MANAGER_SERVICE,
|
||||
VIBRATOR_SERVICE,
|
||||
//@hide: STATUS_BAR_SERVICE,
|
||||
@@ -5754,15 +5753,6 @@ public abstract class Context {
|
||||
@SystemApi
|
||||
public static final String VR_SERVICE = "vrmanager";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService(String)} to retrieve an
|
||||
* {@link android.app.timezone.ITimeZoneRulesManager}.
|
||||
* @hide
|
||||
*
|
||||
* @see #getSystemService(String)
|
||||
*/
|
||||
public static final String TIME_ZONE_RULES_MANAGER_SERVICE = "timezone";
|
||||
|
||||
/**
|
||||
* Use with {@link #getSystemService(String)} to retrieve a
|
||||
* {@link android.content.pm.CrossProfileApps} for cross profile operations.
|
||||
|
||||
@@ -671,10 +671,6 @@
|
||||
<protected-broadcast android:name="android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED" />
|
||||
<protected-broadcast android:name="com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER" />
|
||||
|
||||
<!-- Time zone rules update intents fired by the system server -->
|
||||
<protected-broadcast android:name="com.android.intent.action.timezone.RULES_UPDATE_OPERATION" />
|
||||
<protected-broadcast android:name="com.android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK" />
|
||||
|
||||
<!-- Made protected in P (was introduced in JB-MR2) -->
|
||||
<protected-broadcast android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
|
||||
<protected-broadcast android:name="android.telephony.euicc.action.OTA_STATUS_CHANGED" />
|
||||
@@ -3673,7 +3669,8 @@
|
||||
|
||||
<!-- Allows an application to query the current time zone rules state
|
||||
on device.
|
||||
@SystemApi @hide -->
|
||||
@SystemApi @hide
|
||||
@deprecated Vestigial permission declaration. No longer used. -->
|
||||
<permission android:name="android.permission.QUERY_TIME_ZONE_RULES"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
@@ -3682,17 +3679,11 @@
|
||||
<p>An application requesting this permission is responsible for
|
||||
verifying the source and integrity of the update before passing
|
||||
it off to the installer components.
|
||||
@SystemApi @hide -->
|
||||
@SystemApi @hide
|
||||
@deprecated Vestigial permission declaration. No longer used. -->
|
||||
<permission android:name="android.permission.UPDATE_TIME_ZONE_RULES"
|
||||
android:protectionLevel="signature|privileged" />
|
||||
|
||||
<!-- Must be required by a time zone rule updater application,
|
||||
to ensure that only the system can trigger it.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"
|
||||
android:protectionLevel="signature" />
|
||||
<uses-permission android:name="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"/>
|
||||
|
||||
<!-- Allows the system to reset throttling in shortcut manager.
|
||||
@hide -->
|
||||
<permission android:name="android.permission.RESET_SHORTCUT_MANAGER_THROTTLING"
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link DistroFormatVersion}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class DistroFormatVersionTest {
|
||||
|
||||
@Test
|
||||
public void equalsAndHashCode() {
|
||||
DistroFormatVersion one = new DistroFormatVersion(1, 2);
|
||||
assertEqualsContract(one, one);
|
||||
|
||||
DistroFormatVersion two = new DistroFormatVersion(1, 2);
|
||||
assertEqualsContract(one, two);
|
||||
|
||||
DistroFormatVersion three = new DistroFormatVersion(2, 1);
|
||||
assertFalse(one.equals(three));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parcelable() {
|
||||
DistroFormatVersion version = new DistroFormatVersion(2, 3);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
version.writeToParcel(parcel, 0 /* flags */);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
DistroFormatVersion newVersion = DistroFormatVersion.CREATOR.createFromParcel(parcel);
|
||||
|
||||
assertEquals(version, newVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsVersion() {
|
||||
DistroFormatVersion deviceVersion = new DistroFormatVersion(2, 2);
|
||||
assertTrue(deviceVersion.supports(deviceVersion));
|
||||
|
||||
DistroFormatVersion sameVersion = new DistroFormatVersion(2, 2);
|
||||
assertTrue(deviceVersion.supports(sameVersion));
|
||||
|
||||
// Minor versions are backwards compatible.
|
||||
DistroFormatVersion sameMajorNewerMinor = new DistroFormatVersion(2, 3);
|
||||
assertTrue(deviceVersion.supports(sameMajorNewerMinor));
|
||||
DistroFormatVersion sameMajorOlderMinor = new DistroFormatVersion(2, 1);
|
||||
assertFalse(deviceVersion.supports(sameMajorOlderMinor));
|
||||
|
||||
// Major versions are not backwards compatible.
|
||||
DistroFormatVersion newerMajor = new DistroFormatVersion(1, 2);
|
||||
assertFalse(deviceVersion.supports(newerMajor));
|
||||
DistroFormatVersion olderMajor = new DistroFormatVersion(3, 2);
|
||||
assertFalse(deviceVersion.supports(olderMajor));
|
||||
}
|
||||
|
||||
private static void assertEqualsContract(DistroFormatVersion one, DistroFormatVersion two) {
|
||||
assertEquals(one, two);
|
||||
assertEquals(one.hashCode(), two.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link DistroRulesVersion}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class DistroRulesVersionTest {
|
||||
|
||||
@Test
|
||||
public void equalsAndHashCode() {
|
||||
DistroRulesVersion one = new DistroRulesVersion("2016a", 2);
|
||||
assertEqualsContract(one, one);
|
||||
|
||||
DistroRulesVersion two = new DistroRulesVersion("2016a", 2);
|
||||
assertEqualsContract(one, two);
|
||||
|
||||
DistroRulesVersion three = new DistroRulesVersion("2016b", 1);
|
||||
assertFalse(one.equals(three));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parcelable() {
|
||||
DistroRulesVersion version = new DistroRulesVersion("2016a", 2);
|
||||
|
||||
Parcel parcel = Parcel.obtain();
|
||||
version.writeToParcel(parcel, 0 /* flags */);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
DistroRulesVersion newVersion = DistroRulesVersion.CREATOR.createFromParcel(parcel);
|
||||
|
||||
assertEquals(version, newVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isOlderThan() {
|
||||
DistroRulesVersion deviceVersion = new DistroRulesVersion("2016b", 2);
|
||||
assertFalse(deviceVersion.isOlderThan(deviceVersion));
|
||||
|
||||
DistroRulesVersion sameVersion = new DistroRulesVersion("2016b", 2);
|
||||
assertFalse(deviceVersion.isOlderThan(sameVersion));
|
||||
|
||||
DistroRulesVersion sameRulesNewerRevision = new DistroRulesVersion("2016b", 3);
|
||||
assertTrue(deviceVersion.isOlderThan(sameRulesNewerRevision));
|
||||
|
||||
DistroRulesVersion sameRulesOlderRevision = new DistroRulesVersion("2016b", 1);
|
||||
assertFalse(deviceVersion.isOlderThan(sameRulesOlderRevision));
|
||||
|
||||
DistroRulesVersion newerRules = new DistroRulesVersion("2016c", 2);
|
||||
assertTrue(deviceVersion.isOlderThan(newerRules));
|
||||
|
||||
DistroRulesVersion olderRules = new DistroRulesVersion("2016a", 2);
|
||||
assertFalse(deviceVersion.isOlderThan(olderRules));
|
||||
}
|
||||
|
||||
private static void assertEqualsContract(DistroRulesVersion one, DistroRulesVersion two) {
|
||||
assertEquals(one, two);
|
||||
assertEquals(one.hashCode(), two.hashCode());
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
# Bug component: 24949
|
||||
include /core/java/android/app/timezone/OWNERS
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link RulesState}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class RulesStateTest {
|
||||
|
||||
@Test
|
||||
public void equalsAndHashCode() {
|
||||
RulesState one = new RulesState(
|
||||
"2016a", formatVersion(1, 2), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertEqualsContract(one, one);
|
||||
|
||||
RulesState two = new RulesState(
|
||||
"2016a", formatVersion(1, 2), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertEqualsContract(one, two);
|
||||
|
||||
RulesState differentBaseRules = new RulesState(
|
||||
"2016b", formatVersion(1, 2), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertFalse(one.equals(differentBaseRules));
|
||||
|
||||
RulesState differentFormatVersion = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertFalse(one.equals(differentFormatVersion));
|
||||
|
||||
RulesState differentOperationInProgress = new RulesState(
|
||||
"2016a", formatVersion(1, 1), true /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
|
||||
RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
|
||||
assertFalse(one.equals(differentOperationInProgress));
|
||||
|
||||
RulesState differentStagedOperation = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_UNINSTALL, null /* stagedDistroRulesVersion */,
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertFalse(one.equals(differentStagedOperation));
|
||||
|
||||
RulesState differentStagedInstallVersion = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 4),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 2));
|
||||
assertFalse(one.equals(differentStagedInstallVersion));
|
||||
|
||||
RulesState differentInstalled = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
|
||||
assertFalse(one.equals(differentInstalled));
|
||||
|
||||
RulesState differentInstalledVersion = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016a", 3),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
|
||||
assertFalse(one.equals(differentInstalledVersion));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parcelable() {
|
||||
RulesState rulesState1 = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_INSTALL, rulesVersion("2016b", 2),
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
|
||||
checkParcelableRoundTrip(rulesState1);
|
||||
|
||||
RulesState rulesStateWithNulls = new RulesState(
|
||||
"2016a", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
|
||||
RulesState.DISTRO_STATUS_NONE, null /* installedDistroRulesVersion */);
|
||||
checkParcelableRoundTrip(rulesStateWithNulls);
|
||||
|
||||
RulesState rulesStateWithUnknowns = new RulesState(
|
||||
"2016a", formatVersion(1, 1), true /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_UNKNOWN, null /* stagedDistroRulesVersion */,
|
||||
RulesState.DISTRO_STATUS_UNKNOWN, null /* installedDistroRulesVersion */);
|
||||
checkParcelableRoundTrip(rulesStateWithUnknowns);
|
||||
}
|
||||
|
||||
private static void checkParcelableRoundTrip(RulesState rulesState) {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
rulesState.writeToParcel(parcel, 0 /* flags */);
|
||||
parcel.setDataPosition(0);
|
||||
|
||||
RulesState newVersion = RulesState.CREATOR.createFromParcel(parcel);
|
||||
|
||||
assertEquals(rulesState, newVersion);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isBaseVersionNewerThan() {
|
||||
RulesState rulesState = new RulesState(
|
||||
"2016b", formatVersion(1, 1), false /* operationInProgress */,
|
||||
RulesState.STAGED_OPERATION_NONE, null /* stagedDistroRulesVersion */,
|
||||
RulesState.DISTRO_STATUS_INSTALLED, rulesVersion("2016b", 3));
|
||||
assertTrue(rulesState.isBaseVersionNewerThan(rulesVersion("2016a", 1)));
|
||||
assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016b", 1)));
|
||||
assertFalse(rulesState.isBaseVersionNewerThan(rulesVersion("2016c", 1)));
|
||||
}
|
||||
|
||||
private static void assertEqualsContract(RulesState one, RulesState two) {
|
||||
assertEquals(one, two);
|
||||
assertEquals(one.hashCode(), two.hashCode());
|
||||
}
|
||||
|
||||
private static DistroRulesVersion rulesVersion(String rulesVersion, int revision) {
|
||||
return new DistroRulesVersion(rulesVersion, revision);
|
||||
}
|
||||
|
||||
private static DistroFormatVersion formatVersion(int majorVersion, int minorVersion) {
|
||||
return new DistroFormatVersion(majorVersion, minorVersion);
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.timezone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.hamcrest.MockitoHamcrest.argThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
|
||||
import org.hamcrest.BaseMatcher;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link RulesUpdaterContract}.
|
||||
*/
|
||||
@LargeTest
|
||||
public class RulesUpdaterContractTest {
|
||||
|
||||
@Test
|
||||
public void createUpdaterIntent() throws Exception {
|
||||
String packageName = "foobar";
|
||||
Intent intent = RulesUpdaterContract.createUpdaterIntent(packageName);
|
||||
|
||||
assertEquals(RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK, intent.getAction());
|
||||
assertEquals(packageName, intent.getPackage());
|
||||
assertEquals(Intent.FLAG_INCLUDE_STOPPED_PACKAGES, intent.getFlags());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendBroadcast() throws Exception {
|
||||
String packageName = "foobar";
|
||||
byte[] tokenBytes = new byte[] { 1, 2, 3, 4, 5 };
|
||||
|
||||
Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(packageName);
|
||||
expectedIntent.putExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN, tokenBytes);
|
||||
|
||||
Context mockContext = mock(Context.class);
|
||||
|
||||
RulesUpdaterContract.sendBroadcast(mockContext, packageName, tokenBytes);
|
||||
|
||||
verify(mockContext).sendBroadcastAsUser(
|
||||
filterEquals(expectedIntent),
|
||||
eq(UserHandle.SYSTEM),
|
||||
eq(RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a mockito parameter matcher that uses {@link Intent#filterEquals(Intent)}. to
|
||||
* check the parameter against the intent supplied.
|
||||
*/
|
||||
private static Intent filterEquals(final Intent expected) {
|
||||
final Matcher<Intent> m = new BaseMatcher<Intent>() {
|
||||
@Override
|
||||
public boolean matches(Object actual) {
|
||||
return actual != null && expected.filterEquals((Intent) actual);
|
||||
}
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText(expected.toString());
|
||||
}
|
||||
};
|
||||
return argThat(m);
|
||||
}
|
||||
}
|
||||
@@ -171,12 +171,6 @@ prebuilt_etc {
|
||||
filename_from_src: true,
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "com.android.timezone.updater.xml",
|
||||
sub_dir: "permissions",
|
||||
src: "com.android.timezone.updater.xml",
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "services.core.protolog.json",
|
||||
srcs: ["services.core.protolog.json"],
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018 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
|
||||
-->
|
||||
<permissions>
|
||||
<privapp-permissions package="com.android.timezone.updater">
|
||||
<permission name="android.permission.QUERY_TIME_ZONE_RULES" />
|
||||
<permission name="android.permission.UPDATE_TIME_ZONE_RULES" />
|
||||
</privapp-permissions>
|
||||
</permissions>
|
||||
Reference in New Issue
Block a user