diff options
43 files changed, 1342 insertions, 501 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk index 1f6860b2b226..96aa055cc9e9 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -245,6 +245,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew $(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/platformprotos_intermediates) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/api/current.txt b/api/current.txt index 241117b023da..9ffd50f27c12 100644 --- a/api/current.txt +++ b/api/current.txt @@ -40176,6 +40176,7 @@ package android.telephony { field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool"; field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool"; field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool"; + field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool"; field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool"; field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool"; field public static final java.lang.String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool"; @@ -40831,9 +40832,13 @@ package android.telephony { method public java.lang.String getIccAuthentication(int, int, java.lang.String); method public java.lang.String getImei(); method public java.lang.String getImei(int); + method public java.lang.String getTypeAllocationCode(); + method public java.lang.String getTypeAllocationCode(int); method public java.lang.String getLine1Number(); method public java.lang.String getMeid(); method public java.lang.String getMeid(int); + method public java.lang.String getManufacturerCode(); + method public java.lang.String getManufacturerCode(int); method public java.lang.String getMmsUAProfUrl(); method public java.lang.String getMmsUserAgent(); method public java.lang.String getNai(); @@ -68724,7 +68729,7 @@ package java.util.regex { public final class Pattern implements java.io.Serializable { method public java.util.function.Predicate<java.lang.String> asPredicate(); method public static java.util.regex.Pattern compile(java.lang.String); - method public static java.util.regex.Pattern compile(java.lang.String, int) throws java.util.regex.PatternSyntaxException; + method public static java.util.regex.Pattern compile(java.lang.String, int); method public int flags(); method public java.util.regex.Matcher matcher(java.lang.CharSequence); method public static boolean matches(java.lang.String, java.lang.CharSequence); diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 5652d6dec8a5..a81d16a6c562 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -536,6 +536,20 @@ public class Binder implements IBinder { } /** + * Resolves a transaction code to a human readable name. + * + * <p>Default implementation is a stub that returns null. + * <p>AIDL generated code will return the original method name. + * + * @param transactionCode The code to resolve. + * @return A human readable name. + * @hide + */ + public @Nullable String getTransactionName(int transactionCode) { + return null; + } + + /** * Implemented to call the more convenient version * {@link #dump(FileDescriptor, PrintWriter, String[])}. */ @@ -592,7 +606,7 @@ public class Binder implements IBinder { /** * Print the object's state into the given stream. - * + * * @param fd The raw file descriptor that the dump is being sent to. * @param fout The file to which you should dump your state. This will be * closed for you after you return. diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 3e64af47c276..aca2bb834e10 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -333,8 +333,16 @@ public class TextUtils { } /** - * String.split() returns [''] when the string to be split is empty. This returns []. This does - * not remove any empty strings from the result. For example split("a,", "," ) returns {"a", ""}. + * + * This method yields the same result as {@code text.split(expression, -1)} except that if + * {@code text.isEmpty()} then this method returns an empty array whereas + * {@code "".split(expression, -1)} would have returned an array with a single {@code ""}. + * + * The {@code -1} means that trailing empty Strings are not removed from the result; for + * example split("a,", "," ) returns {"a", ""}. Note that whether a leading zero-width match + * can result in a leading {@code ""} depends on whether your app + * {@link android.content.pm.ApplicationInfo#targetSdkVersion targets an SDK version} + * {@code <= 28}; see {@link Pattern#split(CharSequence, int)}. * * @param text the string to split * @param expression the regular expression to match @@ -351,8 +359,16 @@ public class TextUtils { } /** - * Splits a string on a pattern. String.split() returns [''] when the string to be - * split is empty. This returns []. This does not remove any empty strings from the result. + * Splits a string on a pattern. This method yields the same result as + * {@code pattern.split(text, -1)} except that if {@code text.isEmpty()} then this method + * returns an empty array whereas {@code pattern.split("", -1)} would have returned an array + * with a single {@code ""}. + * + * The {@code -1} means that trailing empty Strings are not removed from the result; + * Note that whether a leading zero-width match can result in a leading {@code ""} depends + * on whether your app {@link android.content.pm.ApplicationInfo#targetSdkVersion targets + * an SDK version} {@code <= 28}; see {@link Pattern#split(CharSequence, int)}. + * * @param text the string to split * @param pattern the regular expression to match * @return an array of strings. The array will be empty if text is empty diff --git a/core/java/android/util/Half.java b/core/java/android/util/Half.java index 84c2e8302e89..5718d994620d 100644 --- a/core/java/android/util/Half.java +++ b/core/java/android/util/Half.java @@ -20,8 +20,6 @@ import android.annotation.HalfFloat; import android.annotation.NonNull; import android.annotation.Nullable; -import sun.misc.FloatingDecimal; - /** * <p>The {@code Half} class is a wrapper and a utility class to manipulate half-precision 16-bit * <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">IEEE 754</a> @@ -1026,7 +1024,7 @@ public final class Half extends Number implements Comparable<Half> { * half-precision float value */ public static @HalfFloat short parseHalf(@NonNull String s) throws NumberFormatException { - return toHalf(FloatingDecimal.parseFloat(s)); + return toHalf(Float.parseFloat(s)); } /** diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java index 3617aa7212dc..5a74ec0e52c0 100644 --- a/core/java/android/util/IntArray.java +++ b/core/java/android/util/IntArray.java @@ -18,9 +18,11 @@ package android.util; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; -import java.util.Arrays; + import libcore.util.EmptyArray; +import java.util.Arrays; + /** * Implements a growing array of int primitives. * @@ -102,7 +104,7 @@ public class IntArray implements Cloneable { ensureCapacity(1); int rightSegment = mSize - index; mSize++; - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); if (rightSegment != 0) { // Move by 1 all values from the right of 'index' @@ -175,7 +177,7 @@ public class IntArray implements Cloneable { * Returns the value at the specified position in this array. */ public int get(int index) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); return mValues[index]; } @@ -183,7 +185,7 @@ public class IntArray implements Cloneable { * Sets the value at the specified position in this array. */ public void set(int index, int value) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); mValues[index] = value; } @@ -205,7 +207,7 @@ public class IntArray implements Cloneable { * Removes the value at the specified index from this array. */ public void remove(int index) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1); mSize--; } @@ -223,10 +225,4 @@ public class IntArray implements Cloneable { public int[] toArray() { return Arrays.copyOf(mValues, mSize); } - - private void checkBounds(int index) { - if (index < 0 || mSize <= index) { - throw new ArrayIndexOutOfBoundsException(mSize, index); - } - } } diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java index 9b0489ca5c6e..9ddb0e21692a 100644 --- a/core/java/android/util/LongArray.java +++ b/core/java/android/util/LongArray.java @@ -18,9 +18,11 @@ package android.util; import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; -import java.util.Arrays; + import libcore.util.EmptyArray; +import java.util.Arrays; + /** * Implements a growing array of long primitives. * @@ -102,7 +104,7 @@ public class LongArray implements Cloneable { ensureCapacity(1); int rightSegment = mSize - index; mSize++; - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); if (rightSegment != 0) { // Move by 1 all values from the right of 'index' @@ -162,7 +164,7 @@ public class LongArray implements Cloneable { * Returns the value at the specified position in this array. */ public long get(int index) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); return mValues[index]; } @@ -170,7 +172,7 @@ public class LongArray implements Cloneable { * Sets the value at the specified position in this array. */ public void set(int index, long value) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); mValues[index] = value; } @@ -192,7 +194,7 @@ public class LongArray implements Cloneable { * Removes the value at the specified index from this array. */ public void remove(int index) { - checkBounds(index); + ArrayUtils.checkBounds(mSize, index); System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1); mSize--; } @@ -210,10 +212,4 @@ public class LongArray implements Cloneable { public long[] toArray() { return Arrays.copyOf(mValues, mSize); } - - private void checkBounds(int index) { - if (index < 0 || mSize <= index) { - throw new ArrayIndexOutOfBoundsException(mSize, index); - } - } } diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java index 41802cc60617..fb54e6940056 100644 --- a/core/java/com/android/internal/net/NetworkStatsFactory.java +++ b/core/java/com/android/internal/net/NetworkStatsFactory.java @@ -192,7 +192,7 @@ public class NetworkStatsFactory { reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { - throw new ProtocolException("problem parsing stats", e); + throw protocolExceptionWithCause("problem parsing stats", e); } finally { IoUtils.closeQuietly(reader); StrictMode.setThreadPolicy(savedPolicy); @@ -242,7 +242,7 @@ public class NetworkStatsFactory { reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { - throw new ProtocolException("problem parsing stats", e); + throw protocolExceptionWithCause("problem parsing stats", e); } finally { IoUtils.closeQuietly(reader); StrictMode.setThreadPolicy(savedPolicy); @@ -339,7 +339,7 @@ public class NetworkStatsFactory { reader.finishLine(); } } catch (NullPointerException|NumberFormatException e) { - throw new ProtocolException("problem parsing idx " + idx, e); + throw protocolExceptionWithCause("problem parsing idx " + idx, e); } finally { IoUtils.closeQuietly(reader); StrictMode.setThreadPolicy(savedPolicy); @@ -376,4 +376,10 @@ public class NetworkStatsFactory { @VisibleForTesting public static native int nativeReadNetworkStatsDev(NetworkStats stats); + + private static ProtocolException protocolExceptionWithCause(String message, Throwable cause) { + ProtocolException pe = new ProtocolException(message); + pe.initCause(cause); + return pe; + } } diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index 91bc6813c5fc..534f3b614f8d 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -587,4 +587,17 @@ public class ArrayUtils { public static @NonNull String[] defeatNullable(@Nullable String[] val) { return (val != null) ? val : EmptyArray.STRING; } + + /** + * Throws {@link ArrayIndexOutOfBoundsException} if the index is out of bounds. + * + * @param len length of the array. Must be non-negative + * @param index the index to check + * @throws ArrayIndexOutOfBoundsException if the {@code index} is out of bounds of the array + */ + public static void checkBounds(int len, int index) { + if (index < 0 || len <= index) { + throw new ArrayIndexOutOfBoundsException("length=" + len + "; index=" + index); + } + } } diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml index 23d70b8dedd4..4b70cda87055 100644 --- a/core/tests/coretests/AndroidTest.xml +++ b/core/tests/coretests/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.coretests" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp index 616558f29676..648fd35d787c 100644 --- a/libs/hwui/tests/macrobench/main.cpp +++ b/libs/hwui/tests/macrobench/main.cpp @@ -135,8 +135,6 @@ static bool setBenchmarkFormat(const char* format) { gBenchmarkReporter.reset(new benchmark::ConsoleReporter()); } else if (!strcmp(format, "json")) { gBenchmarkReporter.reset(new benchmark::JSONReporter()); - } else if (!strcmp(format, "csv")) { - gBenchmarkReporter.reset(new benchmark::CSVReporter()); } else { fprintf(stderr, "Unknown format '%s'", format); return false; diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp index b8f29043e597..027a7488f723 100644 --- a/libs/usb/Android.bp +++ b/libs/usb/Android.bp @@ -1 +1,23 @@ +// +// 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. +// + +java_sdk_library { + name: "com.android.future.usb.accessory", + srcs: ["src/**/*.java"], + api_packages: ["com.android.future.usb"], +} + subdirs = ["tests/*"] diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk deleted file mode 100644 index 129828fd463b..000000000000 --- a/libs/usb/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright (C) 2011 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. -# - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under,src) - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE:= com.android.future.usb.accessory - -include $(BUILD_JAVA_LIBRARY) diff --git a/libs/usb/api/current.txt b/libs/usb/api/current.txt new file mode 100644 index 000000000000..8488db5b0f86 --- /dev/null +++ b/libs/usb/api/current.txt @@ -0,0 +1,25 @@ +package com.android.future.usb { + + public class UsbAccessory { + method public java.lang.String getDescription(); + method public java.lang.String getManufacturer(); + method public java.lang.String getModel(); + method public java.lang.String getSerial(); + method public java.lang.String getUri(); + method public java.lang.String getVersion(); + } + + public class UsbManager { + method public static com.android.future.usb.UsbAccessory getAccessory(android.content.Intent); + method public com.android.future.usb.UsbAccessory[] getAccessoryList(); + method public static com.android.future.usb.UsbManager getInstance(android.content.Context); + method public boolean hasPermission(com.android.future.usb.UsbAccessory); + method public android.os.ParcelFileDescriptor openAccessory(com.android.future.usb.UsbAccessory); + method public void requestPermission(com.android.future.usb.UsbAccessory, android.app.PendingIntent); + field public static final java.lang.String ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED"; + field public static final java.lang.String ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED"; + field public static final java.lang.String EXTRA_PERMISSION_GRANTED = "permission"; + } + +} + diff --git a/libs/usb/api/removed.txt b/libs/usb/api/removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/libs/usb/api/removed.txt diff --git a/libs/usb/api/system-current.txt b/libs/usb/api/system-current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/libs/usb/api/system-current.txt diff --git a/libs/usb/api/system-removed.txt b/libs/usb/api/system-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/libs/usb/api/system-removed.txt diff --git a/libs/usb/api/test-current.txt b/libs/usb/api/test-current.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/libs/usb/api/test-current.txt diff --git a/libs/usb/api/test-removed.txt b/libs/usb/api/test-removed.txt new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/libs/usb/api/test-removed.txt diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk index ecb455a90e29..cfe2da1eb471 100644 --- a/libs/usb/tests/AccessoryChat/Android.mk +++ b/libs/usb/tests/AccessoryChat/Android.mk @@ -23,4 +23,6 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := AccessoryChat +LOCAL_PRIVATE_PLATFORM_APIS := true + include $(BUILD_PACKAGE) diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java index 851b78cfcd49..ecbcb406666d 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java @@ -27,7 +27,6 @@ import com.android.systemui.util.AlarmTimeout; import com.android.systemui.util.wakelock.WakeLock; import java.util.Calendar; -import java.util.GregorianCalendar; /** * The policy controlling doze. @@ -139,7 +138,7 @@ public class DozeUi implements DozeMachine.Part { } private long roundToNextMinute(long timeInMillis) { - Calendar calendar = GregorianCalendar.getInstance(); + Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timeInMillis); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.SECOND, 0); diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 2d2869d8817b..5a6a1c26caf5 100644..100755 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -251,12 +251,13 @@ public class PipManager implements BasePipManager { entry = Pair.<String, String>create(packageAndClassName[0], null); break; case 2: - if (packageAndClassName[1] != null - && packageAndClassName[1].startsWith(".")) { - entry = Pair.<String, String>create( - packageAndClassName[0], - packageAndClassName[0] + packageAndClassName[1]); + if (packageAndClassName[1] != null) { + entry = Pair.<String, String>create(packageAndClassName[0], + packageAndClassName[1].startsWith(".") + ? packageAndClassName[0] + packageAndClassName[1] + : packageAndClassName[1]); } + break; } if (entry != null) { sSettingsPackageAndClassNamePairList.add(entry); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 0b24db00368f..28ac78493793 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2191,6 +2191,7 @@ public class ConnectivityService extends IConnectivityManager.Stub updateCapabilities(oldScore, nai, nai.networkCapabilities); // If score has changed, rebroadcast to NetworkFactories. b/17726566 if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai); + if (valid) handleFreshlyValidatedNetwork(nai); } updateInetCondition(nai); // Let the NetworkAgent know the state of its network @@ -2285,6 +2286,16 @@ public class ConnectivityService extends IConnectivityManager.Stub mDefaultRequest.networkCapabilities, nai.networkCapabilities); } + private void handleFreshlyValidatedNetwork(NetworkAgentInfo nai) { + if (nai == null) return; + // If the Private DNS mode is opportunistic, reprogram the DNS servers + // in order to restart a validation pass from within netd. + final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); + if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) { + updateDnses(nai.linkProperties, null, nai.network.netId); + } + } + private void handlePrivateDnsSettingsChanged() { final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig(); diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java index 2c24798204eb..1ff455ea7a8f 100644 --- a/services/core/java/com/android/server/NetworkTimeUpdateService.java +++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java @@ -16,318 +16,15 @@ package com.android.server; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; -import android.database.ContentObserver; -import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.os.Binder; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.Message; -import android.os.SystemClock; -import android.os.PowerManager; -import android.provider.Settings; -import android.util.Log; -import android.util.NtpTrustedTime; -import android.util.TimeUtils; -import android.util.TrustedTime; - -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.util.DumpUtils; - -import java.io.FileDescriptor; -import java.io.PrintWriter; +import android.os.IBinder; /** - * Monitors the network time and updates the system time if it is out of sync - * and there hasn't been any NITZ update from the carrier recently. - * If looking up the network time fails for some reason, it tries a few times with a short - * interval and then resets to checking on longer intervals. - * <p> - * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't - * available. - * </p> + * An interface for NetworkTimeUpdateService implementations. Eventually part or all of this service + * will be subsumed into {@link com.android.server.timedetector.TimeDetectorService}. In the + * meantime this interface allows Android to use either the old or new implementation. */ -public class NetworkTimeUpdateService extends Binder { - - private static final String TAG = "NetworkTimeUpdateService"; - private static final boolean DBG = false; - - private static final int EVENT_AUTO_TIME_CHANGED = 1; - private static final int EVENT_POLL_NETWORK_TIME = 2; - private static final int EVENT_NETWORK_CHANGED = 3; - - private static final String ACTION_POLL = - "com.android.server.NetworkTimeUpdateService.action.POLL"; - - private static final int POLL_REQUEST = 0; - - private static final long NOT_SET = -1; - private long mNitzTimeSetTime = NOT_SET; - private Network mDefaultNetwork = null; - - private Context mContext; - private TrustedTime mTime; - - // NTP lookup is done on this thread and handler - private Handler mHandler; - private AlarmManager mAlarmManager; - private PendingIntent mPendingPollIntent; - private SettingsObserver mSettingsObserver; - private ConnectivityManager mCM; - private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback; - // The last time that we successfully fetched the NTP time. - private long mLastNtpFetchTime = NOT_SET; - private final PowerManager.WakeLock mWakeLock; - - // Normal polling frequency - private final long mPollingIntervalMs; - // Try-again polling interval, in case the network request failed - private final long mPollingIntervalShorterMs; - // Number of times to try again - private final int mTryAgainTimesMax; - // If the time difference is greater than this threshold, then update the time. - private final int mTimeErrorThresholdMs; - // Keeps track of how many quick attempts were made to fetch NTP time. - // During bootup, the network may not have been up yet, or it's taking time for the - // connection to happen. - private int mTryAgainCounter; - - public NetworkTimeUpdateService(Context context) { - mContext = context; - mTime = NtpTrustedTime.getInstance(context); - mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); - mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - Intent pollIntent = new Intent(ACTION_POLL, null); - mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); - - mPollingIntervalMs = mContext.getResources().getInteger( - com.android.internal.R.integer.config_ntpPollingInterval); - mPollingIntervalShorterMs = mContext.getResources().getInteger( - com.android.internal.R.integer.config_ntpPollingIntervalShorter); - mTryAgainTimesMax = mContext.getResources().getInteger( - com.android.internal.R.integer.config_ntpRetry); - mTimeErrorThresholdMs = mContext.getResources().getInteger( - com.android.internal.R.integer.config_ntpThreshold); - - mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, TAG); - } +public interface NetworkTimeUpdateService extends IBinder { /** Initialize the receivers and initiate the first NTP request */ - public void systemRunning() { - registerForTelephonyIntents(); - registerForAlarms(); - - HandlerThread thread = new HandlerThread(TAG); - thread.start(); - mHandler = new MyHandler(thread.getLooper()); - mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback(); - mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler); - - mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED); - mSettingsObserver.observe(mContext); - } - - private void registerForTelephonyIntents() { - IntentFilter intentFilter = new IntentFilter(); - intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME); - mContext.registerReceiver(mNitzReceiver, intentFilter); - } - - private void registerForAlarms() { - mContext.registerReceiver( - new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget(); - } - }, new IntentFilter(ACTION_POLL)); - } - - private void onPollNetworkTime(int event) { - // If Automatic time is not set, don't bother. Similarly, if we don't - // have any default network, don't bother. - if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return; - mWakeLock.acquire(); - try { - onPollNetworkTimeUnderWakeLock(event); - } finally { - mWakeLock.release(); - } - } - - private void onPollNetworkTimeUnderWakeLock(int event) { - final long refTime = SystemClock.elapsedRealtime(); - // If NITZ time was received less than mPollingIntervalMs time ago, - // no need to sync to NTP. - if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) { - resetAlarm(mPollingIntervalMs); - return; - } - final long currentTime = System.currentTimeMillis(); - if (DBG) Log.d(TAG, "System time = " + currentTime); - // Get the NTP time - if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs - || event == EVENT_AUTO_TIME_CHANGED) { - if (DBG) Log.d(TAG, "Before Ntp fetch"); - - // force refresh NTP cache when outdated - if (mTime.getCacheAge() >= mPollingIntervalMs) { - mTime.forceRefresh(); - } - - // only update when NTP time is fresh - if (mTime.getCacheAge() < mPollingIntervalMs) { - final long ntp = mTime.currentTimeMillis(); - mTryAgainCounter = 0; - // If the clock is more than N seconds off or this is the first time it's been - // fetched since boot, set the current time. - if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs - || mLastNtpFetchTime == NOT_SET) { - // Set the system time - if (DBG && mLastNtpFetchTime == NOT_SET - && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) { - Log.d(TAG, "For initial setup, rtc = " + currentTime); - } - if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp); - // Make sure we don't overflow, since it's going to be converted to an int - if (ntp / 1000 < Integer.MAX_VALUE) { - SystemClock.setCurrentTimeMillis(ntp); - } - } else { - if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp); - } - mLastNtpFetchTime = SystemClock.elapsedRealtime(); - } else { - // Try again shortly - mTryAgainCounter++; - if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) { - resetAlarm(mPollingIntervalShorterMs); - } else { - // Try much later - mTryAgainCounter = 0; - resetAlarm(mPollingIntervalMs); - } - return; - } - } - resetAlarm(mPollingIntervalMs); - } - - /** - * Cancel old alarm and starts a new one for the specified interval. - * - * @param interval when to trigger the alarm, starting from now. - */ - private void resetAlarm(long interval) { - mAlarmManager.cancel(mPendingPollIntent); - long now = SystemClock.elapsedRealtime(); - long next = now + interval; - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); - } - - /** - * Checks if the user prefers to automatically set the time. - */ - private boolean isAutomaticTimeRequested() { - return Settings.Global.getInt( - mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0; - } - - /** Receiver for Nitz time events */ - private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() { - - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (DBG) Log.d(TAG, "Received " + action); - if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) { - mNitzTimeSetTime = SystemClock.elapsedRealtime(); - } - } - }; - - /** Handler to do the network accesses on */ - private class MyHandler extends Handler { - - public MyHandler(Looper l) { - super(l); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case EVENT_AUTO_TIME_CHANGED: - case EVENT_POLL_NETWORK_TIME: - case EVENT_NETWORK_CHANGED: - onPollNetworkTime(msg.what); - break; - } - } - } - - private class NetworkTimeUpdateCallback extends NetworkCallback { - @Override - public void onAvailable(Network network) { - Log.d(TAG, String.format("New default network %s; checking time.", network)); - mDefaultNetwork = network; - // Running on mHandler so invoke directly. - onPollNetworkTime(EVENT_NETWORK_CHANGED); - } - - @Override - public void onLost(Network network) { - if (network.equals(mDefaultNetwork)) mDefaultNetwork = null; - } - } - - /** Observer to watch for changes to the AUTO_TIME setting */ - private static class SettingsObserver extends ContentObserver { - - private int mMsg; - private Handler mHandler; - - SettingsObserver(Handler handler, int msg) { - super(handler); - mHandler = handler; - mMsg = msg; - } - - void observe(Context context) { - ContentResolver resolver = context.getContentResolver(); - resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME), - false, this); - } - - @Override - public void onChange(boolean selfChange) { - mHandler.obtainMessage(mMsg).sendToTarget(); - } - } - - @Override - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; - pw.print("PollingIntervalMs: "); - TimeUtils.formatDuration(mPollingIntervalMs, pw); - pw.print("\nPollingIntervalShorterMs: "); - TimeUtils.formatDuration(mPollingIntervalShorterMs, pw); - pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax); - pw.print("TimeErrorThresholdMs: "); - TimeUtils.formatDuration(mTimeErrorThresholdMs, pw); - pw.println("\nTryAgainCounter: " + mTryAgainCounter); - pw.print("LastNtpFetchTime: "); - TimeUtils.formatDuration(mLastNtpFetchTime, pw); - pw.println(); - } + void systemRunning(); } diff --git a/services/core/java/com/android/server/NewNetworkTimeUpdateService.java b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java new file mode 100644 index 000000000000..e918c1df7bd0 --- /dev/null +++ b/services/core/java/com/android/server/NewNetworkTimeUpdateService.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.os.Binder; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.SystemClock; +import android.os.PowerManager; +import android.provider.Settings; +import android.util.Log; +import android.util.NtpTrustedTime; +import android.util.TimeUtils; +import android.util.TrustedTime; + +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.util.DumpUtils; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Monitors the network time and updates the system time if it is out of sync + * and there hasn't been any NITZ update from the carrier recently. + * If looking up the network time fails for some reason, it tries a few times with a short + * interval and then resets to checking on longer intervals. + * <p> + * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't + * available. + * </p> + */ +public class NewNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService { + + private static final String TAG = "NetworkTimeUpdateService"; + private static final boolean DBG = false; + + private static final int EVENT_AUTO_TIME_CHANGED = 1; + private static final int EVENT_POLL_NETWORK_TIME = 2; + private static final int EVENT_NETWORK_CHANGED = 3; + + private static final String ACTION_POLL = + "com.android.server.NetworkTimeUpdateService.action.POLL"; + + private static final int POLL_REQUEST = 0; + + private static final long NOT_SET = -1; + private long mNitzTimeSetTime = NOT_SET; + private Network mDefaultNetwork = null; + + private Context mContext; + private TrustedTime mTime; + + // NTP lookup is done on this thread and handler + private Handler mHandler; + private AlarmManager mAlarmManager; + private PendingIntent mPendingPollIntent; + private SettingsObserver mSettingsObserver; + private ConnectivityManager mCM; + private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback; + // The last time that we successfully fetched the NTP time. + private long mLastNtpFetchTime = NOT_SET; + private final PowerManager.WakeLock mWakeLock; + + // Normal polling frequency + private final long mPollingIntervalMs; + // Try-again polling interval, in case the network request failed + private final long mPollingIntervalShorterMs; + // Number of times to try again + private final int mTryAgainTimesMax; + // If the time difference is greater than this threshold, then update the time. + private final int mTimeErrorThresholdMs; + // Keeps track of how many quick attempts were made to fetch NTP time. + // During bootup, the network may not have been up yet, or it's taking time for the + // connection to happen. + private int mTryAgainCounter; + + public NewNetworkTimeUpdateService(Context context) { + mContext = context; + mTime = NtpTrustedTime.getInstance(context); + mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); + mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + Intent pollIntent = new Intent(ACTION_POLL, null); + mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); + + mPollingIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpPollingInterval); + mPollingIntervalShorterMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpPollingIntervalShorter); + mTryAgainTimesMax = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpRetry); + mTimeErrorThresholdMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpThreshold); + + mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, TAG); + } + + /** Initialize the receivers and initiate the first NTP request */ + public void systemRunning() { + registerForTelephonyIntents(); + registerForAlarms(); + + HandlerThread thread = new HandlerThread(TAG); + thread.start(); + mHandler = new MyHandler(thread.getLooper()); + mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback(); + mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler); + + mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED); + mSettingsObserver.observe(mContext); + } + + private void registerForTelephonyIntents() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME); + mContext.registerReceiver(mNitzReceiver, intentFilter); + } + + private void registerForAlarms() { + mContext.registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget(); + } + }, new IntentFilter(ACTION_POLL)); + } + + private void onPollNetworkTime(int event) { + // If Automatic time is not set, don't bother. Similarly, if we don't + // have any default network, don't bother. + if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return; + mWakeLock.acquire(); + try { + onPollNetworkTimeUnderWakeLock(event); + } finally { + mWakeLock.release(); + } + } + + private void onPollNetworkTimeUnderWakeLock(int event) { + final long refTime = SystemClock.elapsedRealtime(); + // If NITZ time was received less than mPollingIntervalMs time ago, + // no need to sync to NTP. + if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) { + resetAlarm(mPollingIntervalMs); + return; + } + final long currentTime = System.currentTimeMillis(); + if (DBG) Log.d(TAG, "System time = " + currentTime); + // Get the NTP time + if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs + || event == EVENT_AUTO_TIME_CHANGED) { + if (DBG) Log.d(TAG, "Before Ntp fetch"); + + // force refresh NTP cache when outdated + if (mTime.getCacheAge() >= mPollingIntervalMs) { + mTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mTime.getCacheAge() < mPollingIntervalMs) { + final long ntp = mTime.currentTimeMillis(); + mTryAgainCounter = 0; + // If the clock is more than N seconds off or this is the first time it's been + // fetched since boot, set the current time. + if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs + || mLastNtpFetchTime == NOT_SET) { + // Set the system time + if (DBG && mLastNtpFetchTime == NOT_SET + && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) { + Log.d(TAG, "For initial setup, rtc = " + currentTime); + } + if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp); + // Make sure we don't overflow, since it's going to be converted to an int + if (ntp / 1000 < Integer.MAX_VALUE) { + SystemClock.setCurrentTimeMillis(ntp); + } + } else { + if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp); + } + mLastNtpFetchTime = SystemClock.elapsedRealtime(); + } else { + // Try again shortly + mTryAgainCounter++; + if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) { + resetAlarm(mPollingIntervalShorterMs); + } else { + // Try much later + mTryAgainCounter = 0; + resetAlarm(mPollingIntervalMs); + } + return; + } + } + resetAlarm(mPollingIntervalMs); + } + + /** + * Cancel old alarm and starts a new one for the specified interval. + * + * @param interval when to trigger the alarm, starting from now. + */ + private void resetAlarm(long interval) { + mAlarmManager.cancel(mPendingPollIntent); + long now = SystemClock.elapsedRealtime(); + long next = now + interval; + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); + } + + /** + * Checks if the user prefers to automatically set the time. + */ + private boolean isAutomaticTimeRequested() { + return Settings.Global.getInt( + mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0; + } + + /** Receiver for Nitz time events */ + private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (DBG) Log.d(TAG, "Received " + action); + if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) { + mNitzTimeSetTime = SystemClock.elapsedRealtime(); + } + } + }; + + /** Handler to do the network accesses on */ + private class MyHandler extends Handler { + + public MyHandler(Looper l) { + super(l); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case EVENT_AUTO_TIME_CHANGED: + case EVENT_POLL_NETWORK_TIME: + case EVENT_NETWORK_CHANGED: + onPollNetworkTime(msg.what); + break; + } + } + } + + private class NetworkTimeUpdateCallback extends NetworkCallback { + @Override + public void onAvailable(Network network) { + Log.d(TAG, String.format("New default network %s; checking time.", network)); + mDefaultNetwork = network; + // Running on mHandler so invoke directly. + onPollNetworkTime(EVENT_NETWORK_CHANGED); + } + + @Override + public void onLost(Network network) { + if (network.equals(mDefaultNetwork)) mDefaultNetwork = null; + } + } + + /** Observer to watch for changes to the AUTO_TIME setting */ + private static class SettingsObserver extends ContentObserver { + + private int mMsg; + private Handler mHandler; + + SettingsObserver(Handler handler, int msg) { + super(handler); + mHandler = handler; + mMsg = msg; + } + + void observe(Context context) { + ContentResolver resolver = context.getContentResolver(); + resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME), + false, this); + } + + @Override + public void onChange(boolean selfChange) { + mHandler.obtainMessage(mMsg).sendToTarget(); + } + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + pw.print("PollingIntervalMs: "); + TimeUtils.formatDuration(mPollingIntervalMs, pw); + pw.print("\nPollingIntervalShorterMs: "); + TimeUtils.formatDuration(mPollingIntervalShorterMs, pw); + pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax); + pw.print("TimeErrorThresholdMs: "); + TimeUtils.formatDuration(mTimeErrorThresholdMs, pw); + pw.println("\nTryAgainCounter: " + mTryAgainCounter); + pw.print("LastNtpFetchTime: "); + TimeUtils.formatDuration(mLastNtpFetchTime, pw); + pw.println(); + } +} diff --git a/services/core/java/com/android/server/OldNetworkTimeUpdateService.java b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java new file mode 100644 index 000000000000..d127b67c5d52 --- /dev/null +++ b/services/core/java/com/android/server/OldNetworkTimeUpdateService.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.database.ContentObserver; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; +import android.net.Network; +import android.os.Binder; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; +import android.os.SystemClock; +import android.os.PowerManager; +import android.provider.Settings; +import android.util.Log; +import android.util.NtpTrustedTime; +import android.util.TimeUtils; +import android.util.TrustedTime; + +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.util.DumpUtils; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +/** + * Monitors the network time and updates the system time if it is out of sync + * and there hasn't been any NITZ update from the carrier recently. + * If looking up the network time fails for some reason, it tries a few times with a short + * interval and then resets to checking on longer intervals. + * <p> + * If the user enables AUTO_TIME, it will check immediately for the network time, if NITZ wasn't + * available. + * </p> + */ +public class OldNetworkTimeUpdateService extends Binder implements NetworkTimeUpdateService { + + private static final String TAG = "NetworkTimeUpdateService"; + private static final boolean DBG = false; + + private static final int EVENT_AUTO_TIME_CHANGED = 1; + private static final int EVENT_POLL_NETWORK_TIME = 2; + private static final int EVENT_NETWORK_CHANGED = 3; + + private static final String ACTION_POLL = + "com.android.server.NetworkTimeUpdateService.action.POLL"; + + private static final int POLL_REQUEST = 0; + + private static final long NOT_SET = -1; + private long mNitzTimeSetTime = NOT_SET; + private Network mDefaultNetwork = null; + + private Context mContext; + private TrustedTime mTime; + + // NTP lookup is done on this thread and handler + private Handler mHandler; + private AlarmManager mAlarmManager; + private PendingIntent mPendingPollIntent; + private SettingsObserver mSettingsObserver; + private ConnectivityManager mCM; + private NetworkTimeUpdateCallback mNetworkTimeUpdateCallback; + // The last time that we successfully fetched the NTP time. + private long mLastNtpFetchTime = NOT_SET; + private final PowerManager.WakeLock mWakeLock; + + // Normal polling frequency + private final long mPollingIntervalMs; + // Try-again polling interval, in case the network request failed + private final long mPollingIntervalShorterMs; + // Number of times to try again + private final int mTryAgainTimesMax; + // If the time difference is greater than this threshold, then update the time. + private final int mTimeErrorThresholdMs; + // Keeps track of how many quick attempts were made to fetch NTP time. + // During bootup, the network may not have been up yet, or it's taking time for the + // connection to happen. + private int mTryAgainCounter; + + public OldNetworkTimeUpdateService(Context context) { + mContext = context; + mTime = NtpTrustedTime.getInstance(context); + mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); + mCM = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + Intent pollIntent = new Intent(ACTION_POLL, null); + mPendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST, pollIntent, 0); + + mPollingIntervalMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpPollingInterval); + mPollingIntervalShorterMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpPollingIntervalShorter); + mTryAgainTimesMax = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpRetry); + mTimeErrorThresholdMs = mContext.getResources().getInteger( + com.android.internal.R.integer.config_ntpThreshold); + + mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE)).newWakeLock( + PowerManager.PARTIAL_WAKE_LOCK, TAG); + } + + /** Initialize the receivers and initiate the first NTP request */ + public void systemRunning() { + registerForTelephonyIntents(); + registerForAlarms(); + + HandlerThread thread = new HandlerThread(TAG); + thread.start(); + mHandler = new MyHandler(thread.getLooper()); + mNetworkTimeUpdateCallback = new NetworkTimeUpdateCallback(); + mCM.registerDefaultNetworkCallback(mNetworkTimeUpdateCallback, mHandler); + + mSettingsObserver = new SettingsObserver(mHandler, EVENT_AUTO_TIME_CHANGED); + mSettingsObserver.observe(mContext); + } + + private void registerForTelephonyIntents() { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(TelephonyIntents.ACTION_NETWORK_SET_TIME); + mContext.registerReceiver(mNitzReceiver, intentFilter); + } + + private void registerForAlarms() { + mContext.registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mHandler.obtainMessage(EVENT_POLL_NETWORK_TIME).sendToTarget(); + } + }, new IntentFilter(ACTION_POLL)); + } + + private void onPollNetworkTime(int event) { + // If Automatic time is not set, don't bother. Similarly, if we don't + // have any default network, don't bother. + if (!isAutomaticTimeRequested() || mDefaultNetwork == null) return; + mWakeLock.acquire(); + try { + onPollNetworkTimeUnderWakeLock(event); + } finally { + mWakeLock.release(); + } + } + + private void onPollNetworkTimeUnderWakeLock(int event) { + final long refTime = SystemClock.elapsedRealtime(); + // If NITZ time was received less than mPollingIntervalMs time ago, + // no need to sync to NTP. + if (mNitzTimeSetTime != NOT_SET && refTime - mNitzTimeSetTime < mPollingIntervalMs) { + resetAlarm(mPollingIntervalMs); + return; + } + final long currentTime = System.currentTimeMillis(); + if (DBG) Log.d(TAG, "System time = " + currentTime); + // Get the NTP time + if (mLastNtpFetchTime == NOT_SET || refTime >= mLastNtpFetchTime + mPollingIntervalMs + || event == EVENT_AUTO_TIME_CHANGED) { + if (DBG) Log.d(TAG, "Before Ntp fetch"); + + // force refresh NTP cache when outdated + if (mTime.getCacheAge() >= mPollingIntervalMs) { + mTime.forceRefresh(); + } + + // only update when NTP time is fresh + if (mTime.getCacheAge() < mPollingIntervalMs) { + final long ntp = mTime.currentTimeMillis(); + mTryAgainCounter = 0; + // If the clock is more than N seconds off or this is the first time it's been + // fetched since boot, set the current time. + if (Math.abs(ntp - currentTime) > mTimeErrorThresholdMs + || mLastNtpFetchTime == NOT_SET) { + // Set the system time + if (DBG && mLastNtpFetchTime == NOT_SET + && Math.abs(ntp - currentTime) <= mTimeErrorThresholdMs) { + Log.d(TAG, "For initial setup, rtc = " + currentTime); + } + if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp); + // Make sure we don't overflow, since it's going to be converted to an int + if (ntp / 1000 < Integer.MAX_VALUE) { + SystemClock.setCurrentTimeMillis(ntp); + } + } else { + if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp); + } + mLastNtpFetchTime = SystemClock.elapsedRealtime(); + } else { + // Try again shortly + mTryAgainCounter++; + if (mTryAgainTimesMax < 0 || mTryAgainCounter <= mTryAgainTimesMax) { + resetAlarm(mPollingIntervalShorterMs); + } else { + // Try much later + mTryAgainCounter = 0; + resetAlarm(mPollingIntervalMs); + } + return; + } + } + resetAlarm(mPollingIntervalMs); + } + + /** + * Cancel old alarm and starts a new one for the specified interval. + * + * @param interval when to trigger the alarm, starting from now. + */ + private void resetAlarm(long interval) { + mAlarmManager.cancel(mPendingPollIntent); + long now = SystemClock.elapsedRealtime(); + long next = now + interval; + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, next, mPendingPollIntent); + } + + /** + * Checks if the user prefers to automatically set the time. + */ + private boolean isAutomaticTimeRequested() { + return Settings.Global.getInt( + mContext.getContentResolver(), Settings.Global.AUTO_TIME, 0) != 0; + } + + /** Receiver for Nitz time events */ + private BroadcastReceiver mNitzReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (DBG) Log.d(TAG, "Received " + action); + if (TelephonyIntents.ACTION_NETWORK_SET_TIME.equals(action)) { + mNitzTimeSetTime = SystemClock.elapsedRealtime(); + } + } + }; + + /** Handler to do the network accesses on */ + private class MyHandler extends Handler { + + public MyHandler(Looper l) { + super(l); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case EVENT_AUTO_TIME_CHANGED: + case EVENT_POLL_NETWORK_TIME: + case EVENT_NETWORK_CHANGED: + onPollNetworkTime(msg.what); + break; + } + } + } + + private class NetworkTimeUpdateCallback extends NetworkCallback { + @Override + public void onAvailable(Network network) { + Log.d(TAG, String.format("New default network %s; checking time.", network)); + mDefaultNetwork = network; + // Running on mHandler so invoke directly. + onPollNetworkTime(EVENT_NETWORK_CHANGED); + } + + @Override + public void onLost(Network network) { + if (network.equals(mDefaultNetwork)) mDefaultNetwork = null; + } + } + + /** Observer to watch for changes to the AUTO_TIME setting */ + private static class SettingsObserver extends ContentObserver { + + private int mMsg; + private Handler mHandler; + + SettingsObserver(Handler handler, int msg) { + super(handler); + mHandler = handler; + mMsg = msg; + } + + void observe(Context context) { + ContentResolver resolver = context.getContentResolver(); + resolver.registerContentObserver(Settings.Global.getUriFor(Settings.Global.AUTO_TIME), + false, this); + } + + @Override + public void onChange(boolean selfChange) { + mHandler.obtainMessage(mMsg).sendToTarget(); + } + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; + pw.print("PollingIntervalMs: "); + TimeUtils.formatDuration(mPollingIntervalMs, pw); + pw.print("\nPollingIntervalShorterMs: "); + TimeUtils.formatDuration(mPollingIntervalShorterMs, pw); + pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax); + pw.print("TimeErrorThresholdMs: "); + TimeUtils.formatDuration(mTimeErrorThresholdMs, pw); + pw.println("\nTryAgainCounter: " + mTryAgainCounter); + pw.print("LastNtpFetchTime: "); + TimeUtils.formatDuration(mLastNtpFetchTime, pw); + pw.println(); + } +} diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index bce735b547ef..2a80f0e7c291 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -115,6 +115,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; @@ -895,6 +896,42 @@ public class Vpn { .compareTo(MOST_IPV6_ADDRESSES_COUNT) >= 0; } + /** + * Attempt to perform a seamless handover of VPNs by only updating LinkProperties without + * registering a new NetworkAgent. This is not always possible if the new VPN configuration + * has certain changes, in which case this method would just return {@code false}. + */ + private boolean updateLinkPropertiesInPlaceIfPossible(NetworkAgent agent, VpnConfig oldConfig) { + // NetworkMisc cannot be updated without registering a new NetworkAgent. + if (oldConfig.allowBypass != mConfig.allowBypass) { + Log.i(TAG, "Handover not possible due to changes to allowBypass"); + return false; + } + + // TODO: we currently do not support seamless handover if the allowed or disallowed + // applications have changed. Consider diffing UID ranges and only applying the delta. + if (!Objects.equals(oldConfig.allowedApplications, mConfig.allowedApplications) || + !Objects.equals(oldConfig.disallowedApplications, mConfig.disallowedApplications)) { + Log.i(TAG, "Handover not possible due to changes to whitelisted/blacklisted apps"); + return false; + } + + LinkProperties lp = makeLinkProperties(); + final boolean hadInternetCapability = mNetworkCapabilities.hasCapability( + NetworkCapabilities.NET_CAPABILITY_INTERNET); + final boolean willHaveInternetCapability = providesRoutesToMostDestinations(lp); + if (hadInternetCapability != willHaveInternetCapability) { + // A seamless handover would have led to a change to INTERNET capability, which + // is supposed to be immutable for a given network. In this case bail out and do not + // perform handover. + Log.i(TAG, "Handover not possible due to changes to INTERNET capability"); + return false; + } + + agent.sendLinkProperties(lp); + return true; + } + private void agentConnect() { LinkProperties lp = makeLinkProperties(); @@ -1003,13 +1040,11 @@ public class Vpn { String oldInterface = mInterface; Connection oldConnection = mConnection; NetworkAgent oldNetworkAgent = mNetworkAgent; - mNetworkAgent = null; Set<UidRange> oldUsers = mNetworkCapabilities.getUids(); // Configure the interface. Abort if any of these steps fails. ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu)); try { - updateState(DetailedState.CONNECTING, "establish"); String interfaze = jniGetName(tun.getFd()); // TEMP use the old jni calls until there is support for netd address setting @@ -1037,15 +1072,26 @@ public class Vpn { mConfig = config; // Set up forwarding and DNS rules. - agentConnect(); + // First attempt to do a seamless handover that only changes the interface name and + // parameters. If that fails, disconnect. + if (oldConfig != null + && updateLinkPropertiesInPlaceIfPossible(mNetworkAgent, oldConfig)) { + // Keep mNetworkAgent unchanged + } else { + mNetworkAgent = null; + updateState(DetailedState.CONNECTING, "establish"); + // Set up forwarding and DNS rules. + agentConnect(); + // Remove the old tun's user forwarding rules + // The new tun's user rules have already been added above so they will take over + // as rules are deleted. This prevents data leakage as the rules are moved over. + agentDisconnect(oldNetworkAgent); + } if (oldConnection != null) { mContext.unbindService(oldConnection); } - // Remove the old tun's user forwarding rules - // The new tun's user rules have already been added so they will take over - // as rules are deleted. This prevents data leakage as the rules are moved over. - agentDisconnect(oldNetworkAgent); + if (oldInterface != null && !oldInterface.equals(interfaze)) { jniReset(oldInterface); } diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java index fbee86a84f85..9e6b659dbf93 100644 --- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java +++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java @@ -379,7 +379,7 @@ public class TetherInterfaceStateMachine extends StateMachine { // that adding routes that already exist does not cause an // error (EEXIST is silently ignored). mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded); - } catch (RemoteException e) { + } catch (Exception e) { mLog.e("Failed to add IPv6 routes to local table: " + e); } diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index c523c7ee6fee..a602ab1e5fa5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1205,21 +1205,24 @@ public final class SystemServer { traceEnd(); } - traceBeginAndSlog("StartTimeDetectorService"); - try { - mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS); - } catch (Throwable e) { - reportWtf("starting StartTimeDetectorService service", e); - } - traceEnd(); + final boolean useNewTimeServices = true; + if (useNewTimeServices) { + traceBeginAndSlog("StartTimeDetectorService"); + try { + mSystemServiceManager.startService(TIME_DETECTOR_SERVICE_CLASS); + } catch (Throwable e) { + reportWtf("starting StartTimeDetectorService service", e); + } + traceEnd(); - traceBeginAndSlog("StartTimeZoneDetectorService"); - try { - mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS); - } catch (Throwable e) { - reportWtf("starting StartTimeZoneDetectorService service", e); + traceBeginAndSlog("StartTimeZoneDetectorService"); + try { + mSystemServiceManager.startService(TIME_ZONE_DETECTOR_SERVICE_CLASS); + } catch (Throwable e) { + reportWtf("starting StartTimeZoneDetectorService service", e); + } + traceEnd(); } - traceEnd(); if (!disableNonCoreServices && !disableSearchManager) { traceBeginAndSlog("StartSearchManagerService"); @@ -1394,7 +1397,12 @@ public final class SystemServer { if (!disableNetwork && !disableNetworkTime) { traceBeginAndSlog("StartNetworkTimeUpdateService"); try { - networkTimeUpdater = new NetworkTimeUpdateService(context); + if (useNewTimeServices) { + networkTimeUpdater = new NewNetworkTimeUpdateService(context); + } else { + networkTimeUpdater = new OldNetworkTimeUpdateService(context); + } + Slog.d(TAG, "Using networkTimeUpdater class=" + networkTimeUpdater.getClass()); ServiceManager.addService("network_time_update_service", networkTimeUpdater); } catch (Throwable e) { reportWtf("starting NetworkTimeUpdate service", e); diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java index 5af3c299bfc1..cfcba3a84f51 100644 --- a/services/net/java/android/net/netlink/NetlinkSocket.java +++ b/services/net/java/android/net/netlink/NetlinkSocket.java @@ -59,10 +59,9 @@ public class NetlinkSocket { final String errPrefix = "Error in NetlinkSocket.sendOneShotKernelMessage"; final long IO_TIMEOUT = 300L; - FileDescriptor fd; + final FileDescriptor fd = forProto(nlProto); try { - fd = forProto(nlProto); connectToKernel(fd); sendMessage(fd, msg, 0, msg.length, IO_TIMEOUT); final ByteBuffer bytes = recvMessage(fd, DEFAULT_RECV_BUFSIZE, IO_TIMEOUT); @@ -96,9 +95,9 @@ public class NetlinkSocket { } catch (SocketException e) { Log.e(TAG, errPrefix, e); throw new ErrnoException(errPrefix, EIO, e); + } finally { + IoUtils.closeQuietly(fd); } - - IoUtils.closeQuietly(fd); } public static FileDescriptor forProto(int nlProto) throws ErrnoException { diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index b672e690d45f..102d0f7a86b7 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -113,6 +113,14 @@ public class CarrierConfigManager { public static final String KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool"; + /** + * Flag indicating whether or not sending emergency SMS messages over IMS + * is supported when in LTE/limited LTE (Emergency only) service mode.. + * + */ + public static final String + KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool"; + /** Flag indicating if the phone is a world phone */ public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool"; @@ -1011,6 +1019,26 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string"; /** + * Override the registered PLMN name using #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. + * + * If true, then the registered PLMN name (only for CDMA/CDMA-LTE and only when not roaming) + * will be #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. If false, or if phone type is not + * CDMA/CDMA-LTE or if roaming, then #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING will be ignored. + * @hide + */ + public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL = + "cdma_home_registered_plmn_name_override_bool"; + + /** + * String to identify registered PLMN name in CarrierConfig app. This string overrides + * registered PLMN name if #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL is true, phone type + * is CDMA/CDMA-LTE and device is not in roaming state; otherwise, it will be ignored. + * @hide + */ + public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING = + "cdma_home_registered_plmn_name_string"; + + /** * If this is true, the SIM card (through Customer Service Profile EF file) will be able to * prevent manual operator selection. If false, this SIM setting will be ignored and manual * operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more @@ -1528,7 +1556,7 @@ public class CarrierConfigManager { public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL = "editable_wfc_roaming_mode_bool"; - /** + /** * Determine whether current lpp_mode used for E-911 needs to be kept persistently. * {@code false} - not keeping the lpp_mode means using default configuration of gps.conf * when sim is not presented. @@ -1967,6 +1995,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false); sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false); sDefaults.putBoolean(KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL, false); + sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, false); sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true); sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true); sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false); @@ -2069,6 +2098,8 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false); sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false); sDefaults.putString(KEY_CARRIER_NAME_STRING, ""); + sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false); + sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, ""); sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false); sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false); diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index 7e86966e2c1b..2b6928e2e4f1 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -121,6 +121,8 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** * Get reference signal received quality + * + * @return the RSRQ if available or Integer.MAX_VALUE if unavailable. */ public int getRsrq() { return mRsrq; @@ -128,13 +130,17 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** * Get reference signal signal-to-noise ratio + * + * @return the RSSNR if available or Integer.MAX_VALUE if unavailable. */ public int getRssnr() { return mRssnr; } /** - * Get reference signal received power + * Get reference signal received power in dBm + * + * @return the RSRP of the measured cell. */ public int getRsrp() { return mRsrp; @@ -142,13 +148,17 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** * Get channel quality indicator + * + * @return the CQI if available or Integer.MAX_VALUE if unavailable. */ public int getCqi() { return mCqi; } /** - * Get signal strength as dBm + * Get signal strength in dBm + * + * @return the RSRP of the measured cell. */ @Override public int getDbm() { @@ -175,7 +185,8 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P * Get the timing advance value for LTE, as a value in range of 0..1282. * Integer.MAX_VALUE is reported when there is no active RRC * connection. Refer to 3GPP 36.213 Sec 4.2.3 - * @return the LTE timing advance, if available. + * + * @return the LTE timing advance if available or Integer.MAX_VALUE if unavailable. */ public int getTimingAdvance() { return mTimingAdvance; diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index 26ffe3216bdc..19b3d0d41a0d 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -21,31 +21,27 @@ import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.ActivityManager; import android.app.AppOpsManager; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.UserInfo; -import android.location.LocationManager; import android.os.Binder; -import android.os.Build; import android.os.Process; import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import android.util.SparseBooleanArray; +import android.util.Log; -import java.util.HashMap; import java.util.List; -import java.util.Map; /** * Helper for performing location access checks. * @hide */ public final class LocationAccessPolicy { + private static final String TAG = "LocationAccessPolicy"; + private static final boolean DBG = false; + /** * API to determine if the caller has permissions to get cell location. * @@ -58,10 +54,11 @@ public final class LocationAccessPolicy { int uid, int pid) throws SecurityException { Trace.beginSection("TelephonyLocationCheck"); try { - // Always allow the phone process to access location. This avoid breaking legacy code - // that rely on public-facing APIs to access cell location, and it doesn't create a - // info leak risk because the cell location is stored in the phone process anyway. - if (uid == Process.PHONE_UID) { + // Always allow the phone process and system server to access location. This avoid + // breaking legacy code that rely on public-facing APIs to access cell location, and + // it doesn't create an info leak risk because the cell location is stored in the phone + // process anyway, and the system server already has location access. + if (uid == Process.PHONE_UID || uid == Process.SYSTEM_UID || uid == Process.ROOT_UID) { return true; } @@ -74,15 +71,18 @@ public final class LocationAccessPolicy { if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) == PackageManager.PERMISSION_DENIED) { + if (DBG) Log.w(TAG, "Permission checked failed (" + pid + "," + uid + ")"); return false; } final int opCode = AppOpsManager.permissionToOpCode( Manifest.permission.ACCESS_COARSE_LOCATION); if (opCode != AppOpsManager.OP_NONE && context.getSystemService(AppOpsManager.class) .noteOpNoThrow(opCode, uid, pkgName) != AppOpsManager.MODE_ALLOWED) { + if (DBG) Log.w(TAG, "AppOp check failed (" + uid + "," + pkgName + ")"); return false; } if (!isLocationModeEnabled(context, UserHandle.getUserId(uid))) { + if (DBG) Log.w(TAG, "Location disabled, failed, (" + uid + ")"); return false; } // If the user or profile is current, permission is granted. diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index bba779d0c175..e881549489a3 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -85,12 +85,12 @@ public class NetworkRegistrationState implements Parcelable { public static final int SERVICE_TYPE_VIDEO = 4; public static final int SERVICE_TYPE_EMERGENCY = 5; - /** {@link AccessNetworkConstants.TransportType}*/ - private final int mTransportType; - @Domain private final int mDomain; + /** {@link AccessNetworkConstants.TransportType}*/ + private final int mTransportType; + @RegState private final int mRegState; @@ -112,19 +112,19 @@ public class NetworkRegistrationState implements Parcelable { private DataSpecificRegistrationStates mDataSpecificStates; /** - * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType} * @param domain Network domain. Must be DOMAIN_CS or DOMAIN_PS. + * @param transportType Transport type. Must be {@link AccessNetworkConstants.TransportType} * @param regState Network registration state. * @param accessNetworkTechnology See TelephonyManager NETWORK_TYPE_XXXX. * @param reasonForDenial Reason for denial if the registration state is DENIED. * @param availableServices The supported service. * @param cellIdentity The identity representing a unique cell */ - public NetworkRegistrationState(int transportType, int domain, int regState, + public NetworkRegistrationState(int domain, int transportType, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity) { - mTransportType = transportType; mDomain = domain; + mTransportType = transportType; mRegState = regState; mAccessNetworkTechnology = accessNetworkTechnology; mReasonForDenial = reasonForDenial; @@ -137,11 +137,11 @@ public class NetworkRegistrationState implements Parcelable { * Constructor for voice network registration states. * @hide */ - public NetworkRegistrationState(int transportType, int domain, int regState, + public NetworkRegistrationState(int domain, int transportType, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, boolean cssSupported, int roamingIndicator, int systemIsInPrl, int defaultRoamingIndicator) { - this(transportType, domain, regState, accessNetworkTechnology, + this(domain, transportType, regState, accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices, cellIdentity); mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator, @@ -152,18 +152,18 @@ public class NetworkRegistrationState implements Parcelable { * Constructor for data network registration states. * @hide */ - public NetworkRegistrationState(int transportType, int domain, int regState, + public NetworkRegistrationState(int domain, int transportType, int regState, int accessNetworkTechnology, int reasonForDenial, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls) { - this(transportType, domain, regState, accessNetworkTechnology, + this(domain, transportType, regState, accessNetworkTechnology, reasonForDenial, emergencyOnly, availableServices, cellIdentity); mDataSpecificStates = new DataSpecificRegistrationStates(maxDataCalls); } protected NetworkRegistrationState(Parcel source) { - mTransportType = source.readInt(); mDomain = source.readInt(); + mTransportType = source.readInt(); mRegState = source.readInt(); mAccessNetworkTechnology = source.readInt(); mReasonForDenial = source.readInt(); @@ -260,8 +260,8 @@ public class NetworkRegistrationState implements Parcelable { @Override public String toString() { return new StringBuilder("NetworkRegistrationState{") - .append("transportType=").append(mTransportType) .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS") + .append("transportType=").append(mTransportType) .append(" regState=").append(regStateToString(mRegState)) .append(" accessNetworkTechnology=") .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology)) @@ -290,8 +290,8 @@ public class NetworkRegistrationState implements Parcelable { } NetworkRegistrationState other = (NetworkRegistrationState) o; - return mTransportType == other.mTransportType - && mDomain == other.mDomain + return mDomain == other.mDomain + && mTransportType == other.mTransportType && mRegState == other.mRegState && mAccessNetworkTechnology == other.mAccessNetworkTechnology && mReasonForDenial == other.mReasonForDenial @@ -305,8 +305,8 @@ public class NetworkRegistrationState implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mTransportType); dest.writeInt(mDomain); + dest.writeInt(mTransportType); dest.writeInt(mRegState); dest.writeInt(mAccessNetworkTechnology); dest.writeInt(mReasonForDenial); diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index e971d08aae7a..caf1d6676d04 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -30,6 +30,7 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; /** * Contains phone state and service related information. @@ -723,38 +724,40 @@ public class ServiceState implements Parcelable { @Override public int hashCode() { - return ((mVoiceRegState * 31) - + (mDataRegState * 37) - + mVoiceRoamingType - + mDataRoamingType - + mChannelNumber - + Arrays.hashCode(mCellBandwidths) - + (mIsManualNetworkSelection ? 1 : 0) - + ((null == mVoiceOperatorAlphaLong) ? 0 : mVoiceOperatorAlphaLong.hashCode()) - + ((null == mVoiceOperatorAlphaShort) ? 0 : mVoiceOperatorAlphaShort.hashCode()) - + ((null == mVoiceOperatorNumeric) ? 0 : mVoiceOperatorNumeric.hashCode()) - + ((null == mDataOperatorAlphaLong) ? 0 : mDataOperatorAlphaLong.hashCode()) - + ((null == mDataOperatorAlphaShort) ? 0 : mDataOperatorAlphaShort.hashCode()) - + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode()) - + mCdmaRoamingIndicator - + mCdmaDefaultRoamingIndicator - + (mIsEmergencyOnly ? 1 : 0) - + (mIsDataRoamingFromRegistration ? 1 : 0)); + return Objects.hash( + mVoiceRegState, + mDataRegState, + mVoiceRoamingType, + mDataRoamingType, + mChannelNumber, + mCellBandwidths, + mVoiceOperatorAlphaLong, + mVoiceOperatorAlphaShort, + mVoiceOperatorNumeric, + mDataOperatorAlphaLong, + mDataOperatorAlphaShort, + mDataOperatorNumeric, + mIsManualNetworkSelection, + mRilVoiceRadioTechnology, + mRilDataRadioTechnology, + mCssIndicator, + mNetworkId, + mSystemId, + mCdmaRoamingIndicator, + mCdmaDefaultRoamingIndicator, + mCdmaEriIconIndex, + mCdmaEriIconMode, + mIsEmergencyOnly, + mIsDataRoamingFromRegistration, + mIsUsingCarrierAggregation, + mLteEarfcnRsrpBoost, + mNetworkRegistrationStates); } @Override public boolean equals (Object o) { - ServiceState s; - - try { - s = (ServiceState) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } + if (!(o instanceof ServiceState)) return false; + ServiceState s = (ServiceState) o; return (mVoiceRegState == s.mVoiceRegState && mDataRegState == s.mDataRegState @@ -1562,13 +1565,14 @@ public class ServiceState implements Parcelable { /** * Get the network registration states with given transport type and domain. * + * @param domain The network domain. Must be {@link NetworkRegistrationState#DOMAIN_CS} or + * {@link NetworkRegistrationState#DOMAIN_PS}. * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType} - * @param domain The network domain. Must be DOMAIN_CS or DOMAIN_PS. * @return The matching NetworkRegistrationState. * @hide */ @SystemApi - public NetworkRegistrationState getNetworkRegistrationStates(int transportType, int domain) { + public NetworkRegistrationState getNetworkRegistrationStates(int domain, int transportType) { synchronized (mNetworkRegistrationStates) { for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) { if (networkRegistrationState.getTransportType() == transportType diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index e0b465d26a4a..3bc7341216e7 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1230,6 +1230,33 @@ public class TelephonyManager { } /** + * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not + * available. + */ + public String getTypeAllocationCode() { + return getTypeAllocationCode(getSlotIndex()); + } + + /** + * Returns the Type Allocation Code from the IMEI. Return null if Type Allocation Code is not + * available. + * + * @param slotIndex of which Type Allocation Code is returned + */ + public String getTypeAllocationCode(int slotIndex) { + ITelephony telephony = getITelephony(); + if (telephony == null) return null; + + try { + return telephony.getTypeAllocationCodeForSlot(slotIndex); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + return null; + } + } + + /** * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available. * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} @@ -1265,6 +1292,33 @@ public class TelephonyManager { } /** + * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not + * available. + */ + public String getManufacturerCode() { + return getManufacturerCode(getSlotIndex()); + } + + /** + * Returns the Manufacturer Code from the MEID. Return null if Manufacturer Code is not + * available. + * + * @param slotIndex of which Type Allocation Code is returned + */ + public String getManufacturerCode(int slotIndex) { + ITelephony telephony = getITelephony(); + if (telephony == null) return null; + + try { + return telephony.getManufacturerCodeForSlot(slotIndex); + } catch (RemoteException ex) { + return null; + } catch (NullPointerException ex) { + return null; + } + } + + /** * Returns the Network Access Identifier (NAI). Return null if NAI is not available. * * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index bb181e680d86..296e1de1b135 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -70,7 +70,12 @@ public class ApnSetting implements Parcelable { private static final String UNSPECIFIED_STRING = ""; /** - * All APN types. + * APN type for none. Should only be used for initialization. + * @hide + */ + public static final int TYPE_NONE = ApnTypes.NONE; + /** + * APN type for all APNs. * @hide */ public static final int TYPE_ALL = ApnTypes.ALL; diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java index e82c115cb4b3..e158fa84e34e 100644 --- a/telephony/java/android/telephony/ims/ImsExternalCallState.java +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java @@ -45,6 +45,7 @@ public final class ImsExternalCallState implements Parcelable { private int mCallId; // Number private Uri mAddress; + private Uri mLocalAddress; private boolean mIsPullable; // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED private int mCallState; @@ -69,10 +70,24 @@ public final class ImsExternalCallState implements Parcelable { } /** @hide */ + public ImsExternalCallState(int callId, Uri address, Uri localAddress, + boolean isPullable, int callState, int callType, boolean isCallheld) { + mCallId = callId; + mAddress = address; + mLocalAddress = localAddress; + mIsPullable = isPullable; + mCallState = callState; + mCallType = callType; + mIsHeld = isCallheld; + Rlog.d(TAG, "ImsExternalCallState = " + this); + } + + /** @hide */ public ImsExternalCallState(Parcel in) { mCallId = in.readInt(); ClassLoader classLoader = ImsExternalCallState.class.getClassLoader(); mAddress = in.readParcelable(classLoader); + mLocalAddress = in.readParcelable(classLoader); mIsPullable = (in.readInt() != 0); mCallState = in.readInt(); mCallType = in.readInt(); @@ -89,6 +104,7 @@ public final class ImsExternalCallState implements Parcelable { public void writeToParcel(Parcel out, int flags) { out.writeInt(mCallId); out.writeParcelable(mAddress, 0); + out.writeParcelable(mLocalAddress, 0); out.writeInt(mIsPullable ? 1 : 0); out.writeInt(mCallState); out.writeInt(mCallType); @@ -117,6 +133,11 @@ public final class ImsExternalCallState implements Parcelable { return mAddress; } + /** @hide */ + public Uri getLocalAddress() { + return mLocalAddress; + } + public boolean isCallPullable() { return mIsPullable; } @@ -137,6 +158,7 @@ public final class ImsExternalCallState implements Parcelable { public String toString() { return "ImsExternalCallState { mCallId = " + mCallId + ", mAddress = " + Log.pii(mAddress) + + ", mLocalAddress = " + Log.pii(mLocalAddress) + ", mIsPullable = " + mIsPullable + ", mCallState = " + mCallState + ", mCallType = " + mCallType + diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index e54691702776..86cb1b74abd3 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -103,19 +103,6 @@ public class DctConstants { /***** Constants *****/ - public static final int APN_INVALID_ID = -1; - public static final int APN_DEFAULT_ID = 0; - public static final int APN_MMS_ID = 1; - public static final int APN_SUPL_ID = 2; - public static final int APN_DUN_ID = 3; - public static final int APN_HIPRI_ID = 4; - public static final int APN_IMS_ID = 5; - public static final int APN_FOTA_ID = 6; - public static final int APN_CBS_ID = 7; - public static final int APN_IA_ID = 8; - public static final int APN_EMERGENCY_ID = 9; - public static final int APN_NUM_TYPES = 10; - public static final int INVALID = -1; public static final int DISABLED = 0; public static final int ENABLED = 1; diff --git a/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java b/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java new file mode 100644 index 000000000000..cc1d105ae29e --- /dev/null +++ b/telephony/java/com/android/internal/telephony/ISmsBaseImpl.java @@ -0,0 +1,199 @@ +/* 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. + * + */ + +package com.android.internal.telephony; + +import android.app.PendingIntent; +import android.net.Uri; +import java.lang.UnsupportedOperationException; +import java.util.List; + +public class ISmsBaseImpl extends ISms.Stub { + + @Override + public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPkg) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPkg, + int messageIndex, int newStatus, byte[] pdu) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean copyMessageToIccEfForSubscriber(int subId, String callingPkg, int status, + byte[] pdu, byte[] smsc) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendDataForSubscriber(int subId, String callingPkg, String destAddr, + String scAddr, int destPort, byte[] data, PendingIntent sentIntent, + PendingIntent deliveryIntent) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendDataForSubscriberWithSelfPermissions(int subId, String callingPkg, + String destAddr, String scAddr, int destPort, byte[] data, + PendingIntent sentIntent, PendingIntent deliveryIntent) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendTextForSubscriber(int subId, String callingPkg, String destAddr, + String scAddr, String text, PendingIntent sentIntent, + PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendTextForSubscriberWithSelfPermissions(int subId, String callingPkg, + String destAddr, String scAddr, String text, PendingIntent sentIntent, + PendingIntent deliveryIntent, boolean persistMessage) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendTextForSubscriberWithOptions(int subId, String callingPkg, String destAddr, + String scAddr, String text, PendingIntent sentIntent, + PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, + int priority, boolean expectMore, int validityPeriod) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void injectSmsPduForSubscriber( + int subId, byte[] pdu, String format, PendingIntent receivedIntent) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendMultipartTextForSubscriber(int subId, String callingPkg, + String destinationAddress, String scAddress, + List<String> parts, List<PendingIntent> sentIntents, + List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPkg, + String destinationAddress, String scAddress, + List<String> parts, List<PendingIntent> sentIntents, + List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp, + int priority, boolean expectMore, int validityPeriod) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, + int endMessageId, int ranType) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, + int endMessageId, int ranType) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public int getPremiumSmsPermission(String packageName) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public int getPremiumSmsPermissionForSubscriber(int subId, String packageName) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void setPremiumSmsPermission(String packageName, int permission) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void setPremiumSmsPermissionForSubscriber(int subId, String packageName, + int permission) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isImsSmsSupportedForSubscriber(int subId) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isSmsSimPickActivityNeeded(int subId) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public int getPreferredSmsSubscription() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public String getImsSmsFormatForSubscriber(int subId) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isSMSPromptEnabled() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendStoredText(int subId, String callingPkg, Uri messageUri, String scAddress, + PendingIntent sentIntent, PendingIntent deliveryIntent) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public void sendStoredMultipartText(int subId, String callingPkg, Uri messageUri, + String scAddress, List<PendingIntent> sentIntents, + List<PendingIntent> deliveryIntents) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + @Override + public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } +} diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 3fd1d04c465a..70354b212f25 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1198,6 +1198,13 @@ interface ITelephony { String getImeiForSlot(int slotIndex, String callingPackage); /** + * Returns the Type Allocation Code from the IMEI for the given slot. + * + * @param slotIndex - Which slot to retrieve the Type Allocation Code from. + */ + String getTypeAllocationCodeForSlot(int slotIndex); + + /** * Returns the MEID for the given slot. * * @param slotIndex - device slot. @@ -1208,6 +1215,13 @@ interface ITelephony { String getMeidForSlot(int slotIndex, String callingPackage); /** + * Returns the Manufacturer Code from the MEID for the given slot. + * + * @param slotIndex - Which slot to retrieve the Manufacturer Code from. + */ + String getManufacturerCodeForSlot(int slotIndex); + + /** * Returns the device software version. * * @param slotIndex - device slot. diff --git a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java index b763c78207de..b4b5ca7161fc 100644 --- a/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java +++ b/tests/TouchLatency/app/src/main/java/com/prefabulated/touchlatency/TouchLatencyActivity.java @@ -30,6 +30,7 @@ import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; +import android.os.Trace; import java.util.ArrayList; import java.util.Collections; @@ -42,6 +43,7 @@ class TouchLatencyView extends View implements View.OnTouchListener { public TouchLatencyView(Context context, AttributeSet attrs) { super(context, attrs); + Trace.beginSection("TouchLatencyView constructor"); setOnTouchListener(this); setWillNotDraw(false); mBluePaint = new Paint(Paint.ANTI_ALIAS_FLAG); @@ -63,48 +65,56 @@ class TouchLatencyView extends View implements View.OnTouchListener { mBallY = 100.0f; mVelocityX = 7.0f; mVelocityY = 7.0f; + Trace.endSection(); } @Override public boolean onTouch(View view, MotionEvent event) { + Trace.beginSection("TouchLatencyView onTouch"); int action = event.getActionMasked(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) { mTouching = true; invalidate(); + + mTouchX = event.getX(); + mTouchY = event.getY(); } else if (action == MotionEvent.ACTION_UP) { mTouching = false; invalidate(); - return true; - } else { - return true; } - mTouchX = event.getX(); - mTouchY = event.getY(); + Trace.endSection(); return true; } private void drawTouch(Canvas canvas) { - if (!mTouching) { - Log.d(LOG_TAG, "Filling background"); - canvas.drawColor(BACKGROUND_COLOR); - return; - } + Trace.beginSection("TouchLatencyView drawTouch"); - float deltaX = (mTouchX - mLastDrawnX); - float deltaY = (mTouchY - mLastDrawnY); - float scaleFactor = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 1.5f; + try { + if (!mTouching) { + Log.d(LOG_TAG, "Filling background"); + canvas.drawColor(BACKGROUND_COLOR); + return; + } - mLastDrawnX = mTouchX; - mLastDrawnY = mTouchY; + float deltaX = (mTouchX - mLastDrawnX); + float deltaY = (mTouchY - mLastDrawnY); + float scaleFactor = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 1.5f; - canvas.drawColor(BACKGROUND_COLOR); - canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 3 * scaleFactor, mRedPaint); - canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 2 * scaleFactor, mYellowPaint); - canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + scaleFactor, mGreenPaint); - canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS, mBluePaint); + mLastDrawnX = mTouchX; + mLastDrawnY = mTouchY; + + canvas.drawColor(BACKGROUND_COLOR); + canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 3 * scaleFactor, mRedPaint); + canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + 2 * scaleFactor, mYellowPaint); + canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS + scaleFactor, mGreenPaint); + canvas.drawCircle(mTouchX, mTouchY, INNER_RADIUS, mBluePaint); + } finally { + Trace.endSection(); + } } private void drawBall(Canvas canvas) { + Trace.beginSection("TouchLatencyView drawBall"); int width = canvas.getWidth(); int height = canvas.getHeight(); @@ -141,25 +151,29 @@ class TouchLatencyView extends View implements View.OnTouchListener { canvas.drawColor(BACKGROUND_COLOR); canvas.drawOval(left, top, right, bottom, mYellowPaint); invalidate(); + Trace.endSection(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - + Trace.beginSection("TouchLatencyView onDraw"); if (mMode == 0) { drawTouch(canvas); } else { drawBall(canvas); } + Trace.endSection(); } public void changeMode(MenuItem item) { + Trace.beginSection("TouchLatencyView changeMode"); final int NUM_MODES = 2; final String modes[] = {"Touch", "Ball"}; mMode = (mMode + 1) % NUM_MODES; invalidate(); item.setTitle(modes[mMode]); + Trace.endSection(); } private Paint mBluePaint, mGreenPaint, mYellowPaint, mRedPaint; @@ -178,21 +192,26 @@ public class TouchLatencyActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Trace.beginSection("TouchLatencyActivity onCreate"); setContentView(R.layout.activity_touch_latency); mTouchView = findViewById(R.id.canvasView); + Trace.endSection(); } @Override public boolean onCreateOptionsMenu(Menu menu) { + Trace.beginSection("TouchLatencyActivity onCreateOptionsMenu"); // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_touch_latency, menu); + Trace.endSection(); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { + Trace.beginSection("TouchLatencyActivity onOptionsItemSelected"); // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. @@ -203,6 +222,7 @@ public class TouchLatencyActivity extends Activity { mTouchView.changeMode(item); } + Trace.endSection(); return super.onOptionsItemSelected(item); } diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml index f8ecc6b80cce..6e020a3daa2b 100644 --- a/tests/net/AndroidTest.xml +++ b/tests/net/AndroidTest.xml @@ -23,5 +23,6 @@ <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="com.android.frameworks.tests.net" /> <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + <option name="hidden-api-checks" value="false"/> </test> </configuration> |