Merge "Force creation of Socket upon Transform application"
diff --git a/api/current.txt b/api/current.txt
index ea2cc0e..7f076cb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37030,7 +37030,7 @@
}
public final class SEService {
- ctor public SEService(android.content.Context, android.se.omapi.SEService.OnConnectedListener);
+ ctor public SEService(android.content.Context, java.util.concurrent.Executor, android.se.omapi.SEService.OnConnectedListener);
method public android.se.omapi.Reader[] getReaders();
method public java.lang.String getVersion();
method public boolean isConnected();
@@ -37038,7 +37038,7 @@
}
public static abstract interface SEService.OnConnectedListener {
- method public abstract void onServiceConnected();
+ method public abstract void onConnected();
}
public final class Session {
@@ -39392,7 +39392,7 @@
method public final void putExtras(android.os.Bundle);
method public final void removeExtras(java.util.List<java.lang.String>);
method public final void removeExtras(java.lang.String...);
- method public void requestBluetoothAudio(java.lang.String);
+ method public void requestBluetoothAudio(android.bluetooth.BluetoothDevice);
method public void sendConnectionEvent(java.lang.String, android.os.Bundle);
method public final void sendRemoteRttRequest();
method public final void sendRttInitiationFailure(int);
@@ -39603,7 +39603,7 @@
method public void onCanAddCallChanged(boolean);
method public void onConnectionEvent(android.telecom.Call, java.lang.String, android.os.Bundle);
method public void onSilenceRinger();
- method public final void requestBluetoothAudio(java.lang.String);
+ method public final void requestBluetoothAudio(android.bluetooth.BluetoothDevice);
method public final void setAudioRoute(int);
method public final void setMuted(boolean);
field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.InCallService";
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index 1f69df8..14727f0 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -32,6 +32,7 @@
import android.util.Log;
import java.util.HashMap;
+import java.util.concurrent.Executor;
/**
* The SEService realises the communication to available Secure Elements on the
@@ -66,7 +67,7 @@
/**
* Called by the framework when the service is connected.
*/
- void onServiceConnected();
+ void onConnected();
}
/**
@@ -75,15 +76,21 @@
*/
private class SEListener extends ISecureElementListener.Stub {
public OnConnectedListener mListener = null;
+ public Executor mExecutor = null;
@Override
public IBinder asBinder() {
return this;
}
- public void onServiceConnected() {
- if (mListener != null) {
- mListener.onServiceConnected();
+ public void onConnected() {
+ if (mListener != null && mExecutor != null) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ mListener.onConnected();
+ }
+ });
}
}
}
@@ -116,22 +123,26 @@
* the specified listener is called or if isConnected() returns
* <code>true</code>. <br>
* The call-back object passed as a parameter will have its
- * onServiceConnected() method called when the connection actually happen.
+ * onConnected() method called when the connection actually happen.
*
* @param context
* the context of the calling application. Cannot be
* <code>null</code>.
* @param listener
* a OnConnectedListener object.
+ * @param executor
+ * an Executor which will be used when invoking the callback.
*/
- public SEService(@NonNull Context context, @NonNull OnConnectedListener listener) {
+ public SEService(@NonNull Context context, @NonNull Executor executor,
+ @NonNull OnConnectedListener listener) {
- if (context == null) {
- throw new NullPointerException("context must not be null");
+ if (context == null || listener == null || executor == null) {
+ throw new NullPointerException("Arguments must not be null");
}
mContext = context;
mSEListener.mListener = listener;
+ mSEListener.mExecutor = executor;
mConnection = new ServiceConnection() {
@@ -140,7 +151,7 @@
mSecureElementService = ISecureElementService.Stub.asInterface(service);
if (mSEListener != null) {
- mSEListener.onServiceConnected();
+ mSEListener.onConnected();
}
Log.i(TAG, "Service onServiceConnected");
}
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index bb5a0ad..a9cd5c8 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -34,6 +34,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Objects;
import java.util.TimeZone;
import java.util.logging.LogManager;
import org.apache.harmony.luni.internal.util.TimezoneGetter;
@@ -67,8 +68,12 @@
* but apps can override that behavior.
*/
private static class LoggingHandler implements Thread.UncaughtExceptionHandler {
+ public volatile boolean mTriggered = false;
+
@Override
public void uncaughtException(Thread t, Throwable e) {
+ mTriggered = true;
+
// Don't re-enter if KillApplicationHandler has already run
if (mCrashing) return;
@@ -96,12 +101,33 @@
/**
* Handle application death from an uncaught exception. The framework
* catches these for the main threads, so this should only matter for
- * threads created by applications. Before this method runs,
- * {@link LoggingHandler} will already have logged details.
+ * threads created by applications. Before this method runs, the given
+ * instance of {@link LoggingHandler} should already have logged details
+ * (and if not it is run first).
*/
private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
+ private final LoggingHandler mLoggingHandler;
+
+ /**
+ * Create a new KillApplicationHandler that follows the given LoggingHandler.
+ * If {@link #uncaughtException(Thread, Throwable) uncaughtException} is called
+ * on the created instance without {@code loggingHandler} having been triggered,
+ * {@link LoggingHandler#uncaughtException(Thread, Throwable)
+ * loggingHandler.uncaughtException} will be called first.
+ *
+ * @param loggingHandler the {@link LoggingHandler} expected to have run before
+ * this instance's {@link #uncaughtException(Thread, Throwable) uncaughtException}
+ * is being called.
+ */
+ public KillApplicationHandler(LoggingHandler loggingHandler) {
+ this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
+ }
+
+ @Override
public void uncaughtException(Thread t, Throwable e) {
try {
+ ensureLogging(t, e);
+
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
@@ -132,6 +158,33 @@
System.exit(10);
}
}
+
+ /**
+ * Ensures that the logging handler has been triggered.
+ *
+ * See b/73380984. This reinstates the pre-O behavior of
+ *
+ * {@code thread.getUncaughtExceptionHandler().uncaughtException(thread, e);}
+ *
+ * logging the exception (in addition to killing the app). This behavior
+ * was never documented / guaranteed but helps in diagnostics of apps
+ * using the pattern.
+ *
+ * If this KillApplicationHandler is invoked the "regular" way (by
+ * {@link Thread#dispatchUncaughtException(Throwable)
+ * Thread.dispatchUncaughtException} in case of an uncaught exception)
+ * then the pre-handler (expected to be {@link #mLoggingHandler}) will already
+ * have run. Otherwise, we manually invoke it here.
+ */
+ private void ensureLogging(Thread t, Throwable e) {
+ if (!mLoggingHandler.mTriggered) {
+ try {
+ mLoggingHandler.uncaughtException(t, e);
+ } catch (Throwable loggingThrowable) {
+ // Ignored.
+ }
+ }
+ }
}
protected static final void commonInit() {
@@ -141,8 +194,9 @@
* set handlers; these apply to all threads in the VM. Apps can replace
* the default handler, but not the pre handler.
*/
- Thread.setUncaughtExceptionPreHandler(new LoggingHandler());
- Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler());
+ LoggingHandler loggingHandler = new LoggingHandler();
+ Thread.setUncaughtExceptionPreHandler(loggingHandler);
+ Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
/*
* Install a TimezoneGetter subclass for ZoneInfo.db
diff --git a/packages/CaptivePortalLogin/Android.mk b/packages/CaptivePortalLogin/Android.mk
index 7dc23ff..8a96b16 100644
--- a/packages/CaptivePortalLogin/Android.mk
+++ b/packages/CaptivePortalLogin/Android.mk
@@ -2,7 +2,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 services.net
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 7828c4c..2a1bbed 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -30,6 +30,7 @@
import android.net.NetworkRequest;
import android.net.Proxy;
import android.net.Uri;
+import android.net.dns.ResolvUtil;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
@@ -118,6 +119,8 @@
// Also initializes proxy system properties.
mCm.bindProcessToNetwork(mNetwork);
+ mCm.setProcessDefaultNetworkForHostResolution(
+ ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
// Proxy system properties must be initialized before setContentView is called because
// setContentView initializes the WebView logic which in turn reads the system properties.
diff --git a/packages/CarrierDefaultApp/Android.mk b/packages/CarrierDefaultApp/Android.mk
index df88afd..5068b3b 100644
--- a/packages/CarrierDefaultApp/Android.mk
+++ b/packages/CarrierDefaultApp/Android.mk
@@ -9,6 +9,8 @@
LOCAL_PRIVATE_PLATFORM_APIS := true
LOCAL_CERTIFICATE := platform
+LOCAL_STATIC_JAVA_LIBRARIES := services.net
+
include $(BUILD_PACKAGE)
# This finds and builds the test apk as well, so a single make does both.
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 95ec83d..7479d9a 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -32,6 +32,7 @@
import android.net.Proxy;
import android.net.TrafficStats;
import android.net.Uri;
+import android.net.dns.ResolvUtil;
import android.net.http.SslError;
import android.os.Bundle;
import android.telephony.CarrierConfigManager;
@@ -115,6 +116,8 @@
requestNetworkForCaptivePortal();
} else {
mCm.bindProcessToNetwork(mNetwork);
+ mCm.setProcessDefaultNetworkForHostResolution(
+ ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
// Start initial page load so WebView finishes loading proxy settings.
// Actual load of mUrl is initiated by MyWebViewClient.
mWebView.loadData("", "text/html", null);
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 36f5a6c..5579849 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -34,22 +34,19 @@
import android.net.Network;
import android.net.NetworkUtils;
import android.net.Uri;
+import android.net.dns.ResolvUtil;
import android.os.Binder;
import android.os.INetworkManagementService;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
-import android.system.GaiException;
-import android.system.OsConstants;
-import android.system.StructAddrinfo;
import android.text.TextUtils;
import android.util.Slog;
import com.android.server.connectivity.MockableSystemProperties;
-import libcore.io.Libcore;
-
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
@@ -126,28 +123,19 @@
}
public static PrivateDnsConfig tryBlockingResolveOf(Network network, String name) {
- final StructAddrinfo hints = new StructAddrinfo();
- // Unnecessary, but expressly no AI_ADDRCONFIG.
- hints.ai_flags = 0;
- // Fetch all IP addresses at once to minimize re-resolution.
- hints.ai_family = OsConstants.AF_UNSPEC;
- hints.ai_socktype = OsConstants.SOCK_DGRAM;
-
try {
- final InetAddress[] ips = Libcore.os.android_getaddrinfo(name, hints, network.netId);
- if (ips != null && ips.length > 0) {
- return new PrivateDnsConfig(name, ips);
- }
- } catch (GaiException ignored) {}
-
- return null;
+ final InetAddress[] ips = ResolvUtil.blockingResolveAllLocally(network, name);
+ return new PrivateDnsConfig(name, ips);
+ } catch (UnknownHostException uhe) {
+ return new PrivateDnsConfig(name, null);
+ }
}
public static Uri[] getPrivateDnsSettingsUris() {
- final Uri[] uris = new Uri[2];
- uris[0] = Settings.Global.getUriFor(PRIVATE_DNS_MODE);
- uris[1] = Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER);
- return uris;
+ return new Uri[]{
+ Settings.Global.getUriFor(PRIVATE_DNS_MODE),
+ Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
+ };
}
private final Context mContext;
@@ -203,7 +191,7 @@
// NetworkMonitor to decide which networks need validation and runs the
// blocking calls to resolve Private DNS strict mode hostnames.
//
- // At this time we do attempt to enable Private DNS on non-Internet
+ // At this time we do not attempt to enable Private DNS on non-Internet
// networks like IMS.
final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.get(netId);
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 504184c..73f4274 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -64,6 +64,8 @@
public static final int DEXOPT_ENABLE_HIDDEN_API_CHECKS = 1 << 10;
/** Indicates that dexopt should convert to CompactDex. */
public static final int DEXOPT_GENERATE_COMPACT_DEX = 1 << 11;
+ /** Indicates that dexopt should generate an app image */
+ public static final int DEXOPT_GENERATE_APP_IMAGE = 1 << 12;
// NOTE: keep in sync with installd
public static final int FLAG_CLEAR_CACHE_ONLY = 1 << 8;
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index faaa3ba..88caf32 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -267,7 +267,7 @@
final StringBuilder builder = new StringBuilder();
// The current version.
- builder.append("8 ");
+ builder.append("9 ");
builder.append("dexopt");
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 5f46d77..f9e11f9 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -60,6 +60,7 @@
import static com.android.server.pm.Installer.DEXOPT_IDLE_BACKGROUND_JOB;
import static com.android.server.pm.Installer.DEXOPT_ENABLE_HIDDEN_API_CHECKS;
import static com.android.server.pm.Installer.DEXOPT_GENERATE_COMPACT_DEX;
+import static com.android.server.pm.Installer.DEXOPT_GENERATE_APP_IMAGE;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
@@ -523,6 +524,10 @@
return getDexFlags(pkg.applicationInfo, compilerFilter, options);
}
+ private boolean isAppImageEnabled() {
+ return SystemProperties.get("dalvik.vm.appimageformat", "").length() > 0;
+ }
+
private int getDexFlags(ApplicationInfo info, String compilerFilter, DexoptOptions options) {
int flags = info.flags;
boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
@@ -549,6 +554,14 @@
case PackageManagerService.REASON_INSTALL:
generateCompactDex = false;
}
+ // Use app images only if it is enabled and we are compiling
+ // profile-guided (so the app image doesn't conservatively contain all classes).
+ // If the app didn't request for the splits to be loaded in isolation or if it does not
+ // declare inter-split dependencies, then all the splits will be loaded in the base
+ // apk class loader (in the order of their definition, otherwise disable app images
+ // because they are unsupported for multiple class loaders. b/7269679
+ boolean generateAppImage = isProfileGuidedFilter && (info.splitDependencies == null ||
+ !info.requestsIsolatedSplitLoading()) && isAppImageEnabled();
int dexFlags =
(isPublic ? DEXOPT_PUBLIC : 0)
| (debuggable ? DEXOPT_DEBUGGABLE : 0)
@@ -556,6 +569,7 @@
| (options.isBootComplete() ? DEXOPT_BOOTCOMPLETE : 0)
| (options.isDexoptIdleBackgroundJob() ? DEXOPT_IDLE_BACKGROUND_JOB : 0)
| (generateCompactDex ? DEXOPT_GENERATE_COMPACT_DEX : 0)
+ | (generateAppImage ? DEXOPT_GENERATE_APP_IMAGE : 0)
| hiddenApiFlag;
return adjustDexoptFlags(dexFlags);
}
diff --git a/services/net/java/android/net/dns/ResolvUtil.java b/services/net/java/android/net/dns/ResolvUtil.java
new file mode 100644
index 0000000..97d20f4
--- /dev/null
+++ b/services/net/java/android/net/dns/ResolvUtil.java
@@ -0,0 +1,65 @@
+/*
+ * 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 android.net.dns;
+
+import android.net.Network;
+import android.net.NetworkUtils;
+import android.system.GaiException;
+import android.system.OsConstants;
+import android.system.StructAddrinfo;
+
+import libcore.io.Libcore;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+
+/**
+ * DNS resolution utility class.
+ *
+ * @hide
+ */
+public class ResolvUtil {
+ // Non-portable DNS resolution flag.
+ private static final long NETID_USE_LOCAL_NAMESERVERS = 0x80000000L;
+
+ private ResolvUtil() {}
+
+ public static InetAddress[] blockingResolveAllLocally(Network network, String name)
+ throws UnknownHostException {
+ final StructAddrinfo hints = new StructAddrinfo();
+ // Unnecessary, but expressly no AI_ADDRCONFIG.
+ hints.ai_flags = 0;
+ // Fetch all IP addresses at once to minimize re-resolution.
+ hints.ai_family = OsConstants.AF_UNSPEC;
+ hints.ai_socktype = OsConstants.SOCK_DGRAM;
+
+ final Network networkForResolv = getNetworkWithUseLocalNameserversFlag(network);
+
+ try {
+ return Libcore.os.android_getaddrinfo(name, hints, (int) networkForResolv.netId);
+ } catch (GaiException gai) {
+ gai.rethrowAsUnknownHostException(name + ": TLS-bypass resolution failed");
+ return null; // keep compiler quiet
+ }
+ }
+
+ public static Network getNetworkWithUseLocalNameserversFlag(Network network) {
+ final long netidForResolv = NETID_USE_LOCAL_NAMESERVERS | (long) network.netId;
+ return new Network((int) netidForResolv);
+ }
+}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 9a53d8c..ca444d4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -2598,7 +2598,6 @@
}
/**
- *
* Request audio routing to a specific bluetooth device. Calling this method may result in
* the device routing audio to a different bluetooth device than the one specified if the
* bluetooth stack is unable to route audio to the requested device.
@@ -2609,13 +2608,13 @@
* Used by self-managed {@link ConnectionService}s which wish to use bluetooth audio for a
* self-managed {@link Connection} (see {@link PhoneAccount#CAPABILITY_SELF_MANAGED}.)
* <p>
- * See also {@link InCallService#requestBluetoothAudio(String)}
- * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
- * {@link BluetoothDevice#getAddress()}.
+ * See also {@link InCallService#requestBluetoothAudio(BluetoothDevice)}
+ * @param bluetoothDevice The bluetooth device to connect to.
*/
- public void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+ public void requestBluetoothAudio(@NonNull BluetoothDevice bluetoothDevice) {
for (Listener l : mListeners) {
- l.onAudioRouteChanged(this, CallAudioState.ROUTE_BLUETOOTH, bluetoothAddress);
+ l.onAudioRouteChanged(this, CallAudioState.ROUTE_BLUETOOTH,
+ bluetoothDevice.getAddress());
}
}
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index af65c65..bd25ab2 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -428,12 +428,11 @@
* A list of available devices can be obtained via
* {@link CallAudioState#getSupportedBluetoothDevices()}
*
- * @param bluetoothAddress The address of the bluetooth device to connect to, as returned by
- * {@link BluetoothDevice#getAddress()}.
+ * @param bluetoothDevice The bluetooth device to connect to.
*/
- public final void requestBluetoothAudio(@NonNull String bluetoothAddress) {
+ public final void requestBluetoothAudio(@NonNull BluetoothDevice bluetoothDevice) {
if (mPhone != null) {
- mPhone.requestBluetoothAudio(bluetoothAddress);
+ mPhone.requestBluetoothAudio(bluetoothDevice.getAddress());
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index caf08e9..c2cbd06 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -40,6 +40,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.PersistableBundle;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -214,6 +215,10 @@
return ActivityThread.currentOpPackageName();
}
+ private boolean isSystemProcess() {
+ return Process.myUid() == Process.SYSTEM_UID;
+ }
+
/**
* Returns the multi SIM variant
* Returns DSDS for Dual SIM Dual Standby
@@ -2785,18 +2790,17 @@
* @return ImsiEncryptionInfo Carrier specific information that will be used to encrypt the
* IMSI and IMPI. This includes the public key and the key identifier. This information
* will be stored in the device keystore. The system will return a null when no key was
- * found, and the carrier does not require a key. The system will throw the following
- * exceptions:
- * 1. IllegalArgumentException when an invalid key is sent.
- * 2. RuntimeException if the key is required but not found; and also if there was an
- * internal exception.
+ * found, and the carrier does not require a key. The system will throw
+ * IllegalArgumentException when an invalid key is sent or when key is required but
+ * not found.
* @hide
*/
public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
try {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null) {
- throw new RuntimeException("IMSI error: Subscriber Info is null");
+ Rlog.e(TAG,"IMSI error: Subscriber Info is null");
+ return null;
}
int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
if (keyType != KEY_TYPE_EPDG && keyType != KEY_TYPE_WLAN) {
@@ -2804,19 +2808,46 @@
}
ImsiEncryptionInfo imsiEncryptionInfo = info.getCarrierInfoForImsiEncryption(
subId, keyType, mContext.getOpPackageName());
- if (imsiEncryptionInfo == null
- && isImsiEncryptionRequired(subId, keyType)) {
+ if (imsiEncryptionInfo == null && isImsiEncryptionRequired(subId, keyType)) {
Rlog.e(TAG, "IMSI error: key is required but not found");
- throw new RuntimeException("IMSI error: key is required but not found");
+ throw new IllegalArgumentException("IMSI error: key is required but not found");
}
return imsiEncryptionInfo;
} catch (RemoteException ex) {
Rlog.e(TAG, "getCarrierInfoForImsiEncryption RemoteException" + ex);
- throw new RuntimeException("IMSI error: Remote Exception");
} catch (NullPointerException ex) {
// This could happen before phone restarts due to crashing
Rlog.e(TAG, "getCarrierInfoForImsiEncryption NullPointerException" + ex);
- throw new RuntimeException("IMSI error: Null Pointer exception");
+ }
+ return null;
+ }
+
+ /**
+ * Resets the Carrier Keys in the database. This involves 2 steps:
+ * 1. Delete the keys from the database.
+ * 2. Send an intent to download new Certificates.
+ * <p>
+ * Requires Permission:
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * @hide
+ */
+ public void resetCarrierKeysForImsiEncryption() {
+ try {
+ IPhoneSubInfo info = getSubscriberInfo();
+ if (info == null) {
+ Rlog.e(TAG, "IMSI error: Subscriber Info is null");
+ if (!isSystemProcess()) {
+ throw new RuntimeException("IMSI error: Subscriber Info is null");
+ }
+ return;
+ }
+ int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
+ info.resetCarrierKeysForImsiEncryption(subId, mContext.getOpPackageName());
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getCarrierInfoForImsiEncryption RemoteException" + ex);
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
}
}
@@ -2855,7 +2886,7 @@
* device keystore.
* <p>
* Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
* @param imsiEncryptionInfo which includes the Key Type, the Public Key
* (java.security.PublicKey) and the Key Identifier.and the Key Identifier.
* The keyIdentifier Attribute value pair that helps a server locate
@@ -3801,19 +3832,22 @@
*
* @throws SecurityException if the caller does not have carrier privileges or is not the
* current default dialer
- *
- * @throws IllegalStateException if telephony service is unavailable.
*/
public void sendDialerSpecialCode(String inputCode) {
try {
final ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ if (!isSystemProcess()) {
+ throw new RuntimeException("Telephony service unavailable");
+ }
+ return;
+ }
telephony.sendDialerSpecialCode(mContext.getOpPackageName(), inputCode);
} catch (RemoteException ex) {
// This could happen if binder process crashes.
- ex.rethrowFromSystemServer();
- } catch (NullPointerException ex) {
- // This could happen before phone restarts due to crashing
- throw new IllegalStateException("Telephony service unavailable");
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
}
}
@@ -4965,10 +4999,10 @@
String v = android.provider.Settings.Global.getString(cr, name);
if (index == Integer.MAX_VALUE) {
- throw new RuntimeException("putIntAtIndex index == MAX_VALUE index=" + index);
+ throw new IllegalArgumentException("putIntAtIndex index == MAX_VALUE index=" + index);
}
if (index < 0) {
- throw new RuntimeException("putIntAtIndex index < 0 index=" + index);
+ throw new IllegalArgumentException("putIntAtIndex index < 0 index=" + index);
}
if (v != null) {
valArray = v.split(",");
@@ -7236,7 +7270,6 @@
}
} catch (RemoteException ex) {
// This could happen if binder process crashes.
- ex.rethrowAsRuntimeException();
}
return UNKNOWN_CARRIER_ID;
}
@@ -7261,7 +7294,6 @@
}
} catch (RemoteException ex) {
// This could happen if binder process crashes.
- ex.rethrowAsRuntimeException();
}
return null;
}
@@ -7719,7 +7751,9 @@
}
} catch (RemoteException ex) {
// This could happen if binder process crashes.
- ex.rethrowAsRuntimeException();
+ if (!isSystemProcess()) {
+ ex.rethrowAsRuntimeException();
+ }
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
index 303a068..0ed0820 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl
@@ -152,6 +152,13 @@
in ImsiEncryptionInfo imsiEncryptionInfo);
/**
+ * Resets the Carrier Keys in the database. This involves 2 steps:
+ * 1. Delete the keys from the database.
+ * 2. Send an intent to download new Certificates.
+ */
+ void resetCarrierKeysForImsiEncryption(int subId, String callingPackage);
+
+ /**
* Retrieves the alpha identifier associated with the voice mail number.
*/
String getVoiceMailAlphaTag(String callingPackage);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index f29d993c..51369d0 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -486,4 +486,10 @@
*/
public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE =
"com.android.omadm.service.CONFIGURATION_UPDATE";
+
+ /**
+ * Broadcast action to trigger the Carrier Certificate download.
+ */
+ public static final String ACTION_CARRIER_CERTIFICATE_DOWNLOAD =
+ "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD";
}