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

Commit 06e1ae1a authored by Sanket Padawe's avatar Sanket Padawe
Browse files

Add new TelephonyManager api to query Telephony metrics.

Bug: 28717269
Change-Id: I6f5e88509feda879162049955776cb61dda8c840
parent e19f2f2f
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -37341,6 +37341,26 @@ package android.telephony {
    method public void onSubscriptionsChanged();
  }
  public final class TelephonyHistogram implements android.os.Parcelable {
    ctor public TelephonyHistogram(int, int, int);
    ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
    ctor public TelephonyHistogram(android.os.Parcel);
    method public void addTimeTaken(int);
    method public int describeContents();
    method public int getAverageTime();
    method public int getBucketCount();
    method public int[] getBucketCounters();
    method public int[] getBucketEndPoints();
    method public int getCategory();
    method public int getId();
    method public int getMaxTime();
    method public int getMinTime();
    method public int getSampleCount();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
    field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
  }
  public class TelephonyManager {
    method public boolean canChangeDtmfToneLength();
    method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
@@ -37384,6 +37404,7 @@ package android.telephony {
    method public int getSimState();
    method public java.lang.String getSubscriberId();
    method public java.lang.String getSubscriberId(int);
    method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
    method public java.lang.String getVoiceMailAlphaTag();
    method public java.lang.String getVoiceMailAlphaTag(int);
    method public java.lang.String getVoiceMailNumber();
@@ -51551,7 +51572,6 @@ package java.lang {
    method public java.lang.StringBuffer insert(int, double);
    method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
    method public synchronized java.lang.StringBuffer reverse();
    method public synchronized java.lang.String toString();
  }
  public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
@@ -51589,7 +51609,6 @@ package java.lang {
    method public java.lang.StringBuilder insert(int, double);
    method public java.lang.StringBuilder replace(int, int, java.lang.String);
    method public java.lang.StringBuilder reverse();
    method public java.lang.String toString();
  }
  public class StringIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
@@ -51953,9 +51972,7 @@ package java.lang.reflect {
  }
  public final class Constructor extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
    method public java.lang.Class<T> getDeclaringClass();
    method public java.lang.Class<?>[] getExceptionTypes();
    method public java.lang.reflect.Type[] getGenericExceptionTypes();
@@ -52040,7 +52057,6 @@ package java.lang.reflect {
  }
  public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.Class<?> getDeclaringClass();
    method public java.lang.Object getDefaultValue();
+21 −5
Original line number Diff line number Diff line
@@ -40278,6 +40278,26 @@ package android.telephony {
    method public void onSubscriptionsChanged();
  }
  public final class TelephonyHistogram implements android.os.Parcelable {
    ctor public TelephonyHistogram(int, int, int);
    ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
    ctor public TelephonyHistogram(android.os.Parcel);
    method public void addTimeTaken(int);
    method public int describeContents();
    method public int getAverageTime();
    method public int getBucketCount();
    method public int[] getBucketCounters();
    method public int[] getBucketEndPoints();
    method public int getCategory();
    method public int getId();
    method public int getMaxTime();
    method public int getMinTime();
    method public int getSampleCount();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
    field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
  }
  public class TelephonyManager {
    method public void answerRingingCall();
    method public void call(java.lang.String, java.lang.String);
@@ -40340,6 +40360,7 @@ package android.telephony {
    method public int getSimState();
    method public java.lang.String getSubscriberId();
    method public java.lang.String getSubscriberId(int);
    method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
    method public java.lang.String getVoiceMailAlphaTag();
    method public java.lang.String getVoiceMailAlphaTag(int);
    method public java.lang.String getVoiceMailNumber();
@@ -54910,7 +54931,6 @@ package java.lang {
    method public java.lang.StringBuffer insert(int, double);
    method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
    method public synchronized java.lang.StringBuffer reverse();
    method public synchronized java.lang.String toString();
  }
  public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
@@ -54948,7 +54968,6 @@ package java.lang {
    method public java.lang.StringBuilder insert(int, double);
    method public java.lang.StringBuilder replace(int, int, java.lang.String);
    method public java.lang.StringBuilder reverse();
    method public java.lang.String toString();
  }
  public class StringIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
@@ -55312,9 +55331,7 @@ package java.lang.reflect {
  }
  public final class Constructor extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
    method public java.lang.Class<T> getDeclaringClass();
    method public java.lang.Class<?>[] getExceptionTypes();
    method public java.lang.reflect.Type[] getGenericExceptionTypes();
@@ -55399,7 +55416,6 @@ package java.lang.reflect {
  }
  public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.Class<?> getDeclaringClass();
    method public java.lang.Object getDefaultValue();
+21 −5
Original line number Diff line number Diff line
@@ -37419,6 +37419,26 @@ package android.telephony {
    method public void onSubscriptionsChanged();
  }
  public final class TelephonyHistogram implements android.os.Parcelable {
    ctor public TelephonyHistogram(int, int, int);
    ctor public TelephonyHistogram(android.telephony.TelephonyHistogram);
    ctor public TelephonyHistogram(android.os.Parcel);
    method public void addTimeTaken(int);
    method public int describeContents();
    method public int getAverageTime();
    method public int getBucketCount();
    method public int[] getBucketCounters();
    method public int[] getBucketEndPoints();
    method public int getCategory();
    method public int getId();
    method public int getMaxTime();
    method public int getMinTime();
    method public int getSampleCount();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.telephony.TelephonyHistogram> CREATOR;
    field public static final int TELEPHONY_CATEGORY_RIL = 1; // 0x1
  }
  public class TelephonyManager {
    method public boolean canChangeDtmfToneLength();
    method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
@@ -37462,6 +37482,7 @@ package android.telephony {
    method public int getSimState();
    method public java.lang.String getSubscriberId();
    method public java.lang.String getSubscriberId(int);
    method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
    method public java.lang.String getVoiceMailAlphaTag();
    method public java.lang.String getVoiceMailAlphaTag(int);
    method public java.lang.String getVoiceMailNumber();
@@ -51632,7 +51653,6 @@ package java.lang {
    method public java.lang.StringBuffer insert(int, double);
    method public synchronized java.lang.StringBuffer replace(int, int, java.lang.String);
    method public synchronized java.lang.StringBuffer reverse();
    method public synchronized java.lang.String toString();
  }
  public final class StringBuilder extends java.lang.AbstractStringBuilder implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
@@ -51670,7 +51690,6 @@ package java.lang {
    method public java.lang.StringBuilder insert(int, double);
    method public java.lang.StringBuilder replace(int, int, java.lang.String);
    method public java.lang.StringBuilder reverse();
    method public java.lang.String toString();
  }
  public class StringIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
@@ -52034,9 +52053,7 @@ package java.lang.reflect {
  }
  public final class Constructor extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
    method public java.lang.Class<T> getDeclaringClass();
    method public java.lang.Class<?>[] getExceptionTypes();
    method public java.lang.reflect.Type[] getGenericExceptionTypes();
@@ -52121,7 +52138,6 @@ package java.lang.reflect {
  }
  public final class Method extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
    method public boolean equals(java.lang.Object);
    method public A getAnnotation(java.lang.Class<A>);
    method public java.lang.Class<?> getDeclaringClass();
    method public java.lang.Object getDefaultValue();
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.telephony;
/**
 * @hide
 */
parcelable TelephonyHistogram;
+293 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.telephony;

import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Parcelable class to store Telephony histogram.
 * @hide
 */
@SystemApi
public final class TelephonyHistogram implements Parcelable {
    // Type of Telephony histogram Eg: RIL histogram will have all timing data associated with
    // RIL calls. Similarly we can have any other Telephony histogram.
    private final int category;

    // Unique Id identifying a sample within particular category of histogram
    private final int id;

    // Min time taken in ms
    private int minTimeMs;

    // Max time taken in ms
    private int maxTimeMs;

    // Average time taken in ms
    private int averageTimeMs;

    // Total count of samples
    private int sampleCount;

    // Array storing time taken for first #RANGE_CALCULATION_COUNT samples of histogram.
    private int[] initialTimings;

    // Total number of time ranges expected (must be greater than 1)
    private final int bucketCount;

    // Array storing endpoints of range buckets. Calculated based on values of minTime & maxTime
    // after totalTimeCount is #RANGE_CALCULATION_COUNT.
    private final int[] bucketEndPoints;

    // Array storing counts for each time range starting from smallest value range
    private final int[] bucketCounters;

    /**
     * Constant for Telephony category
     */
    public static final int TELEPHONY_CATEGORY_RIL = 1;

    // Count of Histogram samples after which time buckets are created.
    private static final int RANGE_CALCULATION_COUNT = 10;


    // Constant used to indicate #initialTimings is null while parceling
    private static final int ABSENT = 0;

    // Constant used to indicate #initialTimings is not null while parceling
    private static final int PRESENT = 1;

    // Throws exception if #totalBuckets is not greater than one.
    public TelephonyHistogram (int category, int id, int bucketCount) {
        if (bucketCount <= 1) {
            throw new IllegalArgumentException("Invalid number of buckets");
        }
        this.category = category;
        this.id = id;
        this.minTimeMs = Integer.MAX_VALUE;
        this.maxTimeMs = 0;
        this.averageTimeMs = 0;
        this.sampleCount = 0;
        initialTimings = new int[RANGE_CALCULATION_COUNT];
        this.bucketCount = bucketCount;
        bucketEndPoints = new int[bucketCount - 1];
        bucketCounters = new int[bucketCount];
    }

    public TelephonyHistogram(TelephonyHistogram th) {
        category = th.getCategory();
        id = th.getId();
        minTimeMs = th.getMinTime();
        maxTimeMs = th.getMaxTime();
        averageTimeMs = th.getAverageTime();
        sampleCount = th.getSampleCount();
        initialTimings = th.getInitialTimings();
        bucketCount = th.getBucketCount();
        bucketEndPoints = th.getBucketEndPoints();
        bucketCounters = th.getBucketCounters();
    }

    public int getCategory() {
        return category;
    }

    public int getId() {
        return id;
    }

    public int getMinTime() {
        return minTimeMs;
    }

    public int getMaxTime() {
        return maxTimeMs;
    }

    public int getAverageTime() {
        return averageTimeMs;
    }

    public int getSampleCount () {
        return sampleCount;
    }

    private int[] getInitialTimings() {
        return initialTimings;
    }

    public int getBucketCount() {
        return bucketCount;
    }

    public int[] getBucketEndPoints() {
        return getDeepCopyOfArray(bucketEndPoints);
    }

    public int[] getBucketCounters() {
        return getDeepCopyOfArray(bucketCounters);
    }

    private int[] getDeepCopyOfArray(int[] array) {
        int[] clone = new int[array.length];
        System.arraycopy(array, 0, clone, 0, array.length);
        return clone;
    }

    private void addToBucketCounter(int time) {
        int i;
        for (i = 0; i < bucketEndPoints.length; i++) {
            if (time <= bucketEndPoints[i]) {
                bucketCounters[i]++;
                return;
            }
        }
        bucketCounters[i]++;
    }

    // Add new value of time taken
    // This function updates minTime, maxTime, averageTime & totalTimeCount every time it is
    // called. initialTimings[] is updated if totalTimeCount <= #RANGE_CALCULATION_COUNT. When
    // totalTimeCount = RANGE_CALCULATION_COUNT, based on the min, max time & the number of buckets
    // expected, bucketEndPoints[] would be calculated. Then bucketCounters[] would be filled up
    // using values stored in initialTimings[]. Thereafter bucketCounters[] will always be updated.
    public void addTimeTaken(int time) {
        // Initialize all fields if its first entry or if integer overflow is going to occur while
        // trying to calculate averageTime
        if (sampleCount == 0 || (sampleCount == Integer.MAX_VALUE)) {
            if (sampleCount == 0) {
                minTimeMs = time;
                maxTimeMs = time;
                averageTimeMs = time;
            } else {
                initialTimings = new int[RANGE_CALCULATION_COUNT];
            }
            sampleCount = 1;
            Arrays.fill(initialTimings, 0);
            initialTimings[0] = time;
            Arrays.fill(bucketEndPoints, 0);
            Arrays.fill(bucketCounters, 0);
        } else {
            if (time < minTimeMs) {
                minTimeMs = time;
            }
            if (time > maxTimeMs) {
                maxTimeMs = time;
            }
            long totalTime = ((long)averageTimeMs) * sampleCount + time;
            averageTimeMs = (int)(totalTime/++sampleCount);

            if (sampleCount < RANGE_CALCULATION_COUNT) {
                initialTimings[sampleCount - 1] = time;
            } else if (sampleCount == RANGE_CALCULATION_COUNT) {
                initialTimings[sampleCount - 1] = time;

                // Calculate bucket endpoints based on bucketCount expected
                for (int i = 1; i < bucketCount; i++) {
                    int endPt = minTimeMs + (i * (maxTimeMs - minTimeMs)) / bucketCount;
                    bucketEndPoints[i - 1] = endPt;
                }

                // Use values stored in initialTimings[] to update bucketCounters
                for (int j = 0; j < RANGE_CALCULATION_COUNT; j++) {
                    addToBucketCounter(initialTimings[j]);
                }
                initialTimings = null;
            } else {
                addToBucketCounter(time);
            }

        }
    }

    public String toString() {
        String basic = " Histogram id = " + id + " Time(ms): min = " + minTimeMs + " max = "
                + maxTimeMs + " avg = " + averageTimeMs + " Count = " + sampleCount;
        if (sampleCount < RANGE_CALCULATION_COUNT) {
            return basic;
        } else {
            StringBuffer intervals = new StringBuffer(" Interval Endpoints:");
            for (int i = 0; i < bucketEndPoints.length; i++) {
                intervals.append(" " + bucketEndPoints[i]);
            }
            intervals.append(" Interval counters:");
            for (int i = 0; i < bucketCounters.length; i++) {
                intervals.append(" " + bucketCounters[i]);
            }
            return basic + intervals;
        }
    }

    public static final Parcelable.Creator<TelephonyHistogram> CREATOR =
            new Parcelable.Creator<TelephonyHistogram> () {

                @Override
                public TelephonyHistogram createFromParcel(Parcel in) {
                    return new TelephonyHistogram(in);
                }

                @Override
                public TelephonyHistogram[] newArray(int size) {
                    return new TelephonyHistogram[size];
                }
            };

    public TelephonyHistogram(Parcel in) {
        category = in.readInt();
        id = in.readInt();
        minTimeMs = in.readInt();
        maxTimeMs = in.readInt();
        averageTimeMs = in.readInt();
        sampleCount = in.readInt();
        if (in.readInt() == PRESENT) {
            initialTimings = new int[RANGE_CALCULATION_COUNT];
            in.readIntArray(initialTimings);
        }
        bucketCount = in.readInt();
        bucketEndPoints = new int[bucketCount - 1];
        in.readIntArray(bucketEndPoints);
        bucketCounters = new int[bucketCount];
        in.readIntArray(bucketCounters);
    }

    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(category);
        out.writeInt(id);
        out.writeInt(minTimeMs);
        out.writeInt(maxTimeMs);
        out.writeInt(averageTimeMs);
        out.writeLong(sampleCount);
        if (initialTimings == null) {
            out.writeInt(ABSENT);
        } else {
            out.writeInt(PRESENT);
            out.writeIntArray(initialTimings);
        }
        out.writeInt(bucketCount);
        out.writeIntArray(bucketEndPoints);
        out.writeIntArray(bucketCounters);
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
Loading