Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2be7ac45 authored by Neil Fuller's avatar Neil Fuller
Browse files

Expose time / time zone system apis for telephony

Expose system apis / permissions needed by the telephony module to
communicate with the system server for time and time zone detection.

There are also small improvements for @Nullable.

Bug: 147012511
Test: build only
Change-Id: I27e5aa4c594d5fbad0b6f043afb9e910dcba4349
parent 90c69777
Loading
Loading
Loading
Loading
+80 −0
Original line number Diff line number Diff line
// Signature format: 2.0
package android.app.timedetector {

  public final class PhoneTimeSuggestion implements android.os.Parcelable {
    method public void addDebugInfo(@NonNull String);
    method public void addDebugInfo(@NonNull java.util.List<java.lang.String>);
    method public int describeContents();
    method @NonNull public java.util.List<java.lang.String> getDebugInfo();
    method public int getPhoneId();
    method @Nullable public android.os.TimestampedValue<java.lang.Long> getUtcTime();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.timedetector.PhoneTimeSuggestion> CREATOR;
  }

  public static final class PhoneTimeSuggestion.Builder {
    ctor public PhoneTimeSuggestion.Builder(int);
    method @NonNull public android.app.timedetector.PhoneTimeSuggestion.Builder addDebugInfo(@NonNull String);
    method @NonNull public android.app.timedetector.PhoneTimeSuggestion build();
    method @NonNull public android.app.timedetector.PhoneTimeSuggestion.Builder setUtcTime(@Nullable android.os.TimestampedValue<java.lang.Long>);
  }

  public class TimeDetector {
    method @RequiresPermission("android.permission.SUGGEST_PHONE_TIME_AND_ZONE") public void suggestPhoneTime(@NonNull android.app.timedetector.PhoneTimeSuggestion);
  }

}

package android.app.timezonedetector {

  public final class PhoneTimeZoneSuggestion implements android.os.Parcelable {
    method public void addDebugInfo(@NonNull String);
    method public void addDebugInfo(@NonNull java.util.List<java.lang.String>);
    method @NonNull public static android.app.timezonedetector.PhoneTimeZoneSuggestion createEmptySuggestion(int, @NonNull String);
    method public int describeContents();
    method @NonNull public java.util.List<java.lang.String> getDebugInfo();
    method public int getMatchType();
    method public int getPhoneId();
    method public int getQuality();
    method @Nullable public String getZoneId();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.app.timezonedetector.PhoneTimeZoneSuggestion> CREATOR;
    field public static final int MATCH_TYPE_EMULATOR_ZONE_ID = 4; // 0x4
    field public static final int MATCH_TYPE_NA = 0; // 0x0
    field public static final int MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET = 3; // 0x3
    field public static final int MATCH_TYPE_NETWORK_COUNTRY_ONLY = 2; // 0x2
    field public static final int MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY = 5; // 0x5
    field public static final int QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS = 3; // 0x3
    field public static final int QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET = 2; // 0x2
    field public static final int QUALITY_NA = 0; // 0x0
    field public static final int QUALITY_SINGLE_ZONE = 1; // 0x1
  }

  public static final class PhoneTimeZoneSuggestion.Builder {
    ctor public PhoneTimeZoneSuggestion.Builder(int);
    method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder addDebugInfo(@NonNull String);
    method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion build();
    method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setMatchType(int);
    method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setQuality(int);
    method @NonNull public android.app.timezonedetector.PhoneTimeZoneSuggestion.Builder setZoneId(@Nullable String);
  }

  public class TimeZoneDetector {
    method @RequiresPermission("android.permission.SUGGEST_PHONE_TIME_AND_ZONE") public void suggestPhoneTimeZone(@NonNull android.app.timezonedetector.PhoneTimeZoneSuggestion);
  }

}

package android.os {

  public final class TimestampedValue<T> implements android.os.Parcelable {
    ctor public TimestampedValue(long, @Nullable T);
    method public int describeContents();
    method public long getReferenceTimeMillis();
    method @Nullable public T getValue();
    method public static long referenceTimeDifference(@NonNull android.os.TimestampedValue<?>, @NonNull android.os.TimestampedValue<?>);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.os.TimestampedValue<?>> CREATOR;
  }

}
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ package android {
    field public static final String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
    field public static final String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
    field public static final String SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON = "android.permission.SUBSTITUTE_SHARE_TARGET_APP_NAME_AND_ICON";
    field public static final String SUGGEST_PHONE_TIME_AND_ZONE = "android.permission.SUGGEST_PHONE_TIME_AND_ZONE";
    field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
    field public static final String SYSTEM_CAMERA = "android.permission.SYSTEM_CAMERA";
    field public static final String TETHER_PRIVILEGED = "android.permission.TETHER_PRIVILEGED";
+34 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app.timedetector;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.TimestampedValue;
@@ -28,17 +29,23 @@ import java.util.List;
import java.util.Objects;

/**
 * A time signal from a telephony source. The value can be {@code null} to indicate that the
 * telephony source has entered an "un-opinionated" state and any previously sent suggestions are
 * being withdrawn. When not {@code null}, the value consists of the number of milliseconds elapsed
 * since 1/1/1970 00:00:00 UTC and the time according to the elapsed realtime clock when that number
 * was established. The elapsed realtime clock is considered accurate but volatile, so time signals
 * must not be persisted across device resets.
 * A time suggestion from an identified telephony source. e.g. from NITZ information from a specific
 * radio.
 *
 * <p>The time value can be {@code null} to indicate that the telephony source has entered an
 * "un-opinionated" state and any previous suggestions from the source are being withdrawn. When not
 * {@code null}, the value consists of the number of milliseconds elapsed since 1/1/1970 00:00:00
 * UTC and the time according to the elapsed realtime clock when that number was established. The
 * elapsed realtime clock is considered accurate but volatile, so time suggestions must not be
 * persisted across device resets.
 *
 * @hide
 */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class PhoneTimeSuggestion implements Parcelable {

    /** @hide */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final @NonNull Parcelable.Creator<PhoneTimeSuggestion> CREATOR =
            new Parcelable.Creator<PhoneTimeSuggestion>() {
                public PhoneTimeSuggestion createFromParcel(Parcel in) {
@@ -85,15 +92,27 @@ public final class PhoneTimeSuggestion implements Parcelable {
        dest.writeList(mDebugInfo);
    }

    /**
     * Returns an identifier for the source of this suggestion. When a device has several "phones",
     * i.e. sim slots or equivalent, it is used to identify which one.
     */
    public int getPhoneId() {
        return mPhoneId;
    }

    /**
     * Returns the suggestion. {@code null} means that the caller is no longer sure what time it
     * is.
     */
    @Nullable
    public TimestampedValue<Long> getUtcTime() {
        return mUtcTime;
    }

    /**
     * Returns debug metadata for the suggestion. The information is present in {@link #toString()}
     * but is not considered for {@link #equals(Object)} and {@link #hashCode()}.
     */
    @NonNull
    public List<String> getDebugInfo() {
        return mDebugInfo == null
@@ -105,7 +124,7 @@ public final class PhoneTimeSuggestion implements Parcelable {
     * information is present in {@link #toString()} but is not considered for
     * {@link #equals(Object)} and {@link #hashCode()}.
     */
    public void addDebugInfo(String debugInfo) {
    public void addDebugInfo(@NonNull String debugInfo) {
        if (mDebugInfo == null) {
            mDebugInfo = new ArrayList<>();
        }
@@ -156,16 +175,19 @@ public final class PhoneTimeSuggestion implements Parcelable {
     *
     * @hide
     */
    public static class Builder {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final class Builder {
        private final int mPhoneId;
        private TimestampedValue<Long> mUtcTime;
        private List<String> mDebugInfo;
        @Nullable private TimestampedValue<Long> mUtcTime;
        @Nullable private List<String> mDebugInfo;

        /** Creates a builder with the specified {@code phoneId}. */
        public Builder(int phoneId) {
            mPhoneId = phoneId;
        }

        /** Returns the builder for call chaining. */
        @NonNull
        public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
            if (utcTime != null) {
                // utcTime can be null, but the value it holds cannot.
@@ -177,6 +199,7 @@ public final class PhoneTimeSuggestion implements Parcelable {
        }

        /** Returns the builder for call chaining. */
        @NonNull
        public Builder addDebugInfo(@NonNull String debugInfo) {
            if (mDebugInfo == null) {
                mDebugInfo = new ArrayList<>();
@@ -186,6 +209,7 @@ public final class PhoneTimeSuggestion implements Parcelable {
        }

        /** Returns the {@link PhoneTimeSuggestion}. */
        @NonNull
        public PhoneTimeSuggestion build() {
            return new PhoneTimeSuggestion(this);
        }
+11 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app.timedetector;

import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
@@ -29,8 +30,11 @@ import android.util.Log;

/**
 * The interface through which system components can send signals to the TimeDetectorService.
 *
 * <p>This class is marked non-final for mockito.
 * @hide
 */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
@SystemService(Context.TIME_DETECTOR_SERVICE)
public class TimeDetector {
    private static final String TAG = "timedetector.TimeDetector";
@@ -38,6 +42,7 @@ public class TimeDetector {

    private final ITimeDetectorService mITimeDetectorService;

    /** @hide */
    public TimeDetector() throws ServiceNotFoundException {
        mITimeDetectorService = ITimeDetectorService.Stub.asInterface(
                ServiceManager.getServiceOrThrow(Context.TIME_DETECTOR_SERVICE));
@@ -62,6 +67,8 @@ public class TimeDetector {

    /**
     * Suggests the user's manually entered current time to the detector.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.SUGGEST_MANUAL_TIME_AND_ZONE)
    public void suggestManualTime(@NonNull ManualTimeSuggestion timeSuggestion) {
@@ -77,6 +84,8 @@ public class TimeDetector {

    /**
     * A shared utility method to create a {@link ManualTimeSuggestion}.
     *
     * @hide
     */
    public static ManualTimeSuggestion createManualTimeSuggestion(long when, String why) {
        TimestampedValue<Long> utcTime =
@@ -88,6 +97,8 @@ public class TimeDetector {

    /**
     * Suggests the time according to a network time source like NTP.
     *
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.SET_TIME)
    public void suggestNetworkTime(NetworkTimeSuggestion timeSuggestion) {
+58 −8
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.app.timezonedetector;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

@@ -30,12 +31,27 @@ import java.util.List;
import java.util.Objects;

/**
 * A suggested time zone from a Phone-based signal, e.g. from MCC and NITZ information.
 * A time zone suggestion from an identified telephony source, e.g. from MCC and NITZ information
 * associated with a specific radio.
 *
 * <p>The time zone ID can be {@code null} to indicate that the telephony source has entered an
 * "un-opinionated" state and any previous suggestions from that source are being withdrawn.
 * When not {@code null}, the value consists of a suggested time zone ID and metadata that can be
 * used to judge quality / certainty of the suggestion.
 *
 * <p>{@code matchType} must be set to {@link #MATCH_TYPE_NA} when {@code zoneId} is {@code null},
 * and one of the other {@code MATCH_TYPE_} values when it is not {@code null}.
 *
 * <p>{@code quality} must be set to {@link #QUALITY_NA} when {@code zoneId} is {@code null},
 * and one of the other {@code QUALITY_} values when it is not {@code null}.
 *
 * @hide
 */
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public final class PhoneTimeZoneSuggestion implements Parcelable {

    /** @hide */
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    @NonNull
    public static final Creator<PhoneTimeZoneSuggestion> CREATOR =
            new Creator<PhoneTimeZoneSuggestion>() {
@@ -58,6 +74,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
        return new Builder(phoneId).addDebugInfo(debugInfo).build();
    }

    /** @hide */
    @IntDef({ MATCH_TYPE_NA, MATCH_TYPE_NETWORK_COUNTRY_ONLY, MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET,
            MATCH_TYPE_EMULATOR_ZONE_ID, MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY })
    @Retention(RetentionPolicy.SOURCE)
@@ -90,6 +107,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
     */
    public static final int MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY = 5;

    /** @hide */
    @IntDef({ QUALITY_NA, QUALITY_SINGLE_ZONE, QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET,
            QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS })
    @Retention(RetentionPolicy.SOURCE)
@@ -115,7 +133,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {

    /**
     * The ID of the phone this suggestion is associated with. For multiple-sim devices this
     * helps to establish origin so filtering / stickiness can be implemented.
     * helps to establish source so filtering / stickiness can be implemented.
     */
    private final int mPhoneId;

@@ -123,6 +141,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
     * The suggestion. {@code null} means there is no current suggestion and any previous suggestion
     * should be forgotten.
     */
    @Nullable
    private final String mZoneId;

    /**
@@ -139,9 +158,10 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
    private final int mQuality;

    /**
     * Free-form debug information about how the signal was derived. Used for debug only,
     * Free-form debug information about how the suggestion was derived. Used for debug only,
     * intentionally not used in equals(), etc.
     */
    @Nullable
    private List<String> mDebugInfo;

    private PhoneTimeZoneSuggestion(Builder builder) {
@@ -182,25 +202,47 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
        return 0;
    }

    /**
     * Returns an identifier for the source of this suggestion. When a device has several "phones",
     * i.e. sim slots or equivalent, it is used to identify which one.
     */
    public int getPhoneId() {
        return mPhoneId;
    }

    /**
     * Returns the suggested time zone Olson ID, e.g. "America/Los_Angeles". {@code null} means that
     * the caller is no longer sure what the current time zone is. See
     * {@link PhoneTimeZoneSuggestion} for the associated {@code matchType} / {@code quality} rules.
     */
    @Nullable
    public String getZoneId() {
        return mZoneId;
    }

    /**
     * Returns information about how the suggestion was determined which could be used to rank
     * suggestions when several are available from different sources. See
     * {@link PhoneTimeZoneSuggestion} for the associated rules.
     */
    @MatchType
    public int getMatchType() {
        return mMatchType;
    }

    /**
     * Returns information about the likelihood of the suggested zone being correct.  See
     * {@link PhoneTimeZoneSuggestion} for the associated rules.
     */
    @Quality
    public int getQuality() {
        return mQuality;
    }

    /**
     * Returns debug metadata for the suggestion. The information is present in {@link #toString()}
     * but is not considered for {@link #equals(Object)} and {@link #hashCode()}.
     */
    @NonNull
    public List<String> getDebugInfo() {
        return mDebugInfo == null
@@ -267,36 +309,43 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
     *
     * @hide
     */
    public static class Builder {
    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
    public static final class Builder {
        private final int mPhoneId;
        private String mZoneId;
        @Nullable private String mZoneId;
        @MatchType private int mMatchType;
        @Quality private int mQuality;
        private List<String> mDebugInfo;
        @Nullable private List<String> mDebugInfo;

        public Builder(int phoneId) {
            mPhoneId = phoneId;
        }

        /** Returns the builder for call chaining. */
        public Builder setZoneId(String zoneId) {
        /**
         * Returns the builder for call chaining.
         */
        @NonNull
        public Builder setZoneId(@Nullable String zoneId) {
            mZoneId = zoneId;
            return this;
        }

        /** Returns the builder for call chaining. */
        @NonNull
        public Builder setMatchType(@MatchType int matchType) {
            mMatchType = matchType;
            return this;
        }

        /** Returns the builder for call chaining. */
        @NonNull
        public Builder setQuality(@Quality int quality) {
            mQuality = quality;
            return this;
        }

        /** Returns the builder for call chaining. */
        @NonNull
        public Builder addDebugInfo(@NonNull String debugInfo) {
            if (mDebugInfo == null) {
                mDebugInfo = new ArrayList<>();
@@ -333,6 +382,7 @@ public final class PhoneTimeZoneSuggestion implements Parcelable {
        }

        /** Returns the {@link PhoneTimeZoneSuggestion}. */
        @NonNull
        public PhoneTimeZoneSuggestion build() {
            validate();
            return new PhoneTimeZoneSuggestion(this);
Loading