diff options
Diffstat (limited to 'core/java')
43 files changed, 3183 insertions, 2141 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index b99d5cd13a77..65f2c02faa85 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2770,7 +2770,7 @@ public final class ActivityThread extends ClientTransactionHandler { memInfo.getTotalPrivateDirty(), memInfo.getTotalPrivateClean(), memInfo.hasSwappedOutPss ? memInfo.getTotalSwappedOutPss() : - memInfo.getTotalSwappedOut(), memInfo.getTotalPss(), + memInfo.getTotalSwappedOut(), memInfo.getTotalRss(), nativeMax+dalvikMax, nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 41cac75cbd75..c89b53e2c415 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -19,6 +19,9 @@ package android.app; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.IIntentReceiver; @@ -1171,6 +1174,30 @@ public final class PendingIntent implements Parcelable { } /** + * Comparison operator on two PendingIntent objects, such that true is returned when they + * represent {@link Intent}s that are equal as per {@link Intent#filterEquals}. + * + * @param other The other PendingIntent to compare against. + * @return True if action, data, type, class, and categories on two intents are the same. + * + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @TestApi + @RequiresPermission(android.Manifest.permission.GET_INTENT_SENDER_INTENT) + public boolean intentFilterEquals(@Nullable PendingIntent other) { + if (other == null) { + return false; + } + try { + return ActivityManager.getService().getIntentForIntentSender(other.mTarget) + .filterEquals(getIntent()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Comparison operator on two PendingIntent objects, such that true * is returned then they both represent the same operation from the * same package. This allows you to use {@link #getActivity}, diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 331a0b125ee2..267d029d53fe 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -117,11 +117,13 @@ import android.net.EthernetManager; import android.net.IEthernetManager; import android.net.IIpSecService; import android.net.INetworkPolicyManager; +import android.net.IPacProxyManager; import android.net.IVpnManager; import android.net.IpSecManager; import android.net.NetworkPolicyManager; import android.net.NetworkScoreManager; import android.net.NetworkWatchlistManager; +import android.net.PacProxyManager; import android.net.TetheringManager; import android.net.VpnManager; import android.net.lowpan.ILowpanManager; @@ -346,6 +348,15 @@ public final class SystemServiceRegistry { // (which extends it). SYSTEM_SERVICE_NAMES.put(android.text.ClipboardManager.class, Context.CLIPBOARD_SERVICE); + registerService(Context.PAC_PROXY_SERVICE, PacProxyManager.class, + new CachedServiceFetcher<PacProxyManager>() { + @Override + public PacProxyManager createService(ContextImpl ctx) throws ServiceNotFoundException { + IBinder b = ServiceManager.getServiceOrThrow(Context.PAC_PROXY_SERVICE); + IPacProxyManager service = IPacProxyManager.Stub.asInterface(b); + return new PacProxyManager(ctx.getOuterContext(), service); + }}); + registerService(Context.NETD_SERVICE, IBinder.class, new StaticServiceFetcher<IBinder>() { @Override public IBinder createService() throws ServiceNotFoundException { diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 53aaae0470e2..16413e1a1db6 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -139,7 +139,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage(trackingBug = 181103983) public static final String ACTION_CODEC_CONFIG_CHANGED = "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED"; @@ -684,7 +684,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @return the current codec status * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage(trackingBug = 181103983) @Nullable @RequiresPermission(Manifest.permission.BLUETOOTH) public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) { @@ -713,7 +713,7 @@ public final class BluetoothA2dp implements BluetoothProfile { * @param codecConfig the codec configuration preference * @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @UnsupportedAppUsage(trackingBug = 181103983) @RequiresPermission(Manifest.permission.BLUETOOTH) public void setCodecConfigPreference(@NonNull BluetoothDevice device, @NonNull BluetoothCodecConfig codecConfig) { diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 9c8856650ae0..aa6127904400 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3451,6 +3451,7 @@ public abstract class Context { VIBRATOR_SERVICE, //@hide: STATUS_BAR_SERVICE, CONNECTIVITY_SERVICE, + PAC_PROXY_SERVICE, VCN_MANAGEMENT_SERVICE, //@hide: IP_MEMORY_STORE_SERVICE, IPSEC_SERVICE, @@ -4017,6 +4018,17 @@ public abstract class Context { public static final String CONNECTIVITY_SERVICE = "connectivity"; /** + * Use with {@link #getSystemService(String)} to retrieve a {@link + * android.net.PacProxyManager} for handling management of + * pac proxy information. + * + * @see #getSystemService(String) + * @see android.net.PacProxyManager + * @hide + */ + public static final String PAC_PROXY_SERVICE = "pac_proxy"; + + /** * Use with {@link #getSystemService(String)} to retrieve a {@link android.net.vcn.VcnManager} * for managing Virtual Carrier Networks * diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 6bfc12d8d19e..4d68e90437be 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2329,6 +2329,7 @@ public class Intent implements Parcelable, Cloneable { * @hide */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final String ACTION_CLEAR_DNS_CACHE = "android.intent.action.CLEAR_DNS_CACHE"; /** * Alarm Changed Action: This is broadcast when the AlarmClock diff --git a/core/java/android/ddm/DdmHandleHeap.java b/core/java/android/ddm/DdmHandleHeap.java index e24aeb2af3a1..8fa235294451 100644 --- a/core/java/android/ddm/DdmHandleHeap.java +++ b/core/java/android/ddm/DdmHandleHeap.java @@ -30,15 +30,7 @@ import java.nio.ByteBuffer; */ public class DdmHandleHeap extends ChunkHandler { - public static final int CHUNK_HPIF = type("HPIF"); - public static final int CHUNK_HPSG = type("HPSG"); - public static final int CHUNK_HPDU = type("HPDU"); - public static final int CHUNK_HPDS = type("HPDS"); - public static final int CHUNK_NHSG = type("NHSG"); public static final int CHUNK_HPGC = type("HPGC"); - public static final int CHUNK_REAE = type("REAE"); - public static final int CHUNK_REAQ = type("REAQ"); - public static final int CHUNK_REAL = type("REAL"); private static DdmHandleHeap mInstance = new DdmHandleHeap(); @@ -50,15 +42,7 @@ public class DdmHandleHeap extends ChunkHandler { * Register for the messages we're interested in. */ public static void register() { - DdmServer.registerHandler(CHUNK_HPIF, mInstance); - DdmServer.registerHandler(CHUNK_HPSG, mInstance); - DdmServer.registerHandler(CHUNK_HPDU, mInstance); - DdmServer.registerHandler(CHUNK_HPDS, mInstance); - DdmServer.registerHandler(CHUNK_NHSG, mInstance); DdmServer.registerHandler(CHUNK_HPGC, mInstance); - DdmServer.registerHandler(CHUNK_REAE, mInstance); - DdmServer.registerHandler(CHUNK_REAQ, mInstance); - DdmServer.registerHandler(CHUNK_REAL, mInstance); } /** @@ -81,24 +65,8 @@ public class DdmHandleHeap extends ChunkHandler { Log.v("ddm-heap", "Handling " + name(request.type) + " chunk"); int type = request.type; - if (type == CHUNK_HPIF) { - return handleHPIF(request); - } else if (type == CHUNK_HPSG) { - return handleHPSGNHSG(request, false); - } else if (type == CHUNK_HPDU) { - return handleHPDU(request); - } else if (type == CHUNK_HPDS) { - return handleHPDS(request); - } else if (type == CHUNK_NHSG) { - return handleHPSGNHSG(request, true); - } else if (type == CHUNK_HPGC) { + if (type == CHUNK_HPGC) { return handleHPGC(request); - } else if (type == CHUNK_REAE) { - return handleREAE(request); - } else if (type == CHUNK_REAQ) { - return handleREAQ(request); - } else if (type == CHUNK_REAL) { - return handleREAL(request); } else { throw new RuntimeException("Unknown packet " + ChunkHandler.name(type)); @@ -106,112 +74,6 @@ public class DdmHandleHeap extends ChunkHandler { } /* - * Handle a "HeaP InFo" request. - */ - private Chunk handleHPIF(Chunk request) { - ByteBuffer in = wrapChunk(request); - - int when = in.get(); - if (false) - Log.v("ddm-heap", "Heap segment enable: when=" + when); - - boolean ok = DdmVmInternal.heapInfoNotify(when); - if (!ok) { - return createFailChunk(1, "Unsupported HPIF what"); - } else { - return null; // empty response - } - } - - /* - * Handle a "HeaP SeGment" or "Native Heap SeGment" request. - */ - private Chunk handleHPSGNHSG(Chunk request, boolean isNative) { - ByteBuffer in = wrapChunk(request); - - int when = in.get(); - int what = in.get(); - if (false) - Log.v("ddm-heap", "Heap segment enable: when=" + when - + ", what=" + what + ", isNative=" + isNative); - - boolean ok = DdmVmInternal.heapSegmentNotify(when, what, isNative); - if (!ok) { - return createFailChunk(1, "Unsupported HPSG what/when"); - } else { - // TODO: if "when" is non-zero and we want to see a dump - // right away, initiate a GC. - return null; // empty response - } - } - - /* - * Handle a "HeaP DUmp" request. - * - * This currently just returns a result code. We could pull up - * the entire contents of the file and return them, but hprof dump - * files can be a few megabytes. - */ - private Chunk handleHPDU(Chunk request) { - ByteBuffer in = wrapChunk(request); - byte result; - - /* get the filename for the output file */ - int len = in.getInt(); - String fileName = getString(in, len); - if (false) - Log.d("ddm-heap", "Heap dump: file='" + fileName + "'"); - - try { - Debug.dumpHprofData(fileName); - result = 0; - } catch (UnsupportedOperationException uoe) { - Log.w("ddm-heap", "hprof dumps not supported in this VM"); - result = -1; - } catch (IOException ioe) { - result = -1; - } catch (RuntimeException re) { - result = -1; - } - - /* create a non-empty reply so the handler fires on completion */ - byte[] reply = { result }; - return new Chunk(CHUNK_HPDU, reply, 0, reply.length); - } - - /* - * Handle a "HeaP Dump Streaming" request. - * - * This tells the VM to create a heap dump and send it directly to - * DDMS. The dumps are large enough that we don't want to copy the - * data into a byte[] and send it from here. - */ - private Chunk handleHPDS(Chunk request) { - ByteBuffer in = wrapChunk(request); - byte result; - - /* get the filename for the output file */ - if (false) - Log.d("ddm-heap", "Heap dump: [DDMS]"); - - String failMsg = null; - try { - Debug.dumpHprofDataDdms(); - } catch (UnsupportedOperationException uoe) { - failMsg = "hprof dumps not supported in this VM"; - } catch (RuntimeException re) { - failMsg = "Exception: " + re.getMessage(); - } - - if (failMsg != null) { - Log.w("ddm-heap", failMsg); - return createFailChunk(1, failMsg); - } else { - return null; - } - } - - /* * Handle a "HeaP Garbage Collection" request. */ private Chunk handleHPGC(Chunk request) { @@ -223,47 +85,4 @@ public class DdmHandleHeap extends ChunkHandler { return null; // empty response } - - /* - * Handle a "REcent Allocation Enable" request. - */ - private Chunk handleREAE(Chunk request) { - ByteBuffer in = wrapChunk(request); - boolean enable; - - enable = (in.get() != 0); - - if (false) - Log.d("ddm-heap", "Recent allocation enable request: " + enable); - - DdmVmInternal.enableRecentAllocations(enable); - - return null; // empty response - } - - /* - * Handle a "REcent Allocation Query" request. - */ - private Chunk handleREAQ(Chunk request) { - //ByteBuffer in = wrapChunk(request); - - byte[] reply = new byte[1]; - reply[0] = DdmVmInternal.getRecentAllocationStatus() ? (byte)1 :(byte)0; - return new Chunk(CHUNK_REAQ, reply, 0, reply.length); - } - - /* - * Handle a "REcent ALlocations" request. - */ - private Chunk handleREAL(Chunk request) { - //ByteBuffer in = wrapChunk(request); - - if (false) - Log.d("ddm-heap", "Recent allocations request"); - - /* generate the reply in a ready-to-go format */ - byte[] reply = DdmVmInternal.getRecentAllocations(); - return new Chunk(CHUNK_REAL, reply, 0, reply.length); - } } - diff --git a/core/java/android/ddm/DdmHandleThread.java b/core/java/android/ddm/DdmHandleThread.java deleted file mode 100644 index 613ab75f9c1b..000000000000 --- a/core/java/android/ddm/DdmHandleThread.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007 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.ddm; - -import org.apache.harmony.dalvik.ddmc.Chunk; -import org.apache.harmony.dalvik.ddmc.ChunkHandler; -import org.apache.harmony.dalvik.ddmc.DdmServer; -import org.apache.harmony.dalvik.ddmc.DdmVmInternal; -import android.util.Log; -import java.nio.ByteBuffer; - -/** - * Handle thread-related traffic. - */ -public class DdmHandleThread extends ChunkHandler { - - public static final int CHUNK_THEN = type("THEN"); - public static final int CHUNK_THCR = type("THCR"); - public static final int CHUNK_THDE = type("THDE"); - public static final int CHUNK_THST = type("THST"); - public static final int CHUNK_STKL = type("STKL"); - - private static DdmHandleThread mInstance = new DdmHandleThread(); - - - /* singleton, do not instantiate */ - private DdmHandleThread() {} - - /** - * Register for the messages we're interested in. - */ - public static void register() { - DdmServer.registerHandler(CHUNK_THEN, mInstance); - DdmServer.registerHandler(CHUNK_THST, mInstance); - DdmServer.registerHandler(CHUNK_STKL, mInstance); - } - - /** - * Called when the DDM server connects. The handler is allowed to - * send messages to the server. - */ - public void connected() {} - - /** - * Called when the DDM server disconnects. Can be used to disable - * periodic transmissions or clean up saved state. - */ - public void disconnected() {} - - /** - * Handle a chunk of data. - */ - public Chunk handleChunk(Chunk request) { - if (false) - Log.v("ddm-thread", "Handling " + name(request.type) + " chunk"); - int type = request.type; - - if (type == CHUNK_THEN) { - return handleTHEN(request); - } else if (type == CHUNK_THST) { - return handleTHST(request); - } else if (type == CHUNK_STKL) { - return handleSTKL(request); - } else { - throw new RuntimeException("Unknown packet " - + ChunkHandler.name(type)); - } - } - - /* - * Handle a "THread notification ENable" request. - */ - private Chunk handleTHEN(Chunk request) { - ByteBuffer in = wrapChunk(request); - - boolean enable = (in.get() != 0); - //Log.i("ddm-thread", "Thread notify enable: " + enable); - - DdmVmInternal.threadNotify(enable); - return null; // empty response - } - - /* - * Handle a "THread STatus" request. This is constructed by the VM. - */ - private Chunk handleTHST(Chunk request) { - ByteBuffer in = wrapChunk(request); - // currently nothing to read from "in" - - //Log.d("ddm-thread", "Thread status request"); - - byte[] status = DdmVmInternal.getThreadStats(); - if (status != null) - return new Chunk(CHUNK_THST, status, 0, status.length); - else - return createFailChunk(1, "Can't build THST chunk"); - } - - /* - * Handle a STacK List request. - * - * This is done by threadId, which isn't great since those are - * recycled. We need a thread serial ID. The Linux tid is an okay - * answer as it's unlikely to recycle at the exact wrong moment. - * However, we're using the short threadId in THST messages, so we - * use them here for consistency. (One thought is to keep the current - * thread ID in the low 16 bits and somehow serialize the top 16 bits.) - */ - private Chunk handleSTKL(Chunk request) { - ByteBuffer in = wrapChunk(request); - int threadId; - - threadId = in.getInt(); - - //Log.d("ddm-thread", "Stack list request " + threadId); - - StackTraceElement[] trace = DdmVmInternal.getStackTraceById(threadId); - if (trace == null) { - return createFailChunk(1, "Stack trace unavailable"); - } else { - return createStackChunk(trace, threadId); - } - } - - /* - * Serialize a StackTraceElement[] into an STKL chunk. - * - * We include the threadId in the response so the other side doesn't have - * to match up requests and responses as carefully. - */ - private Chunk createStackChunk(StackTraceElement[] trace, int threadId) { - int bufferSize = 0; - - bufferSize += 4; // version, flags, whatever - bufferSize += 4; // thread ID - bufferSize += 4; // frame count - for (StackTraceElement elem : trace) { - bufferSize += 4 + elem.getClassName().length() * 2; - bufferSize += 4 + elem.getMethodName().length() * 2; - bufferSize += 4; - if (elem.getFileName() != null) - bufferSize += elem.getFileName().length() * 2; - bufferSize += 4; // line number - } - - ByteBuffer out = ByteBuffer.allocate(bufferSize); - out.putInt(0); - out.putInt(threadId); - out.putInt(trace.length); - for (StackTraceElement elem : trace) { - out.putInt(elem.getClassName().length()); - putString(out, elem.getClassName()); - out.putInt(elem.getMethodName().length()); - putString(out, elem.getMethodName()); - if (elem.getFileName() != null) { - out.putInt(elem.getFileName().length()); - putString(out, elem.getFileName()); - } else { - out.putInt(0); - } - out.putInt(elem.getLineNumber()); - } - - return new Chunk(CHUNK_STKL, out); - } -} - diff --git a/core/java/android/ddm/DdmRegister.java b/core/java/android/ddm/DdmRegister.java index e0faa51a938e..ca1031287e3e 100644 --- a/core/java/android/ddm/DdmRegister.java +++ b/core/java/android/ddm/DdmRegister.java @@ -16,9 +16,10 @@ package android.ddm; -import org.apache.harmony.dalvik.ddmc.DdmServer; import android.util.Log; +import org.apache.harmony.dalvik.ddmc.DdmServer; + /** * Just a place to stick handler registrations, instead of scattering * them around. @@ -46,7 +47,6 @@ public class DdmRegister { if (false) Log.v("ddm", "Registering DDM message handlers"); DdmHandleHello.register(); - DdmHandleThread.register(); DdmHandleHeap.register(); DdmHandleNativeHeap.register(); DdmHandleProfiling.register(); diff --git a/core/java/android/net/EthernetNetworkSpecifier.java b/core/java/android/net/EthernetNetworkSpecifier.java new file mode 100644 index 000000000000..e1685887e806 --- /dev/null +++ b/core/java/android/net/EthernetNetworkSpecifier.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2021 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.text.TextUtils; + +import com.android.internal.util.Preconditions; + +import java.util.Objects; + +/** + * A {@link NetworkSpecifier} used to identify ethernet interfaces. + * + * @see EthernetManager + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public final class EthernetNetworkSpecifier extends NetworkSpecifier implements Parcelable { + + /** + * Name of the network interface. + */ + @NonNull + private final String mInterfaceName; + + public EthernetNetworkSpecifier(@NonNull String interfaceName) { + Preconditions.checkStringNotEmpty(interfaceName); + mInterfaceName = interfaceName; + } + + // This may be null in the future to support specifiers based on data other than the interface + // name. + @Nullable + public String getInterfaceName() { + return mInterfaceName; + } + + @Override + public boolean canBeSatisfiedBy(@Nullable NetworkSpecifier other) { + return equals(other); + } + + @Override + public boolean equals(@Nullable Object o) { + if (!(o instanceof EthernetNetworkSpecifier)) return false; + return TextUtils.equals(mInterfaceName, ((EthernetNetworkSpecifier) o).mInterfaceName); + } + + @Override + public int hashCode() { + return Objects.hashCode(mInterfaceName); + } + + @Override + public String toString() { + return "EthernetNetworkSpecifier (" + mInterfaceName + ")"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + dest.writeString(mInterfaceName); + } + + public static final @NonNull Parcelable.Creator<EthernetNetworkSpecifier> CREATOR = + new Parcelable.Creator<EthernetNetworkSpecifier>() { + public EthernetNetworkSpecifier createFromParcel(Parcel in) { + return new EthernetNetworkSpecifier(in.readString()); + } + public EthernetNetworkSpecifier[] newArray(int size) { + return new EthernetNetworkSpecifier[size]; + } + }; +} diff --git a/core/java/android/net/ParseException.java b/core/java/android/net/IPacProxyInstalledListener.aidl index bcfdd7ef09cc..b1f946e02215 100644 --- a/core/java/android/net/ParseException.java +++ b/core/java/android/net/IPacProxyInstalledListener.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 The Android Open Source Project + * Copyright (C) 2021 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. @@ -16,22 +16,10 @@ package android.net; -import android.annotation.NonNull; +import android.net.Network; +import android.net.ProxyInfo; -/** - * Thrown when parsing failed. - */ -// See non-public class {@link WebAddress}. -public class ParseException extends RuntimeException { - public String response; - - ParseException(@NonNull String response) { - super(response); - this.response = response; - } - - ParseException(@NonNull String response, @NonNull Throwable cause) { - super(response, cause); - this.response = response; - } +/** {@hide} */ +oneway interface IPacProxyInstalledListener { + void onPacProxyInstalled(in Network network, in ProxyInfo proxy); } diff --git a/core/java/android/net/IPacProxyManager.aidl b/core/java/android/net/IPacProxyManager.aidl new file mode 100644 index 000000000000..8f65c56662ef --- /dev/null +++ b/core/java/android/net/IPacProxyManager.aidl @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2021, 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 perNmissions and + * limitations under the License. + */ + +package android.net; + +import android.net.IPacProxyInstalledListener; +import android.net.ProxyInfo; + +/** {@hide} */ +interface IPacProxyManager +{ + void addListener(IPacProxyInstalledListener listener); + void removeListener(IPacProxyInstalledListener listener); + void setCurrentProxyScriptUrl(in ProxyInfo proxyInfo); +} diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index a5ece7b713c7..b037261f0bc2 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -179,21 +179,6 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> { } /** - * Build a {@link NetworkIdentity} from the given {@link NetworkState} and - * {@code subType}, assuming that any mobile networks are using the current IMSI. - * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_* - * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not. - */ - // TODO: Delete this function after NetworkPolicyManagerService finishes the migration. - public static NetworkIdentity buildNetworkIdentity(Context context, - NetworkState state, boolean defaultNetwork, @NetworkType int subType) { - final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network, - state.networkCapabilities, state.linkProperties, state.subscriberId, - state.legacyNetworkType); - return buildNetworkIdentity(context, snapshot, defaultNetwork, subType); - } - - /** * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and * {@code subType}, assuming that any mobile networks are using the current IMSI. * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_* diff --git a/core/java/android/net/NetworkScore.aidl b/core/java/android/net/NetworkScore.aidl new file mode 100644 index 000000000000..af12dcf7f17a --- /dev/null +++ b/core/java/android/net/NetworkScore.aidl @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2021, 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; + +parcelable NetworkScore; + diff --git a/core/java/android/net/NetworkScore.java b/core/java/android/net/NetworkScore.java new file mode 100644 index 000000000000..f47801002296 --- /dev/null +++ b/core/java/android/net/NetworkScore.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2021 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; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Object representing the quality of a network as perceived by the user. + * + * A NetworkScore object represents the characteristics of a network that affects how good the + * network is considered for a particular use. + * @hide + */ +// TODO : @SystemApi when the implementation is complete +public final class NetworkScore implements Parcelable { + // This will be removed soon. Do *NOT* depend on it for any new code that is not part of + // a migration. + private final int mLegacyInt; + + /** @hide */ + NetworkScore(final int legacyInt) { + this.mLegacyInt = legacyInt; + } + + private NetworkScore(@NonNull final Parcel in) { + mLegacyInt = in.readInt(); + } + + public int getLegacyInt() { + return mLegacyInt; + } + + @Override + public String toString() { + return "Score(" + mLegacyInt + ")"; + } + + @Override + public void writeToParcel(@NonNull final Parcel dest, final int flags) { + dest.writeInt(mLegacyInt); + } + + @Override + public int describeContents() { + return 0; + } + + @NonNull public static final Creator<NetworkScore> CREATOR = new Creator<>() { + @Override + @NonNull + public NetworkScore createFromParcel(@NonNull final Parcel in) { + return new NetworkScore(in); + } + + @Override + @NonNull + public NetworkScore[] newArray(int size) { + return new NetworkScore[size]; + } + }; + + /** + * A builder for NetworkScore. + */ + public static final class Builder { + private static final int INVALID_LEGACY_INT = Integer.MIN_VALUE; + private int mLegacyInt = INVALID_LEGACY_INT; + + /** + * Sets the legacy int for this score. + * + * Do not rely on this. It will be gone by the time S is released. + * + * @param score the legacy int + * @return this + */ + @NonNull + public Builder setLegacyInt(final int score) { + mLegacyInt = score; + return this; + } + + /** + * Builds this NetworkScore. + * @return The built NetworkScore object. + */ + @NonNull + public NetworkScore build() { + return new NetworkScore(mLegacyInt); + } + } +} diff --git a/core/java/android/net/PacProxyManager.java b/core/java/android/net/PacProxyManager.java new file mode 100644 index 000000000000..8f7ad8c335ca --- /dev/null +++ b/core/java/android/net/PacProxyManager.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2021 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; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.annotation.SystemService; +import android.content.Context; +import android.os.Binder; +import android.os.RemoteException; + +import com.android.internal.annotations.GuardedBy; + +import java.util.HashMap; +import java.util.Objects; +import java.util.concurrent.Executor; + +/** + * @hide + */ +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +@SystemService(Context.PAC_PROXY_SERVICE) +public class PacProxyManager { + private final Context mContext; + private final IPacProxyManager mService; + @GuardedBy("mListenerMap") + private final HashMap<PacProxyInstalledListener, PacProxyInstalledListenerProxy> + mListenerMap = new HashMap<>(); + + /** @hide */ + public PacProxyManager(Context context, IPacProxyManager service) { + Objects.requireNonNull(service, "missing IPacProxyManager"); + mContext = context; + mService = service; + } + + /** + * Add a listener to start monitoring events reported by PacProxyService. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void addPacProxyInstalledListener(@NonNull Executor executor, + @NonNull PacProxyInstalledListener listener) { + try { + synchronized (mListenerMap) { + final PacProxyInstalledListenerProxy listenerProxy = + new PacProxyInstalledListenerProxy(executor, listener); + + if (null != mListenerMap.putIfAbsent(listener, listenerProxy)) { + throw new IllegalStateException("Listener is already added."); + } + mService.addListener(listenerProxy); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Remove the listener to stop monitoring the event of PacProxyInstalledListener. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void removePacProxyInstalledListener(@NonNull PacProxyInstalledListener listener) { + try { + synchronized (mListenerMap) { + final PacProxyInstalledListenerProxy listenerProxy = mListenerMap.remove(listener); + if (listenerProxy == null) return; + mService.removeListener(listenerProxy); + } + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Updates the PAC Proxy Installer with current Proxy information. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STACK, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_SETTINGS}) + public void setCurrentProxyScriptUrl(@Nullable ProxyInfo proxy) { + try { + mService.setCurrentProxyScriptUrl(proxy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * A callback interface for monitoring changes of PAC proxy information. + */ + public interface PacProxyInstalledListener { + /** + * Notify that the PAC proxy has been installed. Note that this method will be called with + * a ProxyInfo with an empty PAC URL when the PAC proxy is removed. + * + * This method supports different PAC proxies per-network but not all devices might support + * per-network proxies. In that case it will be applied globally. + * + * @param network the network for which this proxy installed. + * @param proxy the installed proxy. + */ + void onPacProxyInstalled(@Nullable Network network, @NonNull ProxyInfo proxy); + } + + /** + * PacProxyInstalledListener proxy for PacProxyInstalledListener object. + * @hide + */ + public class PacProxyInstalledListenerProxy extends IPacProxyInstalledListener.Stub { + private final Executor mExecutor; + private final PacProxyInstalledListener mListener; + + PacProxyInstalledListenerProxy(Executor executor, PacProxyInstalledListener listener) { + mExecutor = executor; + mListener = listener; + } + + @Override + public void onPacProxyInstalled(Network network, ProxyInfo proxy) { + Binder.withCleanCallingIdentity(() -> { + mExecutor.execute(() -> { + mListener.onPacProxyInstalled(network, proxy); + }); + }); + } + } +} diff --git a/core/java/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java index 326943a27d4e..84b7eecd2027 100644 --- a/core/java/android/net/PacProxySelector.java +++ b/core/java/android/net/PacProxySelector.java @@ -51,7 +51,7 @@ public class PacProxySelector extends ProxySelector { ServiceManager.getService(PROXY_SERVICE)); if (mProxyService == null) { // Added because of b10267814 where mako is restarting. - Log.e(TAG, "PacProxyInstaller: no proxy service"); + Log.e(TAG, "PacProxyService: no proxy service"); } mDefaultList = Lists.newArrayList(java.net.Proxy.NO_PROXY); } diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java index f472ed4381d1..77754d1256a7 100644 --- a/core/java/android/net/VpnManager.java +++ b/core/java/android/net/VpnManager.java @@ -16,12 +16,15 @@ package android.net; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; + import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.annotation.UserIdInt; import android.app.Activity; import android.content.ComponentName; @@ -56,18 +59,21 @@ import java.util.List; */ public class VpnManager { /** Type representing a lack of VPN @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final int TYPE_VPN_NONE = -1; /** * A VPN created by an app using the {@link VpnService} API. * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final int TYPE_VPN_SERVICE = 1; /** * A VPN created using a {@link VpnManager} API such as {@link #startProvisionedVpnProfile}. * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public static final int TYPE_VPN_PLATFORM = 2; /** @@ -76,6 +82,7 @@ public class VpnManager { * @hide */ @Deprecated + @SystemApi(client = MODULE_LIBRARIES) public static final int TYPE_VPN_LEGACY = 3; /** diff --git a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java index de086f63b14d..22d7faf2fe18 100644 --- a/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java +++ b/core/java/android/net/vcn/VcnControlPlaneIkeConfig.java @@ -19,11 +19,13 @@ package android.net.vcn; import static android.net.vcn.VcnControlPlaneConfig.CONFIG_TYPE_IKE; import android.annotation.NonNull; -import android.annotation.Nullable; import android.net.ipsec.ike.IkeSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.vcn.persistablebundleutils.IkeSessionParamsUtils; +import android.net.vcn.persistablebundleutils.TunnelModeChildSessionParamsUtils; import android.os.PersistableBundle; import android.util.ArraySet; +import android.util.Log; import java.util.Objects; @@ -38,14 +40,11 @@ import java.util.Objects; public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { private static final String TAG = VcnControlPlaneIkeConfig.class.getSimpleName(); - // STOPSHIP: b/163604823 Make mIkeParams and mChildParams @NonNull when it is supported to - // construct mIkeParams and mChildParams from PersistableBundles. - private static final String IKE_PARAMS_KEY = "mIkeParams"; - @Nullable private final IkeSessionParams mIkeParams; + @NonNull private final IkeSessionParams mIkeParams; private static final String CHILD_PARAMS_KEY = "mChildParams"; - @Nullable private final TunnelModeChildSessionParams mChildParams; + @NonNull private final TunnelModeChildSessionParams mChildParams; private static final ArraySet<String> BUNDLE_KEY_SET = new ArraySet<>(); @@ -80,11 +79,19 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { final PersistableBundle ikeParamsBundle = in.getPersistableBundle(IKE_PARAMS_KEY); final PersistableBundle childParamsBundle = in.getPersistableBundle(CHILD_PARAMS_KEY); - // STOPSHIP: b/163604823 Support constructing mIkeParams and mChildParams from - // PersistableBundles. + Objects.requireNonNull(ikeParamsBundle, "IKE Session Params was null"); + Objects.requireNonNull(childParamsBundle, "Child Session Params was null"); + + mIkeParams = IkeSessionParamsUtils.fromPersistableBundle(ikeParamsBundle); + mChildParams = TunnelModeChildSessionParamsUtils.fromPersistableBundle(childParamsBundle); + + for (String key : in.keySet()) { + if (!BUNDLE_KEY_SET.contains(key)) { + Log.w(TAG, "Found an unexpected key in the PersistableBundle: " + key); + } + } - mIkeParams = null; - mChildParams = null; + validate(); } private void validate() { @@ -101,9 +108,11 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { @NonNull public PersistableBundle toPersistableBundle() { final PersistableBundle result = super.toPersistableBundle(); - - // STOPSHIP: b/163604823 Support converting mIkeParams and mChildParams to - // PersistableBundles. + result.putPersistableBundle( + IKE_PARAMS_KEY, IkeSessionParamsUtils.toPersistableBundle(mIkeParams)); + result.putPersistableBundle( + CHILD_PARAMS_KEY, + TunnelModeChildSessionParamsUtils.toPersistableBundle(mChildParams)); return result; } @@ -134,10 +143,9 @@ public final class VcnControlPlaneIkeConfig extends VcnControlPlaneConfig { VcnControlPlaneIkeConfig other = (VcnControlPlaneIkeConfig) o; - // STOPSHIP: b/163604823 Also check mIkeParams and mChildParams when it is supported to - // construct mIkeParams and mChildParams from PersistableBundles. They are not checked - // now so that VcnGatewayConnectionConfigTest and VcnConfigTest can pass. - return super.equals(o); + return super.equals(o) + && Objects.equals(mIkeParams, other.mIkeParams) + && Objects.equals(mChildParams, other.mChildParams); } /** @hide */ diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java index 8ebf757760c3..062438c6e5db 100644 --- a/core/java/android/net/vcn/VcnManager.java +++ b/core/java/android/net/vcn/VcnManager.java @@ -73,7 +73,8 @@ import java.util.concurrent.Executor; public class VcnManager { @NonNull private static final String TAG = VcnManager.class.getSimpleName(); - private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder> + private static final Map< + VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder> REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>(); @NonNull private final Context mContext; @@ -93,13 +94,13 @@ public class VcnManager { } /** - * Get all currently registered VcnNetworkPolicyListeners for testing purposes. + * Get all currently registered VcnNetworkPolicyChangeListeners for testing purposes. * * @hide */ @VisibleForTesting(visibility = Visibility.PRIVATE) @NonNull - public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder> + public static Map<VcnNetworkPolicyChangeListener, VcnUnderlyingNetworkPolicyListenerBinder> getAllPolicyListeners() { return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS); } @@ -162,14 +163,14 @@ public class VcnManager { } // TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using - // the new VcnNetworkPolicyListener API + // the new VcnNetworkPolicyChangeListener API /** * VcnUnderlyingNetworkPolicyListener is the interface through which internal system components * can register to receive updates for VCN-underlying Network policies from the System Server. * * @hide */ - public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {} + public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyChangeListener {} /** * Add a listener for VCN-underlying network policy updates. @@ -185,7 +186,7 @@ public class VcnManager { @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnUnderlyingNetworkPolicyListener( @NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) { - addVcnNetworkPolicyListener(executor, listener); + addVcnNetworkPolicyChangeListener(executor, listener); } /** @@ -198,7 +199,7 @@ public class VcnManager { */ public void removeVcnUnderlyingNetworkPolicyListener( @NonNull VcnUnderlyingNetworkPolicyListener listener) { - removeVcnNetworkPolicyListener(listener); + removeVcnNetworkPolicyChangeListener(listener); } /** @@ -233,20 +234,20 @@ public class VcnManager { } /** - * VcnNetworkPolicyListener is the interface through which internal system components (e.g. - * Network Factories) can register to receive updates for VCN-underlying Network policies from - * the System Server. + * VcnNetworkPolicyChangeListener is the interface through which internal system components + * (e.g. Network Factories) can register to receive updates for VCN-underlying Network policies + * from the System Server. * * <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks - * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify - * the registrant when VCN Network policies change. Upon receiving this signal, the listener - * must check {@link VcnManager} for the current Network policy result for each of its Networks - * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}. + * should register a VcnNetworkPolicyChangeListener. VcnManager will then use this listener to + * notify the registrant when VCN Network policies change. Upon receiving this signal, the + * listener must check {@link VcnManager} for the current Network policy result for each of its + * Networks via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}. * * @hide */ @SystemApi - public interface VcnNetworkPolicyListener { + public interface VcnNetworkPolicyChangeListener { /** * Notifies the implementation that the VCN's underlying Network policy has changed. * @@ -260,20 +261,21 @@ public class VcnManager { /** * Add a listener for VCN-underlying Network policy updates. * - * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is - * registered. No callbacks are guaranteed upon registration. + * <p>A {@link VcnNetworkPolicyChangeListener} is eligible to begin receiving callbacks once it + * is registered. No callbacks are guaranteed upon registration. * * @param executor the Executor that will be used for invoking all calls to the specified * Listener - * @param listener the VcnNetworkPolicyListener to be added + * @param listener the VcnNetworkPolicyChangeListener to be added * @throws SecurityException if the caller does not have permission NETWORK_FACTORY - * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered + * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already + * registered * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) - public void addVcnNetworkPolicyListener( - @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) { + public void addVcnNetworkPolicyChangeListener( + @NonNull Executor executor, @NonNull VcnNetworkPolicyChangeListener listener) { requireNonNull(executor, "executor must not be null"); requireNonNull(listener, "listener must not be null"); @@ -292,15 +294,18 @@ public class VcnManager { } /** - * Remove the specified VcnNetworkPolicyListener from VcnManager. + * Remove the specified VcnNetworkPolicyChangeListener from VcnManager. * * <p>If the specified listener is not currently registered, this is a no-op. * - * @param listener the VcnNetworkPolicyListener that will be removed + * @param listener the VcnNetworkPolicyChangeListener that will be removed + * @throws SecurityException if the caller does not have permission NETWORK_FACTORY * @hide */ @SystemApi - public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) { + @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) + public void removeVcnNetworkPolicyChangeListener( + @NonNull VcnNetworkPolicyChangeListener listener) { requireNonNull(listener, "listener must not be null"); VcnUnderlyingNetworkPolicyListenerBinder binder = @@ -320,8 +325,9 @@ public class VcnManager { * Applies the network policy for a {@link android.net.Network} with the given parameters. * * <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy - * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider - * MUST poll for the updated Network policy based on that Network's capabilities and properties. + * may have changed via {@link VcnNetworkPolicyChangeListener#onPolicyChanged()}, a Network + * Provider MUST poll for the updated Network policy based on that Network's capabilities and + * properties. * * @param networkCapabilities the NetworkCapabilities to be used in determining the Network * policy result for this Network. @@ -532,17 +538,18 @@ public class VcnManager { } /** - * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server. + * Binder wrapper for added VcnNetworkPolicyChangeListeners to receive signals from System + * Server. * * @hide */ private static class VcnUnderlyingNetworkPolicyListenerBinder extends IVcnUnderlyingNetworkPolicyListener.Stub { @NonNull private final Executor mExecutor; - @NonNull private final VcnNetworkPolicyListener mListener; + @NonNull private final VcnNetworkPolicyChangeListener mListener; private VcnUnderlyingNetworkPolicyListenerBinder( - Executor executor, VcnNetworkPolicyListener listener) { + Executor executor, VcnNetworkPolicyChangeListener listener) { mExecutor = executor; mListener = listener; } diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java index b6036b4a6fd1..35b318687773 100644 --- a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java +++ b/core/java/android/net/vcn/persistablebundleutils/CertUtils.java @@ -18,18 +18,24 @@ package android.net.vcn.persistablebundleutils; import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; import java.util.Objects; /** - * CertUtils provides utility methods for constructing Certificate. + * CertUtils provides utility methods for constructing Certificate and PrivateKey. * * @hide */ public class CertUtils { private static final String CERT_TYPE_X509 = "X.509"; + private static final String PRIVATE_KEY_TYPE_RSA = "RSA"; /** Decodes an ASN.1 DER encoded Certificate */ public static X509Certificate certificateFromByteArray(byte[] derEncoded) { @@ -43,4 +49,18 @@ public class CertUtils { throw new IllegalArgumentException("Fail to decode certificate", e); } } + + /** Decodes a PKCS#8 encoded RSA private key */ + public static RSAPrivateKey privateKeyFromByteArray(byte[] pkcs8Encoded) { + Objects.requireNonNull(pkcs8Encoded, "pkcs8Encoded was null"); + PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded); + + try { + KeyFactory keyFactory = KeyFactory.getInstance(PRIVATE_KEY_TYPE_RSA); + + return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { + throw new IllegalArgumentException("Fail to decode PrivateKey", e); + } + } } diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java new file mode 100644 index 000000000000..9d3462cb0b2e --- /dev/null +++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java @@ -0,0 +1,513 @@ +/* + * Copyright (C) 2021 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.vcn.persistablebundleutils; + +import static android.system.OsConstants.AF_INET; +import static android.system.OsConstants.AF_INET6; + +import static com.android.internal.annotations.VisibleForTesting.Visibility; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.net.InetAddresses; +import android.net.eap.EapSessionConfig; +import android.net.ipsec.ike.IkeSaProposal; +import android.net.ipsec.ike.IkeSessionParams; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv4PcscfServer; +import android.net.ipsec.ike.IkeSessionParams.ConfigRequestIpv6PcscfServer; +import android.net.ipsec.ike.IkeSessionParams.IkeAuthConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeAuthEapConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeAuthPskConfig; +import android.net.ipsec.ike.IkeSessionParams.IkeConfigRequest; +import android.os.PersistableBundle; +import android.util.ArraySet; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.vcn.util.PersistableBundleUtils; + +import java.net.InetAddress; +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * Abstract utility class to convert IkeSessionParams to/from PersistableBundle. + * + * @hide + */ +@VisibleForTesting(visibility = Visibility.PRIVATE) +public final class IkeSessionParamsUtils { + private static final String SERVER_HOST_NAME_KEY = "SERVER_HOST_NAME_KEY"; + private static final String SA_PROPOSALS_KEY = "SA_PROPOSALS_KEY"; + private static final String LOCAL_ID_KEY = "LOCAL_ID_KEY"; + private static final String REMOTE_ID_KEY = "REMOTE_ID_KEY"; + private static final String LOCAL_AUTH_KEY = "LOCAL_AUTH_KEY"; + private static final String REMOTE_AUTH_KEY = "REMOTE_AUTH_KEY"; + private static final String CONFIG_REQUESTS_KEY = "CONFIG_REQUESTS_KEY"; + private static final String RETRANS_TIMEOUTS_KEY = "RETRANS_TIMEOUTS_KEY"; + private static final String HARD_LIFETIME_SEC_KEY = "HARD_LIFETIME_SEC_KEY"; + private static final String SOFT_LIFETIME_SEC_KEY = "SOFT_LIFETIME_SEC_KEY"; + private static final String DPD_DELAY_SEC_KEY = "DPD_DELAY_SEC_KEY"; + private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "NATT_KEEPALIVE_DELAY_SEC_KEY"; + private static final String IKE_OPTIONS_KEY = "IKE_OPTIONS_KEY"; + + private static final Set<Integer> IKE_OPTIONS = new ArraySet<>(); + + static { + IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID); + IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH); + IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE); + } + + /** Serializes an IkeSessionParams to a PersistableBundle. */ + @NonNull + public static PersistableBundle toPersistableBundle(@NonNull IkeSessionParams params) { + if (params.getConfiguredNetwork() != null || params.getIke3gppExtension() != null) { + throw new IllegalStateException( + "Cannot convert a IkeSessionParams with a caller configured network or with" + + " 3GPP extension enabled"); + } + + final PersistableBundle result = new PersistableBundle(); + + result.putString(SERVER_HOST_NAME_KEY, params.getServerHostname()); + + final PersistableBundle saProposalBundle = + PersistableBundleUtils.fromList( + params.getSaProposals(), IkeSaProposalUtils::toPersistableBundle); + result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle); + + result.putPersistableBundle( + LOCAL_ID_KEY, + IkeIdentificationUtils.toPersistableBundle(params.getLocalIdentification())); + result.putPersistableBundle( + REMOTE_ID_KEY, + IkeIdentificationUtils.toPersistableBundle(params.getRemoteIdentification())); + + result.putPersistableBundle( + LOCAL_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getLocalAuthConfig())); + result.putPersistableBundle( + REMOTE_AUTH_KEY, AuthConfigUtils.toPersistableBundle(params.getRemoteAuthConfig())); + + final List<ConfigRequest> reqList = new ArrayList<>(); + for (IkeConfigRequest req : params.getConfigurationRequests()) { + reqList.add(new ConfigRequest(req)); + } + final PersistableBundle configReqListBundle = + PersistableBundleUtils.fromList(reqList, ConfigRequest::toPersistableBundle); + result.putPersistableBundle(CONFIG_REQUESTS_KEY, configReqListBundle); + + result.putIntArray(RETRANS_TIMEOUTS_KEY, params.getRetransmissionTimeoutsMillis()); + result.putInt(HARD_LIFETIME_SEC_KEY, params.getHardLifetimeSeconds()); + result.putInt(SOFT_LIFETIME_SEC_KEY, params.getSoftLifetimeSeconds()); + result.putInt(DPD_DELAY_SEC_KEY, params.getDpdDelaySeconds()); + result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, params.getNattKeepAliveDelaySeconds()); + + final List<Integer> enabledIkeOptions = new ArrayList<>(); + for (int option : IKE_OPTIONS) { + if (params.hasIkeOption(option)) { + enabledIkeOptions.add(option); + } + } + + final int[] optionArray = enabledIkeOptions.stream().mapToInt(i -> i).toArray(); + result.putIntArray(IKE_OPTIONS_KEY, optionArray); + + return result; + } + + /** Constructs an IkeSessionParams by deserializing a PersistableBundle. */ + @NonNull + public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle is null"); + + final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(); + + builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY)); + + PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY); + Objects.requireNonNull(in, "SA Proposals was null"); + List<IkeSaProposal> saProposals = + PersistableBundleUtils.toList( + proposalBundle, IkeSaProposalUtils::fromPersistableBundle); + for (IkeSaProposal proposal : saProposals) { + builder.addSaProposal(proposal); + } + + builder.setLocalIdentification( + IkeIdentificationUtils.fromPersistableBundle( + in.getPersistableBundle(LOCAL_ID_KEY))); + builder.setRemoteIdentification( + IkeIdentificationUtils.fromPersistableBundle( + in.getPersistableBundle(REMOTE_ID_KEY))); + + AuthConfigUtils.setBuilderByReadingPersistableBundle( + in.getPersistableBundle(LOCAL_AUTH_KEY), + in.getPersistableBundle(REMOTE_AUTH_KEY), + builder); + + builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY)); + builder.setLifetimeSeconds( + in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY)); + builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY)); + builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY)); + + final PersistableBundle configReqListBundle = in.getPersistableBundle(CONFIG_REQUESTS_KEY); + Objects.requireNonNull(configReqListBundle, "Config request list was null"); + final List<ConfigRequest> reqList = + PersistableBundleUtils.toList(configReqListBundle, ConfigRequest::new); + for (ConfigRequest req : reqList) { + switch (req.type) { + case ConfigRequest.IPV4_P_CSCF_ADDRESS: + if (req.address == null) { + builder.addPcscfServerRequest(AF_INET); + } else { + builder.addPcscfServerRequest(req.address); + } + break; + case ConfigRequest.IPV6_P_CSCF_ADDRESS: + if (req.address == null) { + builder.addPcscfServerRequest(AF_INET6); + } else { + builder.addPcscfServerRequest(req.address); + } + break; + default: + throw new IllegalArgumentException( + "Unrecognized config request type: " + req.type); + } + } + + // Clear IKE Options that are by default enabled + for (int option : IKE_OPTIONS) { + builder.removeIkeOption(option); + } + + final int[] optionArray = in.getIntArray(IKE_OPTIONS_KEY); + for (int option : optionArray) { + builder.addIkeOption(option); + } + + return builder.build(); + } + + private static final class AuthConfigUtils { + private static final int IKE_AUTH_METHOD_PSK = 1; + private static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2; + private static final int IKE_AUTH_METHOD_EAP = 3; + + private static final String AUTH_METHOD_KEY = "AUTH_METHOD_KEY"; + + @NonNull + public static PersistableBundle toPersistableBundle(@NonNull IkeAuthConfig authConfig) { + if (authConfig instanceof IkeAuthPskConfig) { + IkeAuthPskConfig config = (IkeAuthPskConfig) authConfig; + return IkeAuthPskConfigUtils.toPersistableBundle( + config, createPersistableBundle(IKE_AUTH_METHOD_PSK)); + } else if (authConfig instanceof IkeAuthDigitalSignLocalConfig) { + IkeAuthDigitalSignLocalConfig config = (IkeAuthDigitalSignLocalConfig) authConfig; + return IkeAuthDigitalSignConfigUtils.toPersistableBundle( + config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE)); + } else if (authConfig instanceof IkeAuthDigitalSignRemoteConfig) { + IkeAuthDigitalSignRemoteConfig config = (IkeAuthDigitalSignRemoteConfig) authConfig; + return IkeAuthDigitalSignConfigUtils.toPersistableBundle( + config, createPersistableBundle(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE)); + } else if (authConfig instanceof IkeAuthEapConfig) { + IkeAuthEapConfig config = (IkeAuthEapConfig) authConfig; + return IkeAuthEapConfigUtils.toPersistableBundle( + config, createPersistableBundle(IKE_AUTH_METHOD_EAP)); + } else { + throw new IllegalStateException("Invalid IkeAuthConfig subclass"); + } + } + + private static PersistableBundle createPersistableBundle(int type) { + final PersistableBundle result = new PersistableBundle(); + result.putInt(AUTH_METHOD_KEY, type); + return result; + } + + public static void setBuilderByReadingPersistableBundle( + @NonNull PersistableBundle localAuthBundle, + @NonNull PersistableBundle remoteAuthBundle, + @NonNull IkeSessionParams.Builder builder) { + Objects.requireNonNull(localAuthBundle, "localAuthBundle was null"); + Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null"); + + final int localMethodType = localAuthBundle.getInt(AUTH_METHOD_KEY); + final int remoteMethodType = remoteAuthBundle.getInt(AUTH_METHOD_KEY); + switch (localMethodType) { + case IKE_AUTH_METHOD_PSK: + if (remoteMethodType != IKE_AUTH_METHOD_PSK) { + throw new IllegalArgumentException( + "Expect remote auth method to be PSK based, but was " + + remoteMethodType); + } + IkeAuthPskConfigUtils.setBuilderByReadingPersistableBundle( + localAuthBundle, remoteAuthBundle, builder); + return; + case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE: + if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) { + throw new IllegalArgumentException( + "Expect remote auth method to be digital signature based, but was " + + remoteMethodType); + } + IkeAuthDigitalSignConfigUtils.setBuilderByReadingPersistableBundle( + localAuthBundle, remoteAuthBundle, builder); + return; + case IKE_AUTH_METHOD_EAP: + if (remoteMethodType != IKE_AUTH_METHOD_PUB_KEY_SIGNATURE) { + throw new IllegalArgumentException( + "When using EAP for local authentication, expect remote auth" + + " method to be digital signature based, but was " + + remoteMethodType); + } + IkeAuthEapConfigUtils.setBuilderByReadingPersistableBundle( + localAuthBundle, remoteAuthBundle, builder); + return; + default: + throw new IllegalArgumentException( + "Invalid EAP method type " + localMethodType); + } + } + } + + private static final class IkeAuthPskConfigUtils { + private static final String PSK_KEY = "PSK_KEY"; + + @NonNull + public static PersistableBundle toPersistableBundle( + @NonNull IkeAuthPskConfig config, @NonNull PersistableBundle result) { + result.putPersistableBundle( + PSK_KEY, PersistableBundleUtils.fromByteArray(config.getPsk())); + return result; + } + + public static void setBuilderByReadingPersistableBundle( + @NonNull PersistableBundle localAuthBundle, + @NonNull PersistableBundle remoteAuthBundle, + @NonNull IkeSessionParams.Builder builder) { + Objects.requireNonNull(localAuthBundle, "localAuthBundle was null"); + Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null"); + + final PersistableBundle localPskBundle = localAuthBundle.getPersistableBundle(PSK_KEY); + final PersistableBundle remotePskBundle = + remoteAuthBundle.getPersistableBundle(PSK_KEY); + Objects.requireNonNull(localAuthBundle, "Local PSK was null"); + Objects.requireNonNull(remoteAuthBundle, "Remote PSK was null"); + + final byte[] localPsk = PersistableBundleUtils.toByteArray(localPskBundle); + final byte[] remotePsk = PersistableBundleUtils.toByteArray(remotePskBundle); + if (!Arrays.equals(localPsk, remotePsk)) { + throw new IllegalArgumentException("Local PSK and remote PSK are different"); + } + builder.setAuthPsk(localPsk); + } + } + + private static class IkeAuthDigitalSignConfigUtils { + private static final String END_CERT_KEY = "END_CERT_KEY"; + private static final String INTERMEDIATE_CERTS_KEY = "INTERMEDIATE_CERTS_KEY"; + private static final String PRIVATE_KEY_KEY = "PRIVATE_KEY_KEY"; + private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY"; + + @NonNull + public static PersistableBundle toPersistableBundle( + @NonNull IkeAuthDigitalSignLocalConfig config, @NonNull PersistableBundle result) { + try { + result.putPersistableBundle( + END_CERT_KEY, + PersistableBundleUtils.fromByteArray( + config.getClientEndCertificate().getEncoded())); + + final List<X509Certificate> certList = config.getIntermediateCertificates(); + final List<byte[]> encodedCertList = new ArrayList<>(certList.size()); + for (X509Certificate cert : certList) { + encodedCertList.add(cert.getEncoded()); + } + + final PersistableBundle certsBundle = + PersistableBundleUtils.fromList( + encodedCertList, PersistableBundleUtils::fromByteArray); + result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle); + } catch (CertificateEncodingException e) { + throw new IllegalArgumentException("Fail to encode certificate"); + } + + // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore + result.putPersistableBundle( + PRIVATE_KEY_KEY, + PersistableBundleUtils.fromByteArray(config.getPrivateKey().getEncoded())); + return result; + } + + @NonNull + public static PersistableBundle toPersistableBundle( + @NonNull IkeAuthDigitalSignRemoteConfig config, @NonNull PersistableBundle result) { + try { + X509Certificate caCert = config.getRemoteCaCert(); + if (caCert != null) { + result.putPersistableBundle( + TRUST_CERT_KEY, + PersistableBundleUtils.fromByteArray(caCert.getEncoded())); + } + } catch (CertificateEncodingException e) { + throw new IllegalArgumentException("Fail to encode the certificate"); + } + + return result; + } + + public static void setBuilderByReadingPersistableBundle( + @NonNull PersistableBundle localAuthBundle, + @NonNull PersistableBundle remoteAuthBundle, + @NonNull IkeSessionParams.Builder builder) { + Objects.requireNonNull(localAuthBundle, "localAuthBundle was null"); + Objects.requireNonNull(remoteAuthBundle, "remoteAuthBundle was null"); + + // Deserialize localAuth + final PersistableBundle endCertBundle = + localAuthBundle.getPersistableBundle(END_CERT_KEY); + Objects.requireNonNull(endCertBundle, "End cert was null"); + final byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle); + final X509Certificate endCert = CertUtils.certificateFromByteArray(encodedCert); + + final PersistableBundle certsBundle = + localAuthBundle.getPersistableBundle(INTERMEDIATE_CERTS_KEY); + Objects.requireNonNull(certsBundle, "Intermediate certs was null"); + final List<byte[]> encodedCertList = + PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray); + final List<X509Certificate> certList = new ArrayList<>(encodedCertList.size()); + for (byte[] encoded : encodedCertList) { + certList.add(CertUtils.certificateFromByteArray(encoded)); + } + + final PersistableBundle privateKeyBundle = + localAuthBundle.getPersistableBundle(PRIVATE_KEY_KEY); + Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle was null"); + final PrivateKey privateKey = + CertUtils.privateKeyFromByteArray( + PersistableBundleUtils.toByteArray(privateKeyBundle)); + + // Deserialize remoteAuth + final PersistableBundle trustCertBundle = + remoteAuthBundle.getPersistableBundle(TRUST_CERT_KEY); + + X509Certificate caCert = null; + if (trustCertBundle != null) { + final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle); + caCert = CertUtils.certificateFromByteArray(encodedCaCert); + } + + builder.setAuthDigitalSignature(caCert, endCert, certList, privateKey); + } + } + + private static final class IkeAuthEapConfigUtils { + private static final String EAP_CONFIG_KEY = "EAP_CONFIG_KEY"; + + @NonNull + public static PersistableBundle toPersistableBundle( + @NonNull IkeAuthEapConfig config, @NonNull PersistableBundle result) { + result.putPersistableBundle( + EAP_CONFIG_KEY, + EapSessionConfigUtils.toPersistableBundle(config.getEapConfig())); + return result; + } + + public static void setBuilderByReadingPersistableBundle( + @NonNull PersistableBundle localAuthBundle, + @NonNull PersistableBundle remoteAuthBundle, + @NonNull IkeSessionParams.Builder builder) { + // Deserialize localAuth + final PersistableBundle eapBundle = + localAuthBundle.getPersistableBundle(EAP_CONFIG_KEY); + Objects.requireNonNull(eapBundle, "EAP Config was null"); + final EapSessionConfig eapConfig = + EapSessionConfigUtils.fromPersistableBundle(eapBundle); + + // Deserialize remoteAuth + final PersistableBundle trustCertBundle = + remoteAuthBundle.getPersistableBundle( + IkeAuthDigitalSignConfigUtils.TRUST_CERT_KEY); + + X509Certificate serverCaCert = null; + if (trustCertBundle != null) { + final byte[] encodedCaCert = PersistableBundleUtils.toByteArray(trustCertBundle); + serverCaCert = CertUtils.certificateFromByteArray(encodedCaCert); + } + builder.setAuthEap(serverCaCert, eapConfig); + } + } + + private static final class ConfigRequest { + private static final int IPV4_P_CSCF_ADDRESS = 1; + private static final int IPV6_P_CSCF_ADDRESS = 2; + + private static final String TYPE_KEY = "type"; + private static final String ADDRESS_KEY = "address"; + + public final int type; + + // Null when it is an empty request + @Nullable public final InetAddress address; + + ConfigRequest(IkeConfigRequest config) { + if (config instanceof ConfigRequestIpv4PcscfServer) { + type = IPV4_P_CSCF_ADDRESS; + address = ((ConfigRequestIpv4PcscfServer) config).getAddress(); + } else if (config instanceof ConfigRequestIpv6PcscfServer) { + type = IPV6_P_CSCF_ADDRESS; + address = ((ConfigRequestIpv6PcscfServer) config).getAddress(); + } else { + throw new IllegalStateException("Unknown TunnelModeChildConfigRequest"); + } + } + + ConfigRequest(PersistableBundle in) { + Objects.requireNonNull(in, "PersistableBundle was null"); + + type = in.getInt(TYPE_KEY); + + String addressStr = in.getString(ADDRESS_KEY); + if (addressStr == null) { + address = null; + } else { + address = InetAddresses.parseNumericAddress(addressStr); + } + } + + @NonNull + public PersistableBundle toPersistableBundle() { + final PersistableBundle result = new PersistableBundle(); + + result.putInt(TYPE_KEY, type); + if (address != null) { + result.putString(ADDRESS_KEY, address.getHostAddress()); + } + + return result; + } + } +} diff --git a/core/java/android/os/BatteryStatsManager.java b/core/java/android/os/BatteryStatsManager.java index 258e58d7d019..3f4a21878687 100644 --- a/core/java/android/os/BatteryStatsManager.java +++ b/core/java/android/os/BatteryStatsManager.java @@ -24,6 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.net.NetworkStack; import android.os.connectivity.CellularBatteryStats; import android.os.connectivity.WifiBatteryStats; import android.telephony.DataConnectionRealTimeInfo; @@ -416,10 +417,31 @@ public final class BatteryStatsManager { } } + /** + * Notifies the battery stats of a new interface, and the transport types of the network that + * includes that interface. + * + * @param iface The interface of the network. + * @param transportTypes The transport type of the network {@link Transport}. + * @hide + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @RequiresPermission(anyOf = { + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + android.Manifest.permission.NETWORK_STACK}) + public void reportNetworkInterfaceForTransports(@NonNull String iface, + @NonNull int[] transportTypes) throws RuntimeException { + try { + mBatteryStats.noteNetworkInterfaceForTransports(iface, transportTypes); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + private static int getDataConnectionPowerState(boolean isActive) { // TODO: DataConnectionRealTimeInfo is under telephony package but the constants are used - // for both Wifi and mobile. It would make more sense to separate the constants to a generic - // class or move it to generic package. + // for both Wifi and mobile. It would make more sense to separate the constants to a + // generic class or move it to generic package. return isActive ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; } diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index d7d3e5881219..f88b0aefc872 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -138,7 +138,7 @@ public class Build { */ @UnsupportedAppUsage @TestApi - public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1"); + public static final boolean IS_EMULATOR = getString("ro.boot.qemu").equals("1"); /** * A hardware serial number, if available. Alphanumeric only, case-insensitive. diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index a4d6c3845fbf..0264d2335c4b 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -1235,9 +1235,9 @@ public final class FileUtils { } /** - * Creates a directory with name {@code name} under an existing directory {@code baseDir}. - * Returns a {@code File} object representing the directory on success, {@code null} on - * failure. + * Creates a directory with name {@code name} under an existing directory {@code baseDir} if it + * doesn't exist already. Returns a {@code File} object representing the directory if it exists + * and {@code null} if not. * * @hide */ @@ -1247,13 +1247,23 @@ public final class FileUtils { return createDir(dir) ? dir : null; } - /** @hide */ + /** + * Ensure the given directory exists, creating it if needed. This method is threadsafe. + * + * @return false if the directory doesn't exist and couldn't be created + * + * @hide + */ public static boolean createDir(File dir) { + if (dir.mkdir()) { + return true; + } + if (dir.exists()) { return dir.isDirectory(); } - return dir.mkdir(); + return false; } /** diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index 6c49b365c4f3..d9665953dceb 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -54,7 +54,7 @@ per-file HwRemoteBinder.java = file:platform/system/libhwbinder:/OWNERS per-file IHwBinder.java = file:platform/system/libhwbinder:/OWNERS per-file IHwInterface.java = file:platform/system/libhwbinder:/OWNERS -per-file GraphicsEnvironment.java = chrisforbes@google.com, cnorthrop@google.com, lpy@google.com, timvp@google.com, zzyiwei@google.com +per-file GraphicsEnvironment.java = file:platform/frameworks/native:/opengl/OWNERS per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS per-file *Power* = file:/services/core/java/com/android/server/power/OWNERS diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index 769a34eed1dc..13871c51afe2 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -1083,7 +1083,8 @@ public abstract class VibrationEffect implements Parcelable { * * @param primitiveId The primitive to add * @param scale The scale to apply to the intensity of the primitive. - * @param delay The amount of time in milliseconds to wait before playing this primitive + * @param delay The amount of time in milliseconds to wait before playing this primitive, + * starting at the time the previous element in this composition is finished. * @return The {@link Composition} object to enable adding multiple primitives in one chain. */ @NonNull diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java index 18da3a610f36..0ae5ed7bf726 100644 --- a/core/java/android/telephony/PhoneStateListener.java +++ b/core/java/android/telephony/PhoneStateListener.java @@ -17,10 +17,7 @@ package android.telephony; import android.Manifest; -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; @@ -32,16 +29,12 @@ import android.os.Handler; import android.os.HandlerExecutor; import android.os.Looper; import android.telephony.Annotation.CallState; -import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DisconnectCauses; -import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; -import android.telephony.NetworkRegistrationInfo.Domain; import android.telephony.TelephonyManager.DataEnabledReason; -import android.telephony.TelephonyManager.DataState; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; @@ -50,8 +43,6 @@ import com.android.internal.telephony.IPhoneStateListener; import dalvik.system.VMRuntime; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.List; import java.util.Map; @@ -72,49 +63,15 @@ import java.util.concurrent.Executor; * information unless it has the appropriate permissions declared in * its manifest file. Where permissions apply, they are noted in the * appropriate LISTEN_ flags. + * + * @deprecated Use {@link TelephonyCallback} instead. */ +@Deprecated public class PhoneStateListener { private static final String LOG_TAG = "PhoneStateListener"; private static final boolean DBG = false; // STOPSHIP if true /** - * Experiment flag to set the per-pid registration limit for PhoneStateListeners - * - * Limit on registrations of {@link PhoneStateListener}s on a per-pid - * basis. When this limit is exceeded, any calls to {@link TelephonyManager#listen} will fail - * with an {@link IllegalStateException}. - * - * {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that - * TelephonyRegistry runs under are exempt from this limit. - * - * If the value of the flag is less than 1, enforcement of the limit will be disabled. - * @hide - */ - public static final String FLAG_PER_PID_REGISTRATION_LIMIT = - "phone_state_listener_per_pid_registration_limit"; - - /** - * Default value for the per-pid registation limit. - * See {@link #FLAG_PER_PID_REGISTRATION_LIMIT}. - * @hide - */ - public static final int DEFAULT_PER_PID_REGISTRATION_LIMIT = 50; - - /** - * This change enables a limit on the number of {@link PhoneStateListener} objects any process - * may register via {@link TelephonyManager#listen}. The default limit is 50, which may change - * via remote device config updates. - * - * This limit is enforced via an {@link IllegalStateException} thrown from - * {@link TelephonyManager#listen} when the offending process attempts to register one too many - * listeners. - * - * @hide - */ - @ChangeId - public static final long PHONE_STATE_LISTENER_LIMIT_CHANGE_ID = 150880553L; - - /** * Stop listening for updates. * * The PhoneStateListener is not tied to any subscription and unregistered for any update. @@ -126,7 +83,7 @@ public class PhoneStateListener { * * @see #onServiceStateChanged * @see ServiceState - * @deprecated Use {@link ServiceStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.ServiceStateListener} instead. */ @Deprecated public static final int LISTEN_SERVICE_STATE = 0x00000001; @@ -136,7 +93,7 @@ public class PhoneStateListener { * {@more} * * @see #onSignalStrengthChanged - * @deprecated Use {@link SignalStrengthsChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead. */ @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 0x00000002; @@ -152,7 +109,7 @@ public class PhoneStateListener { * voicemail icon. * * @see #onMessageWaitingIndicatorChanged - * @deprecated Use {@link MessageWaitingIndicatorChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.MessageWaitingIndicatorListener} instead. */ @Deprecated public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 0x00000004; @@ -165,7 +122,7 @@ public class PhoneStateListener { * {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onCallForwardingIndicatorChanged - * @deprecated Use {@link CallForwardingIndicatorChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CallForwardingIndicatorListener} instead. */ @Deprecated public static final int LISTEN_CALL_FORWARDING_INDICATOR = 0x00000008; @@ -183,7 +140,7 @@ public class PhoneStateListener { * instead. * * @see #onCellLocationChanged - * @deprecated Use {@link CellLocationChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CellLocationListener} instead. */ @Deprecated public static final int LISTEN_CELL_LOCATION = 0x00000010; @@ -193,7 +150,7 @@ public class PhoneStateListener { * {@more} * * @see #onCallStateChanged - * @deprecated Use {@link CallStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CallStateListener} instead. */ @Deprecated public static final int LISTEN_CALL_STATE = 0x00000020; @@ -202,7 +159,7 @@ public class PhoneStateListener { * Listen for changes to the data connection state (cellular). * * @see #onDataConnectionStateChanged - * @deprecated Use {@link DataConnectionStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead. */ @Deprecated public static final int LISTEN_DATA_CONNECTION_STATE = 0x00000040; @@ -215,7 +172,7 @@ public class PhoneStateListener { * data-traffic icon. * * @see #onDataActivity - * @deprecated Use {@link DataActivityListener} instead. + * @deprecated Use {@link TelephonyCallback.DataActivityListener} instead. */ @Deprecated public static final int LISTEN_DATA_ACTIVITY = 0x00000080; @@ -227,7 +184,7 @@ public class PhoneStateListener { * icon. * * @see #onSignalStrengthsChanged - * @deprecated Use {@link SignalStrengthsChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead. */ @Deprecated public static final int LISTEN_SIGNAL_STRENGTHS = 0x00000100; @@ -239,7 +196,8 @@ public class PhoneStateListener { * @see #onSignalStrengthsChanged * * @hide - * @deprecated Use {@link AlwaysReportedSignalStrengthChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.AlwaysReportedSignalStrengthListener} + * instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) @@ -252,7 +210,7 @@ public class PhoneStateListener { * permission. * * @see #onCellInfoChanged - * @deprecated Use {@link CellInfoChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CellInfoListener} instead. */ @Deprecated public static final int LISTEN_CELL_INFO = 0x00000400; @@ -266,7 +224,7 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @hide - * @deprecated Use {@link PreciseCallStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.PreciseCallStateListener} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @@ -281,7 +239,7 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onPreciseDataConnectionStateChanged - * @deprecated Use {@link PreciseDataConnectionStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.PreciseDataConnectionStateListener} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @@ -307,7 +265,7 @@ public class PhoneStateListener { * * @see #onServiceStateChanged(ServiceState) * @hide - * @deprecated Use {@link SrvccStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.SrvccStateListener} instead. */ @Deprecated @SystemApi @@ -329,7 +287,7 @@ public class PhoneStateListener { * * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean) * @hide - * @deprecated Use {@link CarrierNetworkChangeListener} instead. + * @deprecated Use {@link TelephonyCallback.CarrierNetworkListener} instead. */ @Deprecated public static final int LISTEN_CARRIER_NETWORK_CHANGE = 0x00010000; @@ -350,7 +308,7 @@ public class PhoneStateListener { * * @see #onVoiceActivationStateChanged * @hide - * @deprecated Use {@link VoiceActivationStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.VoiceActivationStateListener} instead. */ @Deprecated @SystemApi @@ -370,7 +328,7 @@ public class PhoneStateListener { * * @see #onDataActivationStateChanged * @hide - * @deprecated Use {@link DataActivationStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.DataActivationStateListener} instead. */ @Deprecated public static final int LISTEN_DATA_ACTIVATION_STATE = 0x00040000; @@ -379,7 +337,7 @@ public class PhoneStateListener { * Listen for changes to the user mobile data state * * @see #onUserMobileDataStateChanged - * @deprecated Use {@link UserMobileDataStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.UserMobileDataStateListener} instead. */ @Deprecated public static final int LISTEN_USER_MOBILE_DATA_STATE = 0x00080000; @@ -392,7 +350,7 @@ public class PhoneStateListener { * {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onDisplayInfoChanged - * @deprecated Use {@link DisplayInfoChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead. */ @Deprecated public static final int LISTEN_DISPLAY_INFO_CHANGED = 0x00100000; @@ -402,7 +360,7 @@ public class PhoneStateListener { * * @see #onPhoneCapabilityChanged * @hide - * @deprecated Use {@link PhoneCapabilityChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.PhoneCapabilityListener} instead. */ @Deprecated public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000; @@ -414,7 +372,7 @@ public class PhoneStateListener { * subscription user selected as default data subscription in DSDS mode. * * @see #onActiveDataSubscriptionIdChanged - * @deprecated Use {@link ActiveDataSubscriptionIdChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.ActiveDataSubscriptionIdListener} instead. */ @Deprecated public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000; @@ -424,7 +382,7 @@ public class PhoneStateListener { * * @see #onRadioPowerStateChanged * @hide - * @deprecated Use {@link RadioPowerStateChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.RadioPowerStateListener} instead. */ @Deprecated @SystemApi @@ -437,7 +395,7 @@ public class PhoneStateListener { * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). * - * @deprecated Use {@link EmergencyNumberListChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.EmergencyNumberListListener} instead. */ @Deprecated public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000; @@ -450,7 +408,7 @@ public class PhoneStateListener { * or the calling app has carrier privileges * (see {@link TelephonyManager#hasCarrierPrivileges}). * - * @deprecated Use {@link CallDisconnectCauseChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CallDisconnectCauseListener} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @@ -465,7 +423,7 @@ public class PhoneStateListener { * * @see #onCallAttributesChanged * @hide - * @deprecated Use {@link CallAttributesChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.CallAttributesListener} instead. */ @Deprecated @SystemApi @@ -481,7 +439,7 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @see #onImsCallDisconnectCauseChanged(ImsReasonInfo) - * @deprecated Use {@link ImsCallDisconnectCauseChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.ImsCallDisconnectCauseListener} instead. */ @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @@ -492,7 +450,7 @@ public class PhoneStateListener { * * @see #onOutgoingEmergencyCall * @hide - * @deprecated Use {@link OutgoingEmergencyCallListener} instead. + * @deprecated Use {@link TelephonyCallback.OutgoingEmergencyCallListener} instead. */ @Deprecated @SystemApi @@ -504,7 +462,7 @@ public class PhoneStateListener { * * @see #onOutgoingEmergencySms * @hide - * @deprecated Use {@link OutgoingEmergencySmsListener} instead. + * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead. */ @Deprecated @SystemApi @@ -525,7 +483,7 @@ public class PhoneStateListener { * of whether the calling app has carrier privileges. * * @see #onRegistrationFailed - * @deprecated Use {@link RegistrationFailedListener} instead. + * @deprecated Use {@link TelephonyCallback.RegistrationFailedListener} instead. */ @Deprecated @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) @@ -541,539 +499,12 @@ public class PhoneStateListener { * of whether the calling app has carrier privileges. * * @see #onBarringInfoChanged - * @deprecated Use {@link BarringInfoChangedListener} instead. + * @deprecated Use {@link TelephonyCallback.BarringInfoListener} instead. */ @Deprecated @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) public static final int LISTEN_BARRING_INFO = 0x80000000; - /** - * Event for changes to the network service state (cellular). - * - * @see ServiceStateChangedListener#onServiceStateChanged - * @see ServiceState - * - * @hide - */ - @SystemApi - public static final int EVENT_SERVICE_STATE_CHANGED = 1; - - /** - * Event for changes to the network signal strength (cellular). - * - * @see SignalStrengthsChangedListener#onSignalStrengthsChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; - - /** - * Event for changes to the message-waiting indicator. - * - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that - * the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - * <p> - * Example: The status bar uses this to determine when to display the - * voicemail icon. - * - * @see MessageWaitingIndicatorChangedListener#onMessageWaitingIndicatorChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; - - /** - * Event for changes to the call-forwarding indicator. - * - * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that - * the calling app has carrier privileges (see - * {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see CallForwardingIndicatorChangedListener#onCallForwardingIndicatorChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; - - /** - * Event for changes to the device's cell location. Note that - * this will result in frequent callbacks to the listener. - * - * If you need regular location updates but want more control over - * the update interval or location precision, you can set up a listener - * through the {@link android.location.LocationManager location manager} - * instead. - * - * @see CellLocationChangedListener#onCellLocationChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) - public static final int EVENT_CELL_LOCATION_CHANGED = 5; - - /** - * Event for changes to the device call state. - * - * @see CallStateChangedListener#onCallStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) - public static final int EVENT_CALL_STATE_CHANGED = 6; - - /** - * Event for changes to the data connection state (cellular). - * - * @see DataConnectionStateChangedListener#onDataConnectionStateChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; - - /** - * Event for changes to the direction of data traffic on the data - * connection (cellular). - * - * Example: The status bar uses this to display the appropriate - * data-traffic icon. - * - * @see DataActivityListener#onDataActivity - * - * @hide - */ - @SystemApi - public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; - - /** - * Event for changes to the network signal strengths (cellular). - * <p> - * Example: The status bar uses this to control the signal-strength - * icon. - * - * @see SignalStrengthsChangedListener#onSignalStrengthsChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; - - /** - * Event for changes of the network signal strengths (cellular) always reported from modem, - * even in some situations such as the screen of the device is off. - * - * @see AlwaysReportedSignalStrengthChangedListener#onSignalStrengthsChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) - public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; - - /** - * Event for changes to observed cell info. - * - * @see CellInfoChangedListener#onCellInfoChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) - public static final int EVENT_CELL_INFO_CHANGED = 11; - - /** - * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing, - * background and foreground calls. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see PreciseCallStateChangedListener#onPreciseCallStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; - - /** - * Event for {@link PreciseDataConnectionState} on the data connection (cellular). - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see PreciseDataConnectionStateChangedListener#onPreciseDataConnectionStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; - - /** - * Event for real time info for all data connections (cellular)). - * - * @see #onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) - * - * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} - * @hide - */ - @Deprecated - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; - - /** - * Event for OEM hook raw event - * - * @see #onOemHookRawEvent - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int EVENT_OEM_HOOK_RAW = 15; - - /** - * Event for changes to the SRVCC state of the active call. - * - * @see SrvccStateChangedListener#onSrvccStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int EVENT_SRVCC_STATE_CHANGED = 16; - - /** - * Event for carrier network changes indicated by a carrier app. - * - * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean) - * @see CarrierNetworkChangeListener#onCarrierNetworkChange - * - * @hide - */ - @SystemApi - public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; - - /** - * Event for changes to the sim voice activation state - * - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been - * fully activated - * - * @see VoiceActivationStateChangedListener#onVoiceActivationStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; - - /** - * Event for changes to the sim data activation state - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING - * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED - * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED - * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN - * - * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been - * fully activated - * - * @see DataActivationStateChangedListener#onDataActivationStateChanged - * @hide - */ - @SystemApi - public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; - - /** - * Event for changes to the user mobile data state - * - * @see UserMobileDataStateChangedListener#onUserMobileDataStateChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; - - /** - * Event for display info changed event. - * - * @see DisplayInfoChangedListener#onDisplayInfoChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_DISPLAY_INFO_CHANGED = 21; - - /** - * Event for changes to the phone capability. - * - * @see PhoneCapabilityChangedListener#onPhoneCapabilityChanged - * - * @hide - */ - @SystemApi - public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; - - /** - * Event for changes to active data subscription ID. Active data subscription is - * the current subscription used to setup Cellular Internet data. For example, - * it could be the current active opportunistic subscription in use, or the - * subscription user selected as default data subscription in DSDS mode. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling - * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see ActiveDataSubscriptionIdChangedListener#onActiveDataSubscriptionIdChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; - - /** - * Event for changes to the radio power state. - * - * @see RadioPowerStateChangedListener#onRadioPowerStateChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; - - /** - * Event for changes to emergency number list based on all active subscriptions. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling - * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see EmergencyNumberListChangedListener#onEmergencyNumberListChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; - - /** - * Event for call disconnect causes which contains {@link DisconnectCause} and - * {@link PreciseDisconnectCause}. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see CallDisconnectCauseChangedListener#onCallDisconnectCauseChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; - - /** - * Event for changes to the call attributes of a currently active call. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see CallAttributesChangedListener#onCallAttributesChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; - - /** - * Event for IMS call disconnect causes which contains - * {@link android.telephony.ims.ImsReasonInfo} - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see ImsCallDisconnectCauseChangedListener#onImsCallDisconnectCauseChanged(ImsReasonInfo) - * - * @hide - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; - - /** - * Event for the emergency number placed from an outgoing call. - * - * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; - - /** - * Event for the emergency number placed from an outgoing SMS. - * - * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; - - /** - * Event for registration failures. - * - * Event for indications that a registration procedure has failed in either the CS or PS - * domain. This indication does not necessarily indicate a change of service state, which should - * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or - * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless - * of whether the calling app has carrier privileges. - * - * @see RegistrationFailedListener#onRegistrationFailed - * - * @hide - */ - @SystemApi - @RequiresPermission(allOf = { - Manifest.permission.READ_PRECISE_PHONE_STATE, - Manifest.permission.ACCESS_FINE_LOCATION - }) - public static final int EVENT_REGISTRATION_FAILURE = 31; - - /** - * Event for Barring Information for the current registered / camped cell. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or - * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless - * of whether the calling app has carrier privileges. - * - * @see BarringInfoChangedListener#onBarringInfoChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(allOf = { - Manifest.permission.READ_PRECISE_PHONE_STATE, - Manifest.permission.ACCESS_FINE_LOCATION - }) - public static final int EVENT_BARRING_INFO_CHANGED = 32; - - /** - * Event for changes to the physical channel configuration. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see PhysicalChannelConfigChangedListener#onPhysicalChannelConfigChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; - - /** - * Event for changes to the data enabled. - * - * Event for indications that the enabled status of current data has changed. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @see DataEnabledChangedListener#onDataEnabledChanged - * - * @hide - */ - @SystemApi - @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - public static final int EVENT_DATA_ENABLED_CHANGED = 34; - - /** - * Event for changes to allowed network list based on all active subscriptions. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling - * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @hide - * @see AllowedNetworkTypesChangedListener#onAllowedNetworkTypesChanged - */ - @SystemApi - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35; - - /** @hide */ - @IntDef(prefix = { "EVENT_" }, value = { - EVENT_SERVICE_STATE_CHANGED, - EVENT_SIGNAL_STRENGTH_CHANGED, - EVENT_MESSAGE_WAITING_INDICATOR_CHANGED, - EVENT_CALL_FORWARDING_INDICATOR_CHANGED, - EVENT_CELL_LOCATION_CHANGED, - EVENT_CALL_STATE_CHANGED, - EVENT_DATA_CONNECTION_STATE_CHANGED, - EVENT_DATA_ACTIVITY_CHANGED, - EVENT_SIGNAL_STRENGTHS_CHANGED, - EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED, - EVENT_CELL_INFO_CHANGED, - EVENT_PRECISE_CALL_STATE_CHANGED, - EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED, - EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED, - EVENT_OEM_HOOK_RAW, - EVENT_SRVCC_STATE_CHANGED, - EVENT_CARRIER_NETWORK_CHANGED, - EVENT_VOICE_ACTIVATION_STATE_CHANGED, - EVENT_DATA_ACTIVATION_STATE_CHANGED, - EVENT_USER_MOBILE_DATA_STATE_CHANGED, - EVENT_DISPLAY_INFO_CHANGED, - EVENT_PHONE_CAPABILITY_CHANGED, - EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED, - EVENT_RADIO_POWER_STATE_CHANGED, - EVENT_EMERGENCY_NUMBER_LIST_CHANGED, - EVENT_CALL_DISCONNECT_CAUSE_CHANGED, - EVENT_CALL_ATTRIBUTES_CHANGED, - EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED, - EVENT_OUTGOING_EMERGENCY_CALL, - EVENT_OUTGOING_EMERGENCY_SMS, - EVENT_REGISTRATION_FAILURE, - EVENT_BARRING_INFO_CHANGED, - EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, - EVENT_DATA_ENABLED_CHANGED, - EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED - }) - @Retention(RetentionPolicy.SOURCE) - public @interface TelephonyEvent {} - /* * Subscription used to listen to the phone state changes * @hide @@ -1085,19 +516,16 @@ public class PhoneStateListener { /** * @hide */ - //TODO: The maxTargetSdk should be S if the build time tool updates it. @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @UnsupportedAppUsage( maxTargetSdk = Build.VERSION_CODES.R, - publicAlternatives = "Use {@code TelephonyManager#registerPhoneStateListener(" + - "Executor, PhoneStateListener)} instead") - public IPhoneStateListener callback; + publicAlternatives = "Use {@code TelephonyManager#registerTelephonyCallback(" + + "Executor, TelephonyCallback)} instead") + public final IPhoneStateListener callback; /** * Create a PhoneStateListener for the Phone with the default subscription. - * If this is created for use with deprecated API - * {@link TelephonyManager#listen(PhoneStateListener, int)}, then this class requires - * Looper.myLooper() not return null. + * This class requires Looper.myLooper() not return null. */ public PhoneStateListener() { this(null, Looper.myLooper()); @@ -1135,10 +563,7 @@ public class PhoneStateListener { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P) public PhoneStateListener(Integer subId, Looper looper) { - if (looper != null) { - setExecutor(new HandlerExecutor(new Handler(looper))); - } - mSubId = subId; + this(subId, new HandlerExecutor(new Handler(looper))); if (subId != null && VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q) { throw new IllegalArgumentException("PhoneStateListener with subId: " @@ -1153,779 +578,18 @@ public class PhoneStateListener { * The Executor must not be null. * * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. - * @deprecated Use - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} instead. */ @Deprecated public PhoneStateListener(@NonNull Executor executor) { - setExecutor(executor); - mSubId = null; + this(null, executor); } - private @NonNull Executor mExecutor; - - /** - * @hide - */ - public void setExecutor(@NonNull @CallbackExecutor Executor executor) { - if (executor == null) { + private PhoneStateListener(Integer subId, Executor e) { + if (e == null) { throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); } - mExecutor = executor; - callback = new IPhoneStateListenerStub(this, mExecutor); - } - - /** - * @hide - */ - public boolean isExecutorSet() { - return mExecutor != null; - } - - /** - * Interface for service state listener. - */ - public interface ServiceStateChangedListener { - /** - * Callback invoked when device service state changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * The instance of {@link ServiceState} passed as an argument here will have various - * levels of location information stripped from it depending on the location permissions - * that your app holds. - * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will - * receive all the information in {@link ServiceState}. - * - * @see ServiceState#STATE_EMERGENCY_ONLY - * @see ServiceState#STATE_IN_SERVICE - * @see ServiceState#STATE_OUT_OF_SERVICE - * @see ServiceState#STATE_POWER_OFF - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onServiceStateChanged(@NonNull ServiceState serviceState); - } - - /** - * Interface for message waiting indicator listener. - */ - public interface MessageWaitingIndicatorChangedListener { - /** - * Callback invoked when the message-waiting indicator changes on the registered - * subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public void onMessageWaitingIndicatorChanged(boolean mwi); - } - - /** - * Interface for call-forwarding indicator listener. - */ - public interface CallForwardingIndicatorChangedListener { - /** - * Callback invoked when the call-forwarding indicator changes on the registered - * subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public void onCallForwardingIndicatorChanged(boolean cfi); - } - - /** - * Interface for device cell location listener. - */ - public interface CellLocationChangedListener { - /** - * Callback invoked when device cell location changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) - public void onCellLocationChanged(@NonNull CellLocation location); - } - - /** - * Interface for call state listener. - */ - public interface CallStateChangedListener { - /** - * Callback invoked when device call state changes. - * <p> - * Reports the state of Telephony (mobile) calls on the device for the registered s - * ubscription. - * <p> - * Note: the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to all subIds. - * <p> - * Note: The state returned here may differ from that returned by - * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that - * calling {@link TelephonyManager#getCallState()} from within this callback may return a - * different state than the callback reports. - * - * @param state call state - * @param phoneNumber call phone number. If application does not have - * {@link android.Manifest.permission#READ_CALL_LOG} permission or carrier - * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be - * passed as an argument. - */ - @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) - public void onCallStateChanged(@CallState int state, @Nullable String phoneNumber); - } - - /** - * Interface for data connection state listener. - */ - public interface DataConnectionStateChangedListener { - /** - * Callback invoked when connection state changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_DISCONNECTED - * @see TelephonyManager#DATA_CONNECTING - * @see TelephonyManager#DATA_CONNECTED - * @see TelephonyManager#DATA_SUSPENDED - * - * @param state is the current state of data connection. - * @param networkType is the current network type of data connection. - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onDataConnectionStateChanged(@DataState int state, - @NetworkType int networkType); - } - - /** - * Interface for data activity state listener. - */ - public interface DataActivityListener { - /** - * Callback invoked when data activity state changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @see TelephonyManager#DATA_ACTIVITY_NONE - * @see TelephonyManager#DATA_ACTIVITY_IN - * @see TelephonyManager#DATA_ACTIVITY_OUT - * @see TelephonyManager#DATA_ACTIVITY_INOUT - * @see TelephonyManager#DATA_ACTIVITY_DORMANT - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onDataActivity(@DataActivityType int direction); - } - - /** - * Interface for network signal strengths listener. - */ - public interface SignalStrengthsChangedListener { - /** - * Callback invoked when network signal strengths changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); - } - - /** - * Interface for network signal strengths listener which always reported from modem. - */ - public interface AlwaysReportedSignalStrengthChangedListener { - /** - * Callback always invoked from modem when network signal strengths changes on the - * registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) - public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); - } - - /** - * Interface for cell info listener. - */ - public interface CellInfoChangedListener { - /** - * Callback invoked when a observed cell info has changed or new cells have been added - * or removed on the registered subscription. - * Note, the registration subscription ID s from {@link TelephonyManager} object - * which registersPhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param cellInfo is the list of currently visible cells. - */ - @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) - public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo); - } - - /** - * Interface for precise device call state listener. - * - * @hide - */ - @SystemApi - public interface PreciseCallStateChangedListener { - /** - * Callback invoked when precise device call state changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param callState {@link PreciseCallState} - */ - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onPreciseCallStateChanged(@NonNull PreciseCallState callState); - } - - /** - * Interface for call disconnect cause listener. - */ - public interface CallDisconnectCauseChangedListener { - /** - * Callback invoked when call disconnect cause changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param disconnectCause {@link DisconnectCause}. - * @param preciseDisconnectCause {@link PreciseDisconnectCause}. - */ - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause, - @PreciseDisconnectCauses int preciseDisconnectCause); - } - - /** - * Interface for IMS call disconnect cause listener. - */ - public interface ImsCallDisconnectCauseChangedListener { - /** - * Callback invoked when IMS call disconnect cause changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. - * - */ - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo); - } - - /** - * Interface for precise data connection state listener. - */ - public interface PreciseDataConnectionStateChangedListener { - /** - * Callback providing update about the default/internet data connection on the registered - * subscription. - * - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} - * or the calling app has carrier privileges - * (see {@link TelephonyManager#hasCarrierPrivileges}). - * - * @param dataConnectionState {@link PreciseDataConnectionState} - */ - @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onPreciseDataConnectionStateChanged( - @NonNull PreciseDataConnectionState dataConnectionState); - } - - /** - * Interface for Single Radio Voice Call Continuity listener. - * - * @hide - */ - @SystemApi - public interface SrvccStateChangedListener { - /** - * Callback invoked when there has been a change in the Single Radio Voice Call Continuity - * (SRVCC) state for the currently active call on the registered subscription. - * - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void onSrvccStateChanged(@SrvccState int srvccState); - } - - /** - * Interface for SIM voice activation state listener. - * - * @hide - */ - @SystemApi - public interface VoiceActivationStateChangedListener { - /** - * Callback invoked when the SIM voice activation state has changed on the registered - * subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM voice activation state - */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void onVoiceActivationStateChanged(@SimActivationState int state); - - } - - /** - * Interface for SIM data activation state listener. - */ - public interface DataActivationStateChangedListener { - /** - * Callback invoked when the SIM data activation state has changed on the registered - * subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state is the current SIM data activation state - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onDataActivationStateChanged(@SimActivationState int state); - } - - /** - * Interface for user mobile data state listener. - */ - public interface UserMobileDataStateChangedListener { - /** - * Callback invoked when the user mobile data state has changed on the registered - * subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param enabled indicates whether the current user mobile data state is enabled or - * disabled. - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onUserMobileDataStateChanged(boolean enabled); - } - - /** - * Interface for display info listener. - */ - public interface DisplayInfoChangedListener { - /** - * Callback invoked when the display info has changed on the registered subscription. - * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user - * based on carrier policy. - * - * @param telephonyDisplayInfo The display information. - */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo); - } - - /** - * Interface for the current emergency number list listener. - */ - public interface EmergencyNumberListChangedListener { - /** - * Callback invoked when the current emergency number list has changed on the registered - * subscription. - * - * Note, the registered subscription is associated with {@link TelephonyManager} object - * on which - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} - * was called. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * given subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param emergencyNumberList Map associating all active subscriptions on the device with - * the list of emergency numbers originating from that - * subscription. - * If there are no active subscriptions, the map will contain a - * single entry with - * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as - * the key and a list of emergency numbers as the value. If no - * emergency number information is available, the value will be - * empty. - */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public void onEmergencyNumberListChanged( - @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList); - } - - /** - * Interface for outgoing emergency call listener. - * - * @hide - */ - @SystemApi - public interface OutgoingEmergencyCallListener { - /** - * Callback invoked when an outgoing call is placed to an emergency number. - * - * This method will be called when an emergency call is placed on any subscription - * (including the no-SIM case), regardless of which subscription this listener was - * registered on. - * - * The default implementation of this method calls - * {@link #onOutgoingEmergencyCall(EmergencyNumber)} for backwards compatibility purposes. - * Do not call {@code super(...)} from within your implementation unless you want - * {@link #onOutgoingEmergencyCall(EmergencyNumber)} to be called as well. - * - * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was - * placed to. - * @param subscriptionId The subscription ID used to place the emergency call. If the - * emergency call was placed without a valid subscription - * (e.g. when there are no SIM cards in the device), this will be - * equal to {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. - */ - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, - int subscriptionId); - } - - /** - * Interface for outgoing emergency sms listener. - * - * @hide - */ - @SystemApi - public interface OutgoingEmergencySmsListener { - /** - * Smsback invoked when an outgoing sms is sent to an emergency number. - * - * This method will be called when an emergency sms is sent on any subscription, - * regardless of which subscription this listener was registered on. - * - * The default implementation of this method calls - * {@link #onOutgoingEmergencySms(EmergencyNumber)} for backwards compatibility purposes. Do - * not call {@code super(...)} from within your implementation unless you want - * {@link #onOutgoingEmergencySms(EmergencyNumber)} to be called as well. - * - * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to. - * @param subscriptionId The subscription ID used to send the emergency sms. - */ - @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) - public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber, - int subscriptionId); - } - - /** - * Interface for phone capability listener. - * - */ - public interface PhoneCapabilityChangedListener { - /** - * Callback invoked when phone capability changes. - * Note, this callback triggers regardless of registered subscription. - * - * @param capability the new phone capability - */ - @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) - public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability); - } - - /** - * Interface for active data subscription ID listener. - */ - public interface ActiveDataSubscriptionIdChangedListener { - /** - * Callback invoked when active data subscription ID changes. - * Note, this callback triggers regardless of registered subscription. - * - * @param subId current subscription used to setup Cellular Internet data. - * For example, it could be the current active opportunistic subscription - * in use, or the subscription user selected as default data subscription in - * DSDS mode. - */ - @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) - public void onActiveDataSubscriptionIdChanged(int subId); - } - - /** - * Interface for modem radio power state listener. - * - * @hide - */ - @SystemApi - public interface RadioPowerStateChangedListener { - /** - * Callback invoked when modem radio power state changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param state the modem radio power state - */ - @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public void onRadioPowerStateChanged(@RadioPowerState int state); - } - - /** - * Interface for carrier network listener. - */ - public interface CarrierNetworkChangeListener { - /** - * Callback invoked when telephony has received notice from a carrier - * app that a network action that could result in connectivity loss - * has been requested by an app using - * {@link android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)} - * - * This is optional and is only used to allow the system to provide alternative UI while - * telephony is performing an action that may result in intentional, temporary network - * lack of connectivity. - * - * Note, this callback is pinned to the registered subscription and will be invoked when - * the notifying carrier app has carrier privilege rule on the registered - * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges} - * - * @param active If the carrier network change is or shortly will be active, - * {@code true} indicate that showing alternative UI, {@code false} otherwise. - */ - public void onCarrierNetworkChange(boolean active); - } - - /** - * Interface for registration failures listener. - */ - public interface RegistrationFailedListener { - /** - * Report that Registration or a Location/Routing/Tracking Area update has failed. - * - * <p>Indicate whenever a registration procedure, including a location, routing, or tracking - * area update fails. This includes procedures that do not necessarily result in a change of - * the modem's registration status. If the modem's registration status changes, that is - * reflected in the onNetworkStateChanged() and subsequent - * get{Voice/Data}RegistrationState(). - * - * <p>Because registration failures are ephemeral, this callback is not sticky. - * Registrants will not receive the most recent past value when registering. - * - * @param cellIdentity the CellIdentity, which must include the globally unique identifier - * for the cell (for example, all components of the CGI or ECGI). - * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those broadcast by the - * cell that was chosen for the failed registration attempt. - * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. - * @param causeCode the primary failure cause code of the procedure. - * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 - * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 - * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 - * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 - * Integer.MAX_VALUE if this value is unused. - * @param additionalCauseCode the cause code of any secondary/combined procedure - * if appropriate. For UMTS, if a combined attach succeeds for - * PS only, then the GMM cause code shall be included as an - * additionalCauseCode. For LTE (ESM), cause codes are in - * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. - */ - @RequiresPermission(allOf = { - Manifest.permission.READ_PRECISE_PHONE_STATE, - Manifest.permission.ACCESS_FINE_LOCATION - }) - public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, - @NonNull String chosenPlmn, @Domain int domain, - int causeCode, int additionalCauseCode); - } - - /** - * Interface for the current allowed network type list listener. This list involves values of - * allowed network type for each of reasons. - * - * @hide - */ - @SystemApi - public interface AllowedNetworkTypesChangedListener { - /** - * Callback invoked when the current allowed network type list has changed on the - * registered subscription. - * Note, the registered subscription is associated with {@link TelephonyManager} object - * on which - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)} - * was called. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * given subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param allowedNetworkTypesList Map associating all allowed network type reasons - * ({@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER}, - * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER}, and - * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}) with reason's allowed - * network type values. - * For example: - * map{{TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER, long type value}, - * {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER, long type value}, - * {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER, long type value}} - */ - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - void onAllowedNetworkTypesChanged( - @NonNull Map<Integer, Long> allowedNetworkTypesList); - } - - /** - * Interface for call attributes listener. - * - * @hide - */ - @SystemApi - public interface CallAttributesChangedListener { - /** - * Callback invoked when the call attributes changes on the registered subscription. - * Note, the registration subscription ID comes from {@link TelephonyManager} object - * which registers PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. - * If this TelephonyManager object was created with - * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the - * subscription ID. Otherwise, this callback applies to - * {@link SubscriptionManager#getDefaultSubscriptionId()}. - * - * @param callAttributes the call attributes - */ - @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - void onCallAttributesChanged(@NonNull CallAttributes callAttributes); - } - - /** - * Interface for barring information listener. - */ - public interface BarringInfoChangedListener { - /** - * Report updated barring information for the current camped/registered cell. - * - * <p>Barring info is provided for all services applicable to the current camped/registered - * cell, for the registered PLMN and current access class/access category. - * - * @param barringInfo for all services on the current cell. - * @see android.telephony.BarringInfo - */ - @RequiresPermission(allOf = { - Manifest.permission.READ_PRECISE_PHONE_STATE, - Manifest.permission.ACCESS_FINE_LOCATION - }) - public void onBarringInfoChanged(@NonNull BarringInfo barringInfo); - } - - /** - * Interface for current physical channel configuration listener. - * @hide - */ - @SystemApi - public interface PhysicalChannelConfigChangedListener { - /** - * Callback invoked when the current physical channel configuration has changed - * - * @param configs List of the current {@link PhysicalChannelConfig}s - */ - @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs); - } - - /** - * Interface for data enabled listener. - * - * @hide - */ - @SystemApi - public interface DataEnabledChangedListener { - /** - * Callback invoked when the data enabled changes. - * - * @param enabled {@code true} if data is enabled, otherwise disabled. - * @param reason Reason for data enabled/disabled. - * See {@link TelephonyManager.DataEnabledReason}. - */ - @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) - public void onDataEnabledChanged(boolean enabled, - @DataEnabledReason int reason); + mSubId = subId; + callback = new IPhoneStateListenerStub(this, e); } /** @@ -1946,7 +610,9 @@ public class PhoneStateListener { * @see ServiceState#STATE_IN_SERVICE * @see ServiceState#STATE_OUT_OF_SERVICE * @see ServiceState#STATE_POWER_OFF + * @deprecated Use {@link TelephonyCallback.ServiceStateListener} instead. */ + @Deprecated public void onServiceStateChanged(ServiceState serviceState) { // default implementation empty } @@ -1979,7 +645,10 @@ public class PhoneStateListener { * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @deprecated Use {@link TelephonyCallback.MessageWaitingIndicatorListener} instead. */ + @Deprecated public void onMessageWaitingIndicatorChanged(boolean mwi) { // default implementation empty } @@ -1992,7 +661,10 @@ public class PhoneStateListener { * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @deprecated Use {@link TelephonyCallback.CallForwardingIndicatorListener} instead. */ + @Deprecated public void onCallForwardingIndicatorChanged(boolean cfi) { // default implementation empty } @@ -2005,7 +677,10 @@ public class PhoneStateListener { * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @deprecated Use {@link TelephonyCallback.CellLocationListener} instead. */ + @Deprecated public void onCellLocationChanged(CellLocation location) { // default implementation empty } @@ -2031,7 +706,10 @@ public class PhoneStateListener { * {@link android.Manifest.permission#READ_CALL_LOG READ_CALL_LOG} permission or carrier * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an empty string will be * passed as an argument. + * + * @deprecated Use {@link TelephonyCallback.CallStateListener} instead. */ + @Deprecated public void onCallStateChanged(@CallState int state, String phoneNumber) { // default implementation empty } @@ -2049,14 +727,19 @@ public class PhoneStateListener { * @see TelephonyManager#DATA_CONNECTING * @see TelephonyManager#DATA_CONNECTED * @see TelephonyManager#DATA_SUSPENDED + * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead. */ + @Deprecated public void onDataConnectionStateChanged(int state) { // default implementation empty } /** * same as above, but with the network type. Both called. + * + * @deprecated Use {@link TelephonyCallback.DataConnectionStateListener} instead. */ + @Deprecated public void onDataConnectionStateChanged(int state, int networkType) { // default implementation empty } @@ -2075,7 +758,9 @@ public class PhoneStateListener { * @see TelephonyManager#DATA_ACTIVITY_OUT * @see TelephonyManager#DATA_ACTIVITY_INOUT * @see TelephonyManager#DATA_ACTIVITY_DORMANT + * @deprecated Use {@link TelephonyCallback.DataActivityListener} instead. */ + @Deprecated public void onDataActivity(int direction) { // default implementation empty } @@ -2088,7 +773,10 @@ public class PhoneStateListener { * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @deprecated Use {@link TelephonyCallback.SignalStrengthsListener} instead. */ + @Deprecated public void onSignalStrengthsChanged(SignalStrength signalStrength) { // default implementation empty } @@ -2104,7 +792,9 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId()}. * * @param cellInfo is the list of currently visible cells. + * @deprecated Use {@link TelephonyCallback.CellInfoListener} instead. */ + @Deprecated public void onCellInfoChanged(List<CellInfo> cellInfo) { // default implementation empty } @@ -2117,11 +807,14 @@ public class PhoneStateListener { * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * * @param callState {@link PreciseCallState} * @hide + * @deprecated Use {@link TelephonyCallback.PreciseCallStateListener} instead. */ @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) @SystemApi + @Deprecated public void onPreciseCallStateChanged(@NonNull PreciseCallState callState) { // default implementation empty } @@ -2137,9 +830,10 @@ public class PhoneStateListener { * * @param disconnectCause {@link DisconnectCause}. * @param preciseDisconnectCause {@link PreciseDisconnectCause}. - * + * @deprecated Use {@link TelephonyCallback.CallDisconnectCauseListener} instead. */ @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + @Deprecated public void onCallDisconnectCauseChanged(@DisconnectCauses int disconnectCause, @PreciseDisconnectCauses int preciseDisconnectCause) { // default implementation empty @@ -2155,9 +849,10 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId()}. * * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. - * + * @deprecated Use {@link TelephonyCallback.ImsCallDisconnectCauseListener} instead. */ @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + @Deprecated public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo) { // default implementation empty } @@ -2178,8 +873,10 @@ public class PhoneStateListener { * (see {@link TelephonyManager#hasCarrierPrivileges}). * * @param dataConnectionState {@link PreciseDataConnectionState} + * @deprecated Use {@link TelephonyCallback.PreciseDataConnectionStateListener} instead. */ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + @Deprecated public void onPreciseDataConnectionStateChanged( @NonNull PreciseDataConnectionState dataConnectionState) { // default implementation empty @@ -2195,8 +892,10 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId()}. * * @hide + * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @Deprecated public void onDataConnectionRealTimeInfoChanged( DataConnectionRealTimeInfo dcRtInfo) { // default implementation empty @@ -2214,11 +913,12 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId()}. * * @hide + * @deprecated Use {@link TelephonyCallback.SrvccStateListener} instead. */ @SystemApi + @Deprecated public void onSrvccStateChanged(@SrvccState int srvccState) { // default implementation empty - } /** @@ -2233,8 +933,10 @@ public class PhoneStateListener { * * @param state is the current SIM voice activation state * @hide + * @deprecated Use {@link TelephonyCallback.VoiceActivationStateListener} instead. */ @SystemApi + @Deprecated public void onVoiceActivationStateChanged(@SimActivationState int state) { // default implementation empty } @@ -2251,7 +953,9 @@ public class PhoneStateListener { * * @param state is the current SIM data activation state * @hide + * @deprecated Use {@link TelephonyCallback.DataActivationStateListener} instead. */ + @Deprecated public void onDataActivationStateChanged(@SimActivationState int state) { // default implementation empty } @@ -2266,7 +970,9 @@ public class PhoneStateListener { * {@link SubscriptionManager#getDefaultSubscriptionId()}. * * @param enabled indicates whether the current user mobile data state is enabled or disabled. + * @deprecated Use {@link TelephonyCallback.UserMobileDataStateListener} instead. */ + @Deprecated public void onUserMobileDataStateChanged(boolean enabled) { // default implementation empty } @@ -2280,8 +986,10 @@ public class PhoneStateListener { * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). * * @param telephonyDisplayInfo The display information. + * @deprecated Use {@link TelephonyCallback.DisplayInfoListener} instead. */ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + @Deprecated public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) { // default implementation empty } @@ -2304,7 +1012,9 @@ public class PhoneStateListener { * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as * the key and a list of emergency numbers as the value. If no * emergency number information is available, the value will be null. + * @deprecated Use {@link TelephonyCallback.EmergencyNumberListListener} instead. */ + @Deprecated public void onEmergencyNumberListChanged( @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList) { // default implementation empty @@ -2317,7 +1027,6 @@ public class PhoneStateListener { * the no-SIM case), regardless of which subscription this listener was registered on. * * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was placed to. - * * @deprecated Use {@link #onOutgoingEmergencyCall(EmergencyNumber, int)}. * @hide */ @@ -2344,9 +1053,11 @@ public class PhoneStateListener { * are no SIM cards in the device), this will be equal to * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. * @hide + * @deprecated Use {@link TelephonyCallback.OutgoingEmergencyCallListener} instead. */ @SystemApi @TestApi + @Deprecated public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, int subscriptionId) { // Default implementation for backwards compatibility @@ -2361,6 +1072,7 @@ public class PhoneStateListener { * * @deprecated Use {@link #onOutgoingEmergencySms(EmergencyNumber, int)}. * @hide + * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead. */ @SystemApi @TestApi @@ -2383,9 +1095,11 @@ public class PhoneStateListener { * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to. * @param subscriptionId The subscription ID used to send the emergency sms. * @hide + * @deprecated Use {@link TelephonyCallback.OutgoingEmergencySmsListener} instead. */ @SystemApi @TestApi + @Deprecated public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber, int subscriptionId) { // Default implementation for backwards compatibility @@ -2395,8 +1109,7 @@ public class PhoneStateListener { /** * Callback invoked when OEM hook raw event is received on the registered subscription. * Note, the registration subId comes from {@link TelephonyManager} object which registers - * PhoneStateListener by - * {@link TelephonyManager#registerPhoneStateListener(Executor, PhoneStateListener)}. + * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. * If this TelephonyManager object was created with * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the * subId. Otherwise, this callback applies to @@ -2405,8 +1118,10 @@ public class PhoneStateListener { * Requires the READ_PRIVILEGED_PHONE_STATE permission. * @param rawData is the byte array of the OEM hook raw data. * @hide + * @deprecated OEM needs a vendor-extension hal and their apps should use that instead */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @Deprecated public void onOemHookRawEvent(byte[] rawData) { // default implementation empty } @@ -2417,7 +1132,9 @@ public class PhoneStateListener { * * @param capability the new phone capability * @hide + * @deprecated Use {@link TelephonyCallback.PhoneCapabilityListener} instead. */ + @Deprecated public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability) { // default implementation empty } @@ -2430,7 +1147,9 @@ public class PhoneStateListener { * @param subId current subscription used to setup Cellular Internet data. * For example, it could be the current active opportunistic subscription in use, * or the subscription user selected as default data subscription in DSDS mode. + * @deprecated Use {@link TelephonyCallback.ActiveDataSubscriptionIdListener} instead. */ + @Deprecated public void onActiveDataSubscriptionIdChanged(int subId) { // default implementation empty } @@ -2447,8 +1166,10 @@ public class PhoneStateListener { * Requires the READ_PRECISE_PHONE_STATE permission. * @param callAttributes the call attributes * @hide + * @deprecated Use {@link TelephonyCallback.CallAttributesListener} instead. */ @SystemApi + @Deprecated public void onCallAttributesChanged(@NonNull CallAttributes callAttributes) { // default implementation empty } @@ -2466,8 +1187,10 @@ public class PhoneStateListener { * * @param state the modem radio power state * @hide + * @deprecated Use {@link TelephonyCallback.RadioPowerStateListener} instead. */ @SystemApi + @Deprecated public void onRadioPowerStateChanged(@RadioPowerState int state) { // default implementation empty } @@ -2485,9 +1208,10 @@ public class PhoneStateListener { * @param active Whether the carrier network change is or shortly * will be active. This value is true to indicate * showing alternative UI and false to stop. - * * @hide + * @deprecated Use {@link TelephonyCallback.CarrierNetworkListener} instead. */ + @Deprecated public void onCarrierNetworkChange(boolean active) { // default implementation empty } @@ -2518,7 +1242,9 @@ public class PhoneStateListener { * For UMTS, if a combined attach succeeds for PS only, then the GMM cause code shall be * included as an additionalCauseCode. For LTE (ESM), cause codes are in * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. + * @deprecated Use {@link TelephonyCallback.RegistrationFailedListener} instead. */ + @Deprecated public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) { // default implementation empty @@ -2531,9 +1257,10 @@ public class PhoneStateListener { * cell, for the registered PLMN and current access class/access category. * * @param barringInfo for all services on the current cell. - * * @see android.telephony.BarringInfo + * @deprecated Use {@link TelephonyCallback.BarringInfoListener} instead. */ + @Deprecated public void onBarringInfoChanged(@NonNull BarringInfo barringInfo) { // default implementation empty } @@ -2829,7 +1556,7 @@ public class PhoneStateListener { Binder.withCleanCallingIdentity( () -> mExecutor.execute(() -> psl.onRegistrationFailed( - cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); + cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); // default implementation empty } @@ -2842,33 +1569,15 @@ public class PhoneStateListener { } public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> configs) { - PhysicalChannelConfigChangedListener listener = - (PhysicalChannelConfigChangedListener) mPhoneStateListenerWeakRef.get(); - if (listener == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged( - configs))); + // default implementation empty } public void onDataEnabledChanged(boolean enabled, @DataEnabledReason int reason) { - DataEnabledChangedListener listener = - (DataEnabledChangedListener) mPhoneStateListenerWeakRef.get(); - if (listener == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute(() -> listener.onDataEnabledChanged( - enabled, reason))); + // default implementation empty } public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) { - AllowedNetworkTypesChangedListener listener = - (AllowedNetworkTypesChangedListener) mPhoneStateListenerWeakRef.get(); - if (listener == null) return; - - Binder.withCleanCallingIdentity( - () -> mExecutor.execute( - () -> listener.onAllowedNetworkTypesChanged(allowedNetworkTypesList))); + // default implementation empty } } diff --git a/core/java/android/telephony/TelephonyCallback.java b/core/java/android/telephony/TelephonyCallback.java new file mode 100644 index 000000000000..a2584cae1b9c --- /dev/null +++ b/core/java/android/telephony/TelephonyCallback.java @@ -0,0 +1,1710 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.telephony; + +import android.Manifest; +import android.annotation.CallbackExecutor; +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.RequiresPermission; +import android.annotation.SystemApi; +import android.compat.annotation.ChangeId; +import android.compat.annotation.UnsupportedAppUsage; +import android.os.Binder; +import android.os.Build; +import android.telephony.emergency.EmergencyNumber; +import android.telephony.ims.ImsReasonInfo; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.telephony.IPhoneStateListener; + +import dalvik.system.VMRuntime; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Executor; + +/** + * A callback class for monitoring changes in specific telephony states + * on the device, including service state, signal strength, message + * waiting indicator (voicemail), and others. + * <p> + * To register a callback, use a {@link TelephonyCallback} which implements interfaces regarding + * EVENT_*. For example, + * FakeServiceStateCallback extends {@link TelephonyCallback} implements + * {@link TelephonyCallback.ServiceStateListener}. + * <p> + * Then override the methods for the state that you wish to receive updates for, and + * pass the executor and your TelephonyCallback object to + * {@link TelephonyManager#registerTelephonyCallback}. + * Methods are called when the state changes, as well as once on initial registration. + * <p> + * Note that access to some telephony information is + * permission-protected. Your application won't receive updates for protected + * information unless it has the appropriate permissions declared in + * its manifest file. Where permissions apply, they are noted in the + * appropriate sub-interfaces. + */ +public class TelephonyCallback { + + /** + * Experiment flag to set the per-pid registration limit for TelephonyCallback + * + * Limit on registrations of {@link TelephonyCallback}s on a per-pid basis. When this limit is + * exceeded, any calls to {@link TelephonyManager#registerTelephonyCallback} will fail with an + * {@link IllegalStateException}. + * + * {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that + * TelephonyRegistry runs under are exempt from this limit. + * + * If the value of the flag is less than 1, enforcement of the limit will be disabled. + * @hide + */ + public static final String FLAG_PER_PID_REGISTRATION_LIMIT = + "phone_state_listener_per_pid_registration_limit"; + + /** + * Default value for the per-pid registration limit. + * See {@link #FLAG_PER_PID_REGISTRATION_LIMIT}. + * @hide + */ + public static final int DEFAULT_PER_PID_REGISTRATION_LIMIT = 50; + + /** + * This change enables a limit on the number of {@link TelephonyCallback} objects any process + * may register via {@link TelephonyManager#registerTelephonyCallback}. The default limit is 50, + * which may change via remote device config updates. + * + * This limit is enforced via an {@link IllegalStateException} thrown from + * {@link TelephonyManager#registerTelephonyCallback} when the offending process attempts to + * register one too many callbacks. + * + * @hide + */ + @ChangeId + public static final long PHONE_STATE_LISTENER_LIMIT_CHANGE_ID = 150880553L; + + /** + * Event for changes to the network service state (cellular). + * + * @hide + * @see ServiceStateListener#onServiceStateChanged + * @see ServiceState + */ + @SystemApi + public static final int EVENT_SERVICE_STATE_CHANGED = 1; + + /** + * Event for changes to the network signal strength (cellular). + * + * @hide + * @see SignalStrengthsListener#onSignalStrengthsChanged + */ + @SystemApi + public static final int EVENT_SIGNAL_STRENGTH_CHANGED = 2; + + /** + * Event for changes to the message-waiting indicator. + * <p> + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that + * the calling app has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges}). + * <p> + * Example: The status bar uses this to determine when to display the + * voicemail icon. + * + * @hide + * @see MessageWaitingIndicatorListener#onMessageWaitingIndicatorChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_MESSAGE_WAITING_INDICATOR_CHANGED = 3; + + /** + * Event for changes to the call-forwarding indicator. + * <p> + * Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE} or that + * the calling app has carrier privileges (see + * {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see CallForwardingIndicatorListener#onCallForwardingIndicatorChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_CALL_FORWARDING_INDICATOR_CHANGED = 4; + + /** + * Event for changes to the device's cell location. Note that + * this will result in frequent listeners to the listener. + * <p> + * If you need regular location updates but want more control over + * the update interval or location precision, you can set up a callback + * through the {@link android.location.LocationManager location manager} + * instead. + * + * @hide + * @see CellLocationListener#onCellLocationChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public static final int EVENT_CELL_LOCATION_CHANGED = 5; + + /** + * Event for changes to the device call state. + * + * @hide + * @see CallStateListener#onCallStateChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) + public static final int EVENT_CALL_STATE_CHANGED = 6; + + /** + * Event for changes to the data connection state (cellular). + * + * @hide + * @see DataConnectionStateListener#onDataConnectionStateChanged + */ + @SystemApi + public static final int EVENT_DATA_CONNECTION_STATE_CHANGED = 7; + + /** + * Event for changes to the direction of data traffic on the data + * connection (cellular). + * <p> + * Example: The status bar uses this to display the appropriate + * data-traffic icon. + * + * @hide + * @see DataActivityListener#onDataActivity + */ + @SystemApi + public static final int EVENT_DATA_ACTIVITY_CHANGED = 8; + + /** + * Event for changes to the network signal strengths (cellular). + * <p> + * Example: The status bar uses this to control the signal-strength + * icon. + * + * @hide + * @see SignalStrengthsListener#onSignalStrengthsChanged + */ + @SystemApi + public static final int EVENT_SIGNAL_STRENGTHS_CHANGED = 9; + + /** + * Event for changes of the network signal strengths (cellular) always reported from modem, + * even in some situations such as the screen of the device is off. + * + * @hide + * @see AlwaysReportedSignalStrengthListener#onSignalStrengthsChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) + public static final int EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED = 10; + + /** + * Event for changes to observed cell info. + * + * @hide + * @see CellInfoListener#onCellInfoChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public static final int EVENT_CELL_INFO_CHANGED = 11; + + /** + * Event for {@link android.telephony.Annotation.PreciseCallStates} of ringing, + * background and foreground calls. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see PreciseCallStateListener#onPreciseCallStateChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PRECISE_CALL_STATE_CHANGED = 12; + + /** + * Event for {@link PreciseDataConnectionState} on the data connection (cellular). + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see PreciseDataConnectionStateListener#onPreciseDataConnectionStateChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED = 13; + + /** + * Event for real time info for all data connections (cellular)). + * + * @hide + * @see PhoneStateListener#onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo) + * @deprecated Use {@link TelephonyManager#requestModemActivityInfo} + */ + @Deprecated + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED = 14; + + /** + * Event for OEM hook raw event + * + * @hide + * @see PhoneStateListener#onOemHookRawEvent + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_OEM_HOOK_RAW = 15; + + /** + * Event for changes to the SRVCC state of the active call. + * + * @hide + * @see SrvccStateListener#onSrvccStateChanged + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_SRVCC_STATE_CHANGED = 16; + + /** + * Event for carrier network changes indicated by a carrier app. + * + * @hide + * @see android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean) + * @see CarrierNetworkListener#onCarrierNetworkChange + */ + @SystemApi + public static final int EVENT_CARRIER_NETWORK_CHANGED = 17; + + /** + * Event for changes to the sim voice activation state + * + * @hide + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * <p> + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates voice service has been + * fully activated + * @see VoiceActivationStateListener#onVoiceActivationStateChanged + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_VOICE_ACTIVATION_STATE_CHANGED = 18; + + /** + * Event for changes to the sim data activation state + * + * @hide + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING + * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED + * @see TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED + * @see TelephonyManager#SIM_ACTIVATION_STATE_UNKNOWN + * <p> + * Example: TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED indicates data service has been + * fully activated + * @see DataActivationStateListener#onDataActivationStateChanged + */ + @SystemApi + public static final int EVENT_DATA_ACTIVATION_STATE_CHANGED = 19; + + /** + * Event for changes to the user mobile data state + * + * @hide + * @see UserMobileDataStateListener#onUserMobileDataStateChanged + */ + @SystemApi + public static final int EVENT_USER_MOBILE_DATA_STATE_CHANGED = 20; + + /** + * Event for display info changed event. + * + * @hide + * @see DisplayInfoListener#onDisplayInfoChanged + */ + @SystemApi + public static final int EVENT_DISPLAY_INFO_CHANGED = 21; + + /** + * Event for changes to the phone capability. + * + * @hide + * @see PhoneCapabilityListener#onPhoneCapabilityChanged + */ + @SystemApi + public static final int EVENT_PHONE_CAPABILITY_CHANGED = 22; + + /** + * Event for changes to active data subscription ID. Active data subscription is + * the current subscription used to setup Cellular Internet data. For example, + * it could be the current active opportunistic subscription in use, or the + * subscription user selected as default data subscription in DSDS mode. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see ActiveDataSubscriptionIdListener#onActiveDataSubscriptionIdChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED = 23; + + /** + * Event for changes to the radio power state. + * + * @hide + * @see RadioPowerStateListener#onRadioPowerStateChanged + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_RADIO_POWER_STATE_CHANGED = 24; + + /** + * Event for changes to emergency number list based on all active subscriptions. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see EmergencyNumberListListener#onEmergencyNumberListChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public static final int EVENT_EMERGENCY_NUMBER_LIST_CHANGED = 25; + + /** + * Event for call disconnect causes which contains {@link DisconnectCause} and + * {@link PreciseDisconnectCause}. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see CallDisconnectCauseListener#onCallDisconnectCauseChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_CALL_DISCONNECT_CAUSE_CHANGED = 26; + + /** + * Event for changes to the call attributes of a currently active call. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see CallAttributesListener#onCallAttributesChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_CALL_ATTRIBUTES_CHANGED = 27; + + /** + * Event for IMS call disconnect causes which contains + * {@link android.telephony.ims.ImsReasonInfo} + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see ImsCallDisconnectCauseListener#onImsCallDisconnectCauseChanged(ImsReasonInfo) + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED = 28; + + /** + * Event for the emergency number placed from an outgoing call. + * + * @hide + * @see OutgoingEmergencyCallListener#onOutgoingEmergencyCall + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int EVENT_OUTGOING_EMERGENCY_CALL = 29; + + /** + * Event for the emergency number placed from an outgoing SMS. + * + * @hide + * @see OutgoingEmergencySmsListener#onOutgoingEmergencySms + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public static final int EVENT_OUTGOING_EMERGENCY_SMS = 30; + + /** + * Event for registration failures. + * <p> + * Event for indications that a registration procedure has failed in either the CS or PS + * domain. This indication does not necessarily indicate a change of service state, which should + * be tracked via {@link #EVENT_SERVICE_STATE_CHANGED}. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or + * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless + * of whether the calling app has carrier privileges. + * + * @hide + * @see RegistrationFailedListener#onRegistrationFailed + */ + @SystemApi + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public static final int EVENT_REGISTRATION_FAILURE = 31; + + /** + * Event for Barring Information for the current registered / camped cell. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} or + * the calling app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * <p>Also requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission, regardless + * of whether the calling app has carrier privileges. + * + * @hide + * @see BarringInfoListener#onBarringInfoChanged + */ + @SystemApi + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public static final int EVENT_BARRING_INFO_CHANGED = 32; + + /** + * Event for changes to the physical channel configuration. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see PhysicalChannelConfigListener#onPhysicalChannelConfigChanged + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 33; + + + /** + * Event for changes to the data enabled. + * <p> + * Event for indications that the enabled status of current data has changed. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see DataEnabledListener#onDataEnabledChanged + */ + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public static final int EVENT_DATA_ENABLED_CHANGED = 34; + + /** + * Event for changes to allowed network list based on all active subscriptions. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PHONE_STATE} or the calling + * app has carrier privileges (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @hide + * @see AllowedNetworkTypesListener#onAllowedNetworkTypesChanged + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED = 35; + + /** + * @hide + */ + @IntDef(prefix = {"EVENT_"}, value = { + EVENT_SERVICE_STATE_CHANGED, + EVENT_SIGNAL_STRENGTH_CHANGED, + EVENT_MESSAGE_WAITING_INDICATOR_CHANGED, + EVENT_CALL_FORWARDING_INDICATOR_CHANGED, + EVENT_CELL_LOCATION_CHANGED, + EVENT_CALL_STATE_CHANGED, + EVENT_DATA_CONNECTION_STATE_CHANGED, + EVENT_DATA_ACTIVITY_CHANGED, + EVENT_SIGNAL_STRENGTHS_CHANGED, + EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED, + EVENT_CELL_INFO_CHANGED, + EVENT_PRECISE_CALL_STATE_CHANGED, + EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED, + EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED, + EVENT_OEM_HOOK_RAW, + EVENT_SRVCC_STATE_CHANGED, + EVENT_CARRIER_NETWORK_CHANGED, + EVENT_VOICE_ACTIVATION_STATE_CHANGED, + EVENT_DATA_ACTIVATION_STATE_CHANGED, + EVENT_USER_MOBILE_DATA_STATE_CHANGED, + EVENT_DISPLAY_INFO_CHANGED, + EVENT_PHONE_CAPABILITY_CHANGED, + EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED, + EVENT_RADIO_POWER_STATE_CHANGED, + EVENT_EMERGENCY_NUMBER_LIST_CHANGED, + EVENT_CALL_DISCONNECT_CAUSE_CHANGED, + EVENT_CALL_ATTRIBUTES_CHANGED, + EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED, + EVENT_OUTGOING_EMERGENCY_CALL, + EVENT_OUTGOING_EMERGENCY_SMS, + EVENT_REGISTRATION_FAILURE, + EVENT_BARRING_INFO_CHANGED, + EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED, + EVENT_DATA_ENABLED_CHANGED, + EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED + }) + @Retention(RetentionPolicy.SOURCE) + public @interface TelephonyEvent { + } + + /** + * @hide + */ + //TODO: The maxTargetSdk should be S if the build time tool updates it. + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public IPhoneStateListener callback; + + /** + * @hide + */ + public void init(@NonNull @CallbackExecutor Executor executor) { + if (executor == null) { + throw new IllegalArgumentException("TelephonyCallback Executor must be non-null"); + } + callback = new IPhoneStateListenerStub(this, executor); + } + + /** + * Interface for service state listener. + */ + public interface ServiceStateListener { + /** + * Callback invoked when device service state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * <p> + * The instance of {@link ServiceState} passed as an argument here will have various + * levels of location information stripped from it depending on the location permissions + * that your app holds. + * Only apps holding the {@link Manifest.permission#ACCESS_FINE_LOCATION} permission will + * receive all the information in {@link ServiceState}. + * + * @see ServiceState#STATE_EMERGENCY_ONLY + * @see ServiceState#STATE_IN_SERVICE + * @see ServiceState#STATE_OUT_OF_SERVICE + * @see ServiceState#STATE_POWER_OFF + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onServiceStateChanged(@NonNull ServiceState serviceState); + } + + /** + * Interface for message waiting indicator listener. + */ + public interface MessageWaitingIndicatorListener { + /** + * Callback invoked when the message-waiting indicator changes on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onMessageWaitingIndicatorChanged(boolean mwi); + } + + /** + * Interface for call-forwarding indicator listener. + */ + public interface CallForwardingIndicatorListener { + /** + * Callback invoked when the call-forwarding indicator changes on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onCallForwardingIndicatorChanged(boolean cfi); + } + + /** + * Interface for device cell location listener. + */ + public interface CellLocationListener { + /** + * Callback invoked when device cell location changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public void onCellLocationChanged(@NonNull CellLocation location); + } + + /** + * Interface for call state listener. + */ + public interface CallStateListener { + /** + * Callback invoked when device call state changes. + * <p> + * Reports the state of Telephony (mobile) calls on the device for the registered + * subscription. + * <p> + * Note: the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * <p> + * Note: The state returned here may differ from that returned by + * {@link TelephonyManager#getCallState()}. Receivers of this callback should be aware that + * calling {@link TelephonyManager#getCallState()} from within this callback may return a + * different state than the callback reports. + * + * @param state call state + * @param phoneNumber call phone number. If application does not have + * {@link android.Manifest.permission#READ_CALL_LOG} permission or + * carrier + * privileges (see {@link TelephonyManager#hasCarrierPrivileges}), an + * empty string will be + * passed as an argument. + */ + @RequiresPermission(android.Manifest.permission.READ_CALL_LOG) + public void onCallStateChanged(@Annotation.CallState int state, + @Nullable String phoneNumber); + } + + /** + * Interface for data connection state listener. + */ + public interface DataConnectionStateListener { + /** + * Callback invoked when connection state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current state of data connection. + * @param networkType is the current network type of data connection. + * @see TelephonyManager#DATA_DISCONNECTED + * @see TelephonyManager#DATA_CONNECTING + * @see TelephonyManager#DATA_CONNECTED + * @see TelephonyManager#DATA_SUSPENDED + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataConnectionStateChanged(@TelephonyManager.DataState int state, + @Annotation.NetworkType int networkType); + } + + /** + * Interface for data activity state listener. + */ + public interface DataActivityListener { + /** + * Callback invoked when data activity state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @see TelephonyManager#DATA_ACTIVITY_NONE + * @see TelephonyManager#DATA_ACTIVITY_IN + * @see TelephonyManager#DATA_ACTIVITY_OUT + * @see TelephonyManager#DATA_ACTIVITY_INOUT + * @see TelephonyManager#DATA_ACTIVITY_DORMANT + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataActivity(@Annotation.DataActivityType int direction); + } + + /** + * Interface for network signal strengths listener. + */ + public interface SignalStrengthsListener { + /** + * Callback invoked when network signal strengths changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); + } + + /** + * Interface for network signal strengths callback which always reported from modem. + */ + public interface AlwaysReportedSignalStrengthListener { + /** + * Callback always invoked from modem when network signal strengths changes on the + * registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) + public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength); + } + + /** + * Interface for cell info listener. + */ + public interface CellInfoListener { + /** + * Callback invoked when a observed cell info has changed or new cells have been added + * or removed on the registered subscription. + * Note, the registration subscription ID s from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param cellInfo is the list of currently visible cells. + */ + @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) + public void onCellInfoChanged(@NonNull List<CellInfo> cellInfo); + } + + /** + * Interface for precise device call state listener. + * + * @hide + */ + @SystemApi + public interface PreciseCallStateListener { + /** + * Callback invoked when precise device call state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param callState {@link PreciseCallState} + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPreciseCallStateChanged(@NonNull PreciseCallState callState); + } + + /** + * Interface for call disconnect cause listener. + */ + public interface CallDisconnectCauseListener { + /** + * Callback invoked when call disconnect cause changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param disconnectCause {@link DisconnectCause}. + * @param preciseDisconnectCause {@link PreciseDisconnectCause}. + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onCallDisconnectCauseChanged(@Annotation.DisconnectCauses int disconnectCause, + @Annotation.PreciseDisconnectCauses int preciseDisconnectCause); + } + + /** + * Interface for IMS call disconnect cause listener. + */ + public interface ImsCallDisconnectCauseListener { + /** + * Callback invoked when IMS call disconnect cause changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param imsReasonInfo {@link ImsReasonInfo} contains details on why IMS call failed. + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onImsCallDisconnectCauseChanged(@NonNull ImsReasonInfo imsReasonInfo); + } + + /** + * Interface for precise data connection state listener. + */ + public interface PreciseDataConnectionStateListener { + /** + * Callback providing update about the default/internet data connection on the registered + * subscription. + * <p> + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * <p>Requires permission {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE} + * or the calling app has carrier privileges + * (see {@link TelephonyManager#hasCarrierPrivileges}). + * + * @param dataConnectionState {@link PreciseDataConnectionState} + */ + @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPreciseDataConnectionStateChanged( + @NonNull PreciseDataConnectionState dataConnectionState); + } + + /** + * Interface for Single Radio Voice Call Continuity listener. + * + * @hide + */ + @SystemApi + public interface SrvccStateListener { + /** + * Callback invoked when there has been a change in the Single Radio Voice Call Continuity + * (SRVCC) state for the currently active call on the registered subscription. + * <p> + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onSrvccStateChanged(@Annotation.SrvccState int srvccState); + } + + /** + * Interface for SIM voice activation state listener. + * + * @hide + */ + @SystemApi + public interface VoiceActivationStateListener { + /** + * Callback invoked when the SIM voice activation state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM voice activation state + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onVoiceActivationStateChanged(@Annotation.SimActivationState int state); + + } + + /** + * Interface for SIM data activation state listener. + */ + public interface DataActivationStateListener { + /** + * Callback invoked when the SIM data activation state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state is the current SIM data activation state + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onDataActivationStateChanged(@Annotation.SimActivationState int state); + } + + /** + * Interface for user mobile data state listener. + */ + public interface UserMobileDataStateListener { + /** + * Callback invoked when the user mobile data state has changed on the registered + * subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param enabled indicates whether the current user mobile data state is enabled or + * disabled. + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onUserMobileDataStateChanged(boolean enabled); + } + + /** + * Interface for display info listener. + */ + public interface DisplayInfoListener { + /** + * Callback invoked when the display info has changed on the registered subscription. + * <p> The {@link TelephonyDisplayInfo} contains status information shown to the user + * based on carrier policy. + * + * @param telephonyDisplayInfo The display information. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo); + } + + /** + * Interface for the current emergency number list listener. + */ + public interface EmergencyNumberListListener { + /** + * Callback invoked when the current emergency number list has changed on the registered + * subscription. + * <p> + * Note, the registered subscription is associated with {@link TelephonyManager} object + * on which + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)} + * was called. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * given subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param emergencyNumberList Map associating all active subscriptions on the device with + * the list of emergency numbers originating from that + * subscription. + * If there are no active subscriptions, the map will contain a + * single entry with + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} as + * the key and a list of emergency numbers as the value. If no + * emergency number information is available, the value will be + * empty. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onEmergencyNumberListChanged( + @NonNull Map<Integer, List<EmergencyNumber>> emergencyNumberList); + } + + /** + * Interface for outgoing emergency call listener. + * + * @hide + */ + @SystemApi + public interface OutgoingEmergencyCallListener { + /** + * Callback invoked when an outgoing call is placed to an emergency number. + * <p> + * This method will be called when an emergency call is placed on any subscription + * (including the no-SIM case), regardless of which subscription this callback was + * registered on. + * <p> + * + * @param placedEmergencyNumber The {@link EmergencyNumber} the emergency call was + * placed to. + * @param subscriptionId The subscription ID used to place the emergency call. If the + * emergency call was placed without a valid subscription + * (e.g. when there are no SIM cards in the device), this + * will be + * equal to + * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + */ + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, + int subscriptionId); + } + + /** + * Interface for outgoing emergency sms listener. + * + * @hide + */ + @SystemApi + public interface OutgoingEmergencySmsListener { + /** + * Smsback invoked when an outgoing sms is sent to an emergency number. + * <p> + * This method will be called when an emergency sms is sent on any subscription, + * regardless of which subscription this callback was registered on. + * + * @param sentEmergencyNumber The {@link EmergencyNumber} the emergency sms was sent to. + * @param subscriptionId The subscription ID used to send the emergency sms. + */ + @RequiresPermission(Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) + public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber, + int subscriptionId); + } + + /** + * Interface for phone capability listener. + * + * @hide + */ + @SystemApi + public interface PhoneCapabilityListener { + /** + * Callback invoked when phone capability changes. + * Note, this callback triggers regardless of registered subscription. + * + * @param capability the new phone capability + */ + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void onPhoneCapabilityChanged(@NonNull PhoneCapability capability); + } + + /** + * Interface for active data subscription ID listener. + */ + public interface ActiveDataSubscriptionIdListener { + /** + * Callback invoked when active data subscription ID changes. + * Note, this callback triggers regardless of registered subscription. + * + * @param subId current subscription used to setup Cellular Internet data. + * For example, it could be the current active opportunistic subscription + * in use, or the subscription user selected as default data subscription in + * DSDS mode. + */ + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public void onActiveDataSubscriptionIdChanged(int subId); + } + + /** + * Interface for modem radio power state listener. + * + * @hide + */ + @SystemApi + public interface RadioPowerStateListener { + /** + * Callback invoked when modem radio power state changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param state the modem radio power state + */ + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public void onRadioPowerStateChanged(@Annotation.RadioPowerState int state); + } + + /** + * Interface for carrier network listener. + */ + public interface CarrierNetworkListener { + /** + * Callback invoked when telephony has received notice from a carrier + * app that a network action that could result in connectivity loss + * has been requested by an app using + * {@link android.service.carrier.CarrierService#notifyCarrierNetworkChange(boolean)} + * <p> + * This is optional and is only used to allow the system to provide alternative UI while + * telephony is performing an action that may result in intentional, temporary network + * lack of connectivity. + * <p> + * Note, this callback is pinned to the registered subscription and will be invoked when + * the notifying carrier app has carrier privilege rule on the registered + * subscription. {@link android.telephony.TelephonyManager#hasCarrierPrivileges} + * + * @param active If the carrier network change is or shortly will be active, + * {@code true} indicate that showing alternative UI, {@code false} otherwise. + */ + public void onCarrierNetworkChange(boolean active); + } + + /** + * Interface for registration failures listener. + */ + public interface RegistrationFailedListener { + /** + * Report that Registration or a Location/Routing/Tracking Area update has failed. + * + * <p>Indicate whenever a registration procedure, including a location, routing, or tracking + * area update fails. This includes procedures that do not necessarily result in a change of + * the modem's registration status. If the modem's registration status changes, that is + * reflected in the onNetworkStateChanged() and subsequent + * get{Voice/Data}RegistrationState(). + * + * <p>Because registration failures are ephemeral, this callback is not sticky. + * Registrants will not receive the most recent past value when registering. + * + * @param cellIdentity the CellIdentity, which must include the globally unique + * identifier + * for the cell (for example, all components of the CGI or ECGI). + * @param chosenPlmn a 5 or 6 digit alphanumeric PLMN (MCC|MNC) among those + * broadcast by the + * cell that was chosen for the failed registration attempt. + * @param domain DOMAIN_CS, DOMAIN_PS or both in case of a combined procedure. + * @param causeCode the primary failure cause code of the procedure. + * For GSM/UMTS (MM), values are in TS 24.008 Sec 10.5.95 + * For GSM/UMTS (GMM), values are in TS 24.008 Sec 10.5.147 + * For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9 + * For NR (5GMM), cause codes are TS 24.501 Sec 9.11.3.2 + * Integer.MAX_VALUE if this value is unused. + * @param additionalCauseCode the cause code of any secondary/combined procedure + * if appropriate. For UMTS, if a combined attach succeeds for + * PS only, then the GMM cause code shall be included as an + * additionalCauseCode. For LTE (ESM), cause codes are in + * TS 24.301 9.9.4.4. Integer.MAX_VALUE if this value is unused. + */ + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, + @NonNull String chosenPlmn, @NetworkRegistrationInfo.Domain int domain, int causeCode, + int additionalCauseCode); + } + + /** + * Interface for the current allowed network type list listener. This list involves values of + * allowed network type for each of reasons. + * + * @hide + */ + @SystemApi + public interface AllowedNetworkTypesListener { + /** + * Callback invoked when the current allowed network type list has changed on the + * registered subscription. + * Note, the registered subscription is associated with {@link TelephonyManager} object + * on which + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)} + * was called. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * given subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param allowedNetworkTypesList Map associating all allowed network type reasons + * ({@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER}, + * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER}, + * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER}, and + * {@link TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G}) with reason's allowed + * network type values. + * For example: + * map{{TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_USER, long type value}, + * {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_POWER, long type value}, + * {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_CARRIER, long type value}, + * {TelephonyManager#ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G, long type value}} + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + void onAllowedNetworkTypesChanged(@NonNull Map<Integer, Long> allowedNetworkTypesList); + } + + /** + * Interface for call attributes listener. + * + * @hide + */ + @SystemApi + public interface CallAttributesListener { + /** + * Callback invoked when the call attributes changes on the registered subscription. + * Note, the registration subscription ID comes from {@link TelephonyManager} object + * which registers TelephonyCallback by + * {@link TelephonyManager#registerTelephonyCallback(Executor, TelephonyCallback)}. + * If this TelephonyManager object was created with + * {@link TelephonyManager#createForSubscriptionId(int)}, then the callback applies to the + * subscription ID. Otherwise, this callback applies to + * {@link SubscriptionManager#getDefaultSubscriptionId()}. + * + * @param callAttributes the call attributes + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + void onCallAttributesChanged(@NonNull CallAttributes callAttributes); + } + + /** + * Interface for barring information listener. + */ + public interface BarringInfoListener { + /** + * Report updated barring information for the current camped/registered cell. + * + * <p>Barring info is provided for all services applicable to the current camped/registered + * cell, for the registered PLMN and current access class/access category. + * + * @param barringInfo for all services on the current cell. + * @see android.telephony.BarringInfo + */ + @RequiresPermission(allOf = { + Manifest.permission.READ_PRECISE_PHONE_STATE, + Manifest.permission.ACCESS_FINE_LOCATION + }) + public void onBarringInfoChanged(@NonNull BarringInfo barringInfo); + } + + /** + * Interface for current physical channel configuration listener. + * + * @hide + */ + @SystemApi + public interface PhysicalChannelConfigListener { + /** + * Callback invoked when the current physical channel configuration has changed + * + * @param configs List of the current {@link PhysicalChannelConfig}s + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onPhysicalChannelConfigChanged(@NonNull List<PhysicalChannelConfig> configs); + } + + /** + * Interface for data enabled listener. + * + * @hide + */ + @SystemApi + public interface DataEnabledListener { + /** + * Callback invoked when the data enabled changes. + * + * @param enabled {@code true} if data is enabled, otherwise disabled. + * @param reason Reason for data enabled/disabled. + * See {@link TelephonyManager.DataEnabledReason}. + */ + @RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE) + public void onDataEnabledChanged(boolean enabled, + @TelephonyManager.DataEnabledReason int reason); + } + + + /** + * The callback methods need to be called on the handler thread where + * this object was created. If the binder did that for us it'd be nice. + * <p> + * Using a static class and weak reference here to avoid memory leak caused by the + * IPhoneState.Stub callback retaining references to the outside TelephonyCallback: + * even caller has been destroyed and "un-registered" the TelephonyCallback, it is still not + * eligible for GC given the references coming from: + * Native Stack --> TelephonyCallback --> Context (Activity). + * memory of caller's context will be collected after GC from service side get triggered + */ + private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub { + private WeakReference<TelephonyCallback> mTelephonyCallbackWeakRef; + private Executor mExecutor; + + IPhoneStateListenerStub(TelephonyCallback telephonyCallback, Executor executor) { + mTelephonyCallbackWeakRef = new WeakReference<TelephonyCallback>(telephonyCallback); + mExecutor = executor; + } + + public void onServiceStateChanged(ServiceState serviceState) { + ServiceStateListener listener = (ServiceStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onServiceStateChanged(serviceState))); + } + + public void onSignalStrengthChanged(int asu) { + // default implementation empty + } + + public void onMessageWaitingIndicatorChanged(boolean mwi) { + MessageWaitingIndicatorListener listener = + (MessageWaitingIndicatorListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onMessageWaitingIndicatorChanged(mwi))); + } + + public void onCallForwardingIndicatorChanged(boolean cfi) { + CallForwardingIndicatorListener listener = + (CallForwardingIndicatorListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCallForwardingIndicatorChanged(cfi))); + } + + public void onCellLocationChanged(CellIdentity cellIdentity) { + // There is no system/public API to create an CellIdentity in system server, + // so the server pass a null to indicate an empty initial location. + CellLocation location = + cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation(); + CellLocationListener listener = (CellLocationListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCellLocationChanged(location))); + } + + public void onCallStateChanged(int state, String incomingNumber) { + CallStateListener listener = (CallStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCallStateChanged(state, + incomingNumber))); + } + + public void onDataConnectionStateChanged(int state, int networkType) { + DataConnectionStateListener listener = + (DataConnectionStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + if (state == TelephonyManager.DATA_DISCONNECTING + && VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) { + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> + listener.onDataConnectionStateChanged( + TelephonyManager.DATA_CONNECTED, networkType))); + } else { + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> + listener.onDataConnectionStateChanged(state, networkType))); + } + } + + public void onDataActivity(int direction) { + DataActivityListener listener = (DataActivityListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onDataActivity(direction))); + } + + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + SignalStrengthsListener listener = + (SignalStrengthsListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onSignalStrengthsChanged( + signalStrength))); + } + + public void onCellInfoChanged(List<CellInfo> cellInfo) { + CellInfoListener listener = (CellInfoListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCellInfoChanged(cellInfo))); + } + + public void onPreciseCallStateChanged(PreciseCallState callState) { + PreciseCallStateListener listener = + (PreciseCallStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onPreciseCallStateChanged(callState))); + } + + public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { + CallDisconnectCauseListener listener = + (CallDisconnectCauseListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCallDisconnectCauseChanged( + disconnectCause, preciseDisconnectCause))); + } + + public void onPreciseDataConnectionStateChanged( + PreciseDataConnectionState dataConnectionState) { + PreciseDataConnectionStateListener listener = + (PreciseDataConnectionStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onPreciseDataConnectionStateChanged( + dataConnectionState))); + } + + public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { + // default implementation empty + } + + public void onSrvccStateChanged(int state) { + SrvccStateListener listener = (SrvccStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onSrvccStateChanged(state))); + } + + public void onVoiceActivationStateChanged(int activationState) { + VoiceActivationStateListener listener = + (VoiceActivationStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onVoiceActivationStateChanged(activationState))); + } + + public void onDataActivationStateChanged(int activationState) { + DataActivationStateListener listener = + (DataActivationStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onDataActivationStateChanged(activationState))); + } + + public void onUserMobileDataStateChanged(boolean enabled) { + UserMobileDataStateListener listener = + (UserMobileDataStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onUserMobileDataStateChanged(enabled))); + } + + public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) { + DisplayInfoListener listener = (DisplayInfoListener)mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onDisplayInfoChanged(telephonyDisplayInfo))); + } + + public void onOemHookRawEvent(byte[] rawData) { + // default implementation empty + } + + public void onCarrierNetworkChange(boolean active) { + CarrierNetworkListener listener = + (CarrierNetworkListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCarrierNetworkChange(active))); + } + + public void onEmergencyNumberListChanged(Map emergencyNumberList) { + EmergencyNumberListListener listener = + (EmergencyNumberListListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onEmergencyNumberListChanged(emergencyNumberList))); + } + + public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber, + int subscriptionId) { + OutgoingEmergencyCallListener listener = + (OutgoingEmergencyCallListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onOutgoingEmergencyCall(placedEmergencyNumber, + subscriptionId))); + } + + public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber, + int subscriptionId) { + OutgoingEmergencySmsListener listener = + (OutgoingEmergencySmsListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onOutgoingEmergencySms(sentEmergencyNumber, + subscriptionId))); + } + + public void onPhoneCapabilityChanged(PhoneCapability capability) { + PhoneCapabilityListener listener = + (PhoneCapabilityListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onPhoneCapabilityChanged(capability))); + } + + public void onRadioPowerStateChanged(@Annotation.RadioPowerState int state) { + RadioPowerStateListener listener = + (RadioPowerStateListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onRadioPowerStateChanged(state))); + } + + public void onCallAttributesChanged(CallAttributes callAttributes) { + CallAttributesListener listener = + (CallAttributesListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onCallAttributesChanged( + callAttributes))); + } + + public void onActiveDataSubIdChanged(int subId) { + ActiveDataSubscriptionIdListener listener = + (ActiveDataSubscriptionIdListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onActiveDataSubscriptionIdChanged( + subId))); + } + + public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) { + ImsCallDisconnectCauseListener listener = + (ImsCallDisconnectCauseListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onImsCallDisconnectCauseChanged(disconnectCause))); + } + + public void onRegistrationFailed(@NonNull CellIdentity cellIdentity, + @NonNull String chosenPlmn, int domain, int causeCode, int additionalCauseCode) { + RegistrationFailedListener listener = + (RegistrationFailedListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onRegistrationFailed( + cellIdentity, chosenPlmn, domain, causeCode, additionalCauseCode))); + // default implementation empty + } + + public void onBarringInfoChanged(BarringInfo barringInfo) { + BarringInfoListener listener = (BarringInfoListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onBarringInfoChanged(barringInfo))); + } + + public void onPhysicalChannelConfigChanged(List<PhysicalChannelConfig> configs) { + PhysicalChannelConfigListener listener = + (PhysicalChannelConfigListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onPhysicalChannelConfigChanged( + configs))); + } + + public void onDataEnabledChanged(boolean enabled, + @TelephonyManager.DataEnabledReason int reason) { + DataEnabledListener listener = + (DataEnabledListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> listener.onDataEnabledChanged( + enabled, reason))); + } + + public void onAllowedNetworkTypesChanged(Map allowedNetworkTypesList) { + AllowedNetworkTypesListener listener = + (AllowedNetworkTypesListener) mTelephonyCallbackWeakRef.get(); + if (listener == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> listener.onAllowedNetworkTypesChanged(allowedNetworkTypesList))); + } + } +} diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 8c516516a9de..15d1a595ff0e 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -209,7 +209,7 @@ public class TelephonyRegistryManager { } /** - * To check the SDK version for {@link #listenWithEventList}. + * To check the SDK version for {@link #listenFromListener}. */ @ChangeId @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.P) @@ -221,24 +221,49 @@ public class TelephonyRegistryManager { * @param pkg Package name * @param featureId Feature ID * @param listener Listener providing callback - * @param events List events + * @param events Events * @param notifyNow Whether to notify instantly */ - public void listenWithEventList(int subId, @NonNull String pkg, @NonNull String featureId, - @NonNull PhoneStateListener listener, @NonNull int[] events, boolean notifyNow) { + public void listenFromListener(int subId, @NonNull String pkg, @NonNull String featureId, + @NonNull PhoneStateListener listener, @NonNull int events, boolean notifyNow) { + if (listener == null) { + throw new IllegalStateException("telephony service is null."); + } + try { + int[] eventsList = getEventsFromBitmask(events).stream().mapToInt(i -> i).toArray(); // subId from PhoneStateListener is deprecated Q on forward, use the subId from // TelephonyManager instance. Keep using subId from PhoneStateListener for pre-Q. if (Compatibility.isChangeEnabled(LISTEN_CODE_CHANGE)) { // Since mSubId in PhoneStateListener is deprecated from Q on forward, this is // the only place to set mSubId and its for "informational" only. - listener.mSubId = (events.length == 0) + listener.mSubId = (eventsList.length == 0) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : subId; } else if (listener.mSubId != null) { subId = listener.mSubId; } sRegistry.listenWithEventList( - subId, pkg, featureId, listener.callback, events, notifyNow); + subId, pkg, featureId, listener.callback, eventsList, notifyNow); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Listen for incoming subscriptions + * @param subId Subscription ID + * @param pkg Package name + * @param featureId Feature ID + * @param telephonyCallback Listener providing callback + * @param events List events + * @param notifyNow Whether to notify instantly + */ + private void listenFromCallback(int subId, @NonNull String pkg, @NonNull String featureId, + @NonNull TelephonyCallback telephonyCallback, @NonNull int[] events, + boolean notifyNow) { + try { + sRegistry.listenWithEventList( + subId, pkg, featureId, telephonyCallback.callback, events, notifyNow); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -802,11 +827,11 @@ public class TelephonyRegistryManager { /** * Notify emergency number list changed on certain subscription. * - * @param subId for which emergency number list changed. * @param slotIndex for which emergency number list changed. Can be derived from subId except * when subId is invalid. + * @param subId for which emergency number list changed. */ - public void notifyAllowedNetworkTypesChanged(int subId, int slotIndex, + public void notifyAllowedNetworkTypesChanged(int slotIndex, int subId, Map<Integer, Long> allowedNetworkTypeList) { try { sRegistry.notifyAllowedNetworkTypesChanged(slotIndex, subId, allowedNetworkTypeList); @@ -815,136 +840,137 @@ public class TelephonyRegistryManager { } } - public @NonNull Set<Integer> getEventsFromListener(@NonNull PhoneStateListener listener) { + public @NonNull Set<Integer> getEventsFromCallback( + @NonNull TelephonyCallback telephonyCallback) { Set<Integer> eventList = new ArraySet<>(); - if (listener instanceof PhoneStateListener.ServiceStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.ServiceStateListener) { + eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.MessageWaitingIndicatorChangedListener) { - eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.MessageWaitingIndicatorListener) { + eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); } - if (listener instanceof PhoneStateListener.CallForwardingIndicatorChangedListener) { - eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CallForwardingIndicatorListener) { + eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); } - if (listener instanceof PhoneStateListener.CellLocationChangedListener) { - eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CellLocationListener) { + eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED); } - if (listener instanceof PhoneStateListener.CallStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CallStateListener) { + eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.DataConnectionStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.DataConnectionStateListener) { + eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.DataActivityListener) { - eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.DataActivityListener) { + eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED); } - if (listener instanceof PhoneStateListener.SignalStrengthsChangedListener) { - eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.SignalStrengthsListener) { + eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED); } - if (listener instanceof PhoneStateListener.AlwaysReportedSignalStrengthChangedListener) { - eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.AlwaysReportedSignalStrengthListener) { + eventList.add(TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); } - if (listener instanceof PhoneStateListener.CellInfoChangedListener) { - eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CellInfoListener) { + eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED); } - if (listener instanceof PhoneStateListener.PreciseCallStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.PreciseCallStateListener) { + eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.CallDisconnectCauseChangedListener) { - eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CallDisconnectCauseListener) { + eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); } - if (listener instanceof PhoneStateListener.ImsCallDisconnectCauseChangedListener) { - eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.ImsCallDisconnectCauseListener) { + eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); } - if (listener instanceof PhoneStateListener.PreciseDataConnectionStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.PreciseDataConnectionStateListener) { + eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.SrvccStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.SrvccStateListener) { + eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.VoiceActivationStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.VoiceActivationStateListener) { + eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.DataActivationStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.DataActivationStateListener) { + eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.UserMobileDataStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.UserMobileDataStateListener) { + eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.DisplayInfoChangedListener) { - eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.DisplayInfoListener) { + eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED); } - if (listener instanceof PhoneStateListener.EmergencyNumberListChangedListener) { - eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.EmergencyNumberListListener) { + eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); } - if (listener instanceof PhoneStateListener.OutgoingEmergencyCallListener) { - eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL); + if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencyCallListener) { + eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL); } - if (listener instanceof PhoneStateListener.OutgoingEmergencySmsListener) { - eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS); + if (telephonyCallback instanceof TelephonyCallback.OutgoingEmergencySmsListener) { + eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS); } - if (listener instanceof PhoneStateListener.PhoneCapabilityChangedListener) { - eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.PhoneCapabilityListener) { + eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED); } - if (listener instanceof PhoneStateListener.ActiveDataSubscriptionIdChangedListener) { - eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.ActiveDataSubscriptionIdListener) { + eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); } - if (listener instanceof PhoneStateListener.RadioPowerStateChangedListener) { - eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.RadioPowerStateListener) { + eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED); } - if (listener instanceof PhoneStateListener.CarrierNetworkChangeListener) { - eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CarrierNetworkListener) { + eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED); } - if (listener instanceof PhoneStateListener.RegistrationFailedListener) { - eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE); + if (telephonyCallback instanceof TelephonyCallback.RegistrationFailedListener) { + eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE); } - if (listener instanceof PhoneStateListener.CallAttributesChangedListener) { - eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.CallAttributesListener) { + eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED); } - if (listener instanceof PhoneStateListener.BarringInfoChangedListener) { - eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.BarringInfoListener) { + eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED); } - if (listener instanceof PhoneStateListener.PhysicalChannelConfigChangedListener) { - eventList.add(PhoneStateListener.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.PhysicalChannelConfigListener) { + eventList.add(TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED); } - if (listener instanceof PhoneStateListener.DataEnabledChangedListener) { - eventList.add(PhoneStateListener.EVENT_DATA_ENABLED_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.DataEnabledListener) { + eventList.add(TelephonyCallback.EVENT_DATA_ENABLED_CHANGED); } - if (listener instanceof PhoneStateListener.AllowedNetworkTypesChangedListener) { - eventList.add(PhoneStateListener.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED); + if (telephonyCallback instanceof TelephonyCallback.AllowedNetworkTypesListener) { + eventList.add(TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED); } return eventList; @@ -955,200 +981,183 @@ public class TelephonyRegistryManager { Set<Integer> eventList = new ArraySet<>(); if ((eventMask & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_SERVICE_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTH) != 0) { - eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTH_CHANGED); + eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR) != 0) { - eventList.add(PhoneStateListener.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); + eventList.add(TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR) != 0) { - eventList.add(PhoneStateListener.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); + eventList.add(TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CELL_LOCATION) != 0) { - eventList.add(PhoneStateListener.EVENT_CELL_LOCATION_CHANGED); + eventList.add(TelephonyCallback.EVENT_CELL_LOCATION_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CALL_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_CALL_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_CALL_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVITY) != 0) { - eventList.add(PhoneStateListener.EVENT_DATA_ACTIVITY_CHANGED); + eventList.add(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) { - eventList.add(PhoneStateListener.EVENT_SIGNAL_STRENGTHS_CHANGED); + eventList.add(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) { - eventList.add(PhoneStateListener.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); + eventList.add(TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CELL_INFO) != 0) { - eventList.add(PhoneStateListener.EVENT_CELL_INFO_CHANGED); + eventList.add(TelephonyCallback.EVENT_CELL_INFO_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_PRECISE_CALL_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_PRECISE_CALL_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_DATA_CONNECTION_REAL_TIME_INFO) != 0) { - eventList.add(PhoneStateListener.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); + eventList.add(TelephonyCallback.EVENT_DATA_CONNECTION_REAL_TIME_INFO_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) { - eventList.add(PhoneStateListener.EVENT_OEM_HOOK_RAW); + eventList.add(TelephonyCallback.EVENT_OEM_HOOK_RAW); } if ((eventMask & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { - eventList.add(PhoneStateListener.EVENT_SRVCC_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) != 0) { - eventList.add(PhoneStateListener.EVENT_CARRIER_NETWORK_CHANGED); + eventList.add(TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_VOICE_ACTIVATION_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_DATA_ACTIVATION_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_DATA_ACTIVATION_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_USER_MOBILE_DATA_STATE) != 0) { - eventList.add(PhoneStateListener.EVENT_USER_MOBILE_DATA_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED) != 0) { - eventList.add(PhoneStateListener.EVENT_DISPLAY_INFO_CHANGED); + eventList.add(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_PHONE_CAPABILITY_CHANGE) != 0) { - eventList.add(PhoneStateListener.EVENT_PHONE_CAPABILITY_CHANGED); + eventList.add(TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) { - eventList.add(PhoneStateListener.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); + eventList.add(TelephonyCallback.EVENT_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) { - eventList.add(PhoneStateListener.EVENT_RADIO_POWER_STATE_CHANGED); + eventList.add(TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST) != 0) { - eventList.add(PhoneStateListener.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); + eventList.add(TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) { - eventList.add(PhoneStateListener.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); + eventList.add(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_CALL_ATTRIBUTES_CHANGED) != 0) { - eventList.add(PhoneStateListener.EVENT_CALL_ATTRIBUTES_CHANGED); + eventList.add(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_IMS_CALL_DISCONNECT_CAUSES) != 0) { - eventList.add(PhoneStateListener.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); + eventList.add(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED); } if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL) != 0) { - eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_CALL); + eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_CALL); } if ((eventMask & PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS) != 0) { - eventList.add(PhoneStateListener.EVENT_OUTGOING_EMERGENCY_SMS); + eventList.add(TelephonyCallback.EVENT_OUTGOING_EMERGENCY_SMS); } if ((eventMask & PhoneStateListener.LISTEN_REGISTRATION_FAILURE) != 0) { - eventList.add(PhoneStateListener.EVENT_REGISTRATION_FAILURE); + eventList.add(TelephonyCallback.EVENT_REGISTRATION_FAILURE); } if ((eventMask & PhoneStateListener.LISTEN_BARRING_INFO) != 0) { - eventList.add(PhoneStateListener.EVENT_BARRING_INFO_CHANGED); + eventList.add(TelephonyCallback.EVENT_BARRING_INFO_CHANGED); } return eventList; } /** - * Registers a listener object to receive notification of changes - * in specified telephony states. + * Registers a callback object to receive notification of changes in specified telephony states. * <p> - * To register a listener, pass a {@link PhoneStateListener} which implements + * To register a callback, pass a {@link TelephonyCallback} which implements * interfaces of events. For example, - * FakeServiceStateChangedListener extends {@link PhoneStateListener} implements - * {@link PhoneStateListener.ServiceStateChangedListener}. + * FakeServiceStateCallback extends {@link TelephonyCallback} implements + * {@link TelephonyCallback.ServiceStateListener}. * * At registration, and when a specified telephony state changes, the telephony manager invokes - * the appropriate callback method on the listener object and passes the current (updated) + * the appropriate callback method on the callback object and passes the current (updated) * values. * <p> * * If this TelephonyManager object has been created with * {@link TelephonyManager#createForSubscriptionId}, applies to the given subId. * Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}. - * To listen events for multiple subIds, pass a separate listener object to + * To register events for multiple subIds, pass a separate callback object to * each TelephonyManager object created with {@link TelephonyManager#createForSubscriptionId}. * * Note: if you call this method while in the middle of a binder transaction, you <b>must</b> * call {@link android.os.Binder#clearCallingIdentity()} before calling this method. A * {@link SecurityException} will be thrown otherwise. * - * This API should be used sparingly -- large numbers of listeners will cause system - * instability. If a process has registered too many listeners without unregistering them, it - * may encounter an {@link IllegalStateException} when trying to register more listeners. + * This API should be used sparingly -- large numbers of callbacks will cause system + * instability. If a process has registered too many callbacks without unregistering them, it + * may encounter an {@link IllegalStateException} when trying to register more callbacks. * - * @param listener The {@link PhoneStateListener} object to register. + * @param callback The {@link TelephonyCallback} object to register. */ - public void registerPhoneStateListener(@NonNull @CallbackExecutor Executor executor, int subId, - String pkgName, String attributionTag, @NonNull PhoneStateListener listener, + public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor, + int subId, String pkgName, String attributionTag, @NonNull TelephonyCallback callback, boolean notifyNow) { - listener.setExecutor(executor); - registerPhoneStateListener(subId, pkgName, attributionTag, listener, - getEventsFromListener(listener), notifyNow); - } - - public void registerPhoneStateListenerWithEvents(int subId, String pkgName, - String attributionTag, @NonNull PhoneStateListener listener, int events, - boolean notifyNow) { - registerPhoneStateListener( - subId, pkgName, attributionTag, listener, getEventsFromBitmask(events), notifyNow); - } - - private void registerPhoneStateListener(int subId, - String pkgName, String attributionTag, @NonNull PhoneStateListener listener, - @NonNull Set<Integer> events, boolean notifyNow) { - if (listener == null) { + if (callback == null) { throw new IllegalStateException("telephony service is null."); } - - listenWithEventList(subId, pkgName, attributionTag, listener, - events.stream().mapToInt(i -> i).toArray(), notifyNow); + callback.init(executor); + listenFromCallback(subId, pkgName, attributionTag, callback, + getEventsFromCallback(callback).stream().mapToInt(i -> i).toArray(), notifyNow); } /** - * Unregister an existing {@link PhoneStateListener}. + * Unregister an existing {@link TelephonyCallback}. * - * @param listener The {@link PhoneStateListener} object to unregister. + * @param callback The {@link TelephonyCallback} object to unregister. */ - public void unregisterPhoneStateListener(int subId, String pkgName, String attributionTag, - @NonNull PhoneStateListener listener, - boolean notifyNow) { - listenWithEventList(subId, pkgName, attributionTag, listener, new int[0], notifyNow); + public void unregisterTelephonyCallback(int subId, String pkgName, String attributionTag, + @NonNull TelephonyCallback callback, boolean notifyNow) { + listenFromCallback(subId, pkgName, attributionTag, callback, new int[0], notifyNow); } } diff --git a/core/java/android/uwb/AngleMeasurement.java b/core/java/android/uwb/AngleMeasurement.java index 9df213b2092f..8c771baaea37 100644 --- a/core/java/android/uwb/AngleMeasurement.java +++ b/core/java/android/uwb/AngleMeasurement.java @@ -38,9 +38,30 @@ public final class AngleMeasurement implements Parcelable { private final double mErrorRadians; private final double mConfidenceLevel; - private AngleMeasurement(double radians, double errorRadians, double confidenceLevel) { + /** + * Constructs a new {@link AngleMeasurement} object + * + * @param radians the angle in radians + * @param errorRadians the error of the angle measurement in radians + * @param confidenceLevel confidence level of the angle measurement + * + * @throws IllegalArgumentException if the radians, errorRadians, or confidenceLevel is out of + * allowed range + */ + public AngleMeasurement(double radians, double errorRadians, double confidenceLevel) { + if (radians < -Math.PI || radians > Math.PI) { + throw new IllegalArgumentException("Invalid radians: " + radians); + } mRadians = radians; + + if (errorRadians < 0.0 || errorRadians > Math.PI) { + throw new IllegalArgumentException("Invalid error radians: " + errorRadians); + } mErrorRadians = errorRadians; + + if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { + throw new IllegalArgumentException("Invalid confidence level: " + confidenceLevel); + } mConfidenceLevel = confidenceLevel; } @@ -122,11 +143,7 @@ public final class AngleMeasurement implements Parcelable { new Creator<AngleMeasurement>() { @Override public AngleMeasurement createFromParcel(Parcel in) { - Builder builder = new Builder(); - builder.setRadians(in.readDouble()); - builder.setErrorRadians(in.readDouble()); - builder.setConfidenceLevel(in.readDouble()); - return builder.build(); + return new AngleMeasurement(in.readDouble(), in.readDouble(), in.readDouble()); } @Override @@ -134,82 +151,4 @@ public final class AngleMeasurement implements Parcelable { return new AngleMeasurement[size]; } }; - - /** - * Builder class for {@link AngleMeasurement}. - */ - public static final class Builder { - private double mRadians = Double.NaN; - private double mErrorRadians = Double.NaN; - private double mConfidenceLevel = Double.NaN; - - /** - * Set the angle in radians - * - * @param radians angle in radians - * @throws IllegalArgumentException if angle exceeds allowed limits of [-Math.PI, +Math.PI] - */ - @NonNull - public Builder setRadians(double radians) { - if (radians < -Math.PI || radians > Math.PI) { - throw new IllegalArgumentException("Invalid radians: " + radians); - } - mRadians = radians; - return this; - } - - /** - * Set the angle error in radians - * - * @param errorRadians error of the angle in radians - * @throws IllegalArgumentException if the error exceeds the allowed limits of [0, +Math.PI] - */ - @NonNull - public Builder setErrorRadians(double errorRadians) { - if (errorRadians < 0.0 || errorRadians > Math.PI) { - throw new IllegalArgumentException( - "Invalid error radians: " + errorRadians); - } - mErrorRadians = errorRadians; - return this; - } - - /** - * Set the angle confidence level - * - * @param confidenceLevel level of confidence of the angle measurement - * @throws IllegalArgumentException if the error exceeds the allowed limits of [0.0, 1.0] - */ - @NonNull - public Builder setConfidenceLevel(double confidenceLevel) { - if (confidenceLevel < 0.0 || confidenceLevel > 1.0) { - throw new IllegalArgumentException( - "Invalid confidence level: " + confidenceLevel); - } - mConfidenceLevel = confidenceLevel; - return this; - } - - /** - * Build the {@link AngleMeasurement} object - * - * @throws IllegalStateException if angle, error, or confidence values are missing - */ - @NonNull - public AngleMeasurement build() { - if (Double.isNaN(mRadians)) { - throw new IllegalStateException("Angle is not set"); - } - - if (Double.isNaN(mErrorRadians)) { - throw new IllegalStateException("Angle error is not set"); - } - - if (Double.isNaN(mConfidenceLevel)) { - throw new IllegalStateException("Angle confidence level is not set"); - } - - return new AngleMeasurement(mRadians, mErrorRadians, mConfidenceLevel); - } - } } diff --git a/core/java/android/uwb/AngleOfArrivalMeasurement.java b/core/java/android/uwb/AngleOfArrivalMeasurement.java index 3d8626b98bed..db04ad16c191 100644 --- a/core/java/android/uwb/AngleOfArrivalMeasurement.java +++ b/core/java/android/uwb/AngleOfArrivalMeasurement.java @@ -116,9 +116,8 @@ public final class AngleOfArrivalMeasurement implements Parcelable { new Creator<AngleOfArrivalMeasurement>() { @Override public AngleOfArrivalMeasurement createFromParcel(Parcel in) { - Builder builder = new Builder(); - - builder.setAzimuth(in.readParcelable(AngleMeasurement.class.getClassLoader())); + Builder builder = + new Builder(in.readParcelable(AngleMeasurement.class.getClassLoader())); builder.setAltitude(in.readParcelable(AngleMeasurement.class.getClassLoader())); @@ -135,18 +134,16 @@ public final class AngleOfArrivalMeasurement implements Parcelable { * Builder class for {@link AngleOfArrivalMeasurement}. */ public static final class Builder { - private AngleMeasurement mAzimuthAngleMeasurement = null; + private final AngleMeasurement mAzimuthAngleMeasurement; private AngleMeasurement mAltitudeAngleMeasurement = null; /** - * Set the azimuth angle + * Constructs an {@link AngleOfArrivalMeasurement} object * - * @param azimuthAngle azimuth angle + * @param azimuthAngle the azimuth angle of the measurement */ - @NonNull - public Builder setAzimuth(@NonNull AngleMeasurement azimuthAngle) { + public Builder(@NonNull AngleMeasurement azimuthAngle) { mAzimuthAngleMeasurement = azimuthAngle; - return this; } /** @@ -162,15 +159,9 @@ public final class AngleOfArrivalMeasurement implements Parcelable { /** * Build the {@link AngleOfArrivalMeasurement} object - * - * @throws IllegalStateException if the required azimuth angle is not provided */ @NonNull public AngleOfArrivalMeasurement build() { - if (mAzimuthAngleMeasurement == null) { - throw new IllegalStateException("Azimuth angle measurement is not set"); - } - return new AngleOfArrivalMeasurement(mAzimuthAngleMeasurement, mAltitudeAngleMeasurement); } diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl index 468a69c7bddb..4036892fb9e7 100644 --- a/core/java/android/uwb/IUwbAdapter.aidl +++ b/core/java/android/uwb/IUwbAdapter.aidl @@ -62,9 +62,6 @@ interface IUwbAdapter { /** * Request to open a new ranging session * - * This function must return before calling any functions in - * IUwbAdapterCallbacks. - * * This function does not start the ranging session, but all necessary * components must be initialized and ready to start a new ranging * session prior to calling IUwbAdapterCallback#onRangingOpened. @@ -77,12 +74,16 @@ interface IUwbAdapter { * RANGING_SESSION_OPEN_THRESHOLD_MS milliseconds of #openRanging being called * if the ranging session fails to be opened. * + * If the provided sessionHandle is already open for the calling client, then + * #onRangingOpenFailed must be called and the new session must not be opened. + * + * @param sessionHandle the session handle to open ranging for * @param rangingCallbacks the callbacks used to deliver ranging information * @param parameters the configuration to use for ranging - * @return a SessionHandle used to identify this ranging request */ - SessionHandle openRanging(in IUwbRangingCallbacks rangingCallbacks, - in PersistableBundle parameters); + void openRanging(in SessionHandle sessionHandle, + in IUwbRangingCallbacks rangingCallbacks, + in PersistableBundle parameters); /** * Request to start ranging diff --git a/core/java/android/uwb/RangingManager.java b/core/java/android/uwb/RangingManager.java index c0d818774ba0..85f2c1ccc180 100644 --- a/core/java/android/uwb/RangingManager.java +++ b/core/java/android/uwb/RangingManager.java @@ -17,6 +17,7 @@ package android.uwb; import android.annotation.NonNull; +import android.os.CancellationSignal; import android.os.PersistableBundle; import android.os.RemoteException; import android.util.Log; @@ -32,6 +33,7 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { private final IUwbAdapter mAdapter; private final Hashtable<SessionHandle, RangingSession> mRangingSessionTable = new Hashtable<>(); + private int mNextSessionId = 1; public RangingManager(IUwbAdapter adapter) { mAdapter = adapter; @@ -44,29 +46,26 @@ public class RangingManager extends android.uwb.IUwbRangingCallbacks.Stub { * @param executor {@link Executor} to run callbacks * @param callbacks {@link RangingSession.Callback} to associate with the {@link RangingSession} * that is being opened. - * @return a new {@link RangingSession} + * @return a {@link CancellationSignal} that may be used to cancel the opening of the + * {@link RangingSession}. */ - public RangingSession openSession(@NonNull PersistableBundle params, @NonNull Executor executor, + public CancellationSignal openSession(@NonNull PersistableBundle params, + @NonNull Executor executor, @NonNull RangingSession.Callback callbacks) { - SessionHandle sessionHandle; - try { - sessionHandle = mAdapter.openRanging(this, params); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - synchronized (this) { - if (hasSession(sessionHandle)) { - Log.w(TAG, "Newly created session unexpectedly reuses an active SessionHandle"); - executor.execute(() -> callbacks.onClosed( - RangingSession.Callback.REASON_GENERIC_ERROR, - new PersistableBundle())); - } - + SessionHandle sessionHandle = new SessionHandle(mNextSessionId++); RangingSession session = new RangingSession(executor, callbacks, mAdapter, sessionHandle); mRangingSessionTable.put(sessionHandle, session); - return session; + try { + mAdapter.openRanging(sessionHandle, this, params); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + + CancellationSignal cancellationSignal = new CancellationSignal(); + cancellationSignal.setOnCancelListener(() -> session.close()); + return cancellationSignal; } } diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java index 63a6d058f358..844bbbe7970b 100644 --- a/core/java/android/uwb/UwbManager.java +++ b/core/java/android/uwb/UwbManager.java @@ -25,6 +25,7 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.Context; +import android.os.CancellationSignal; import android.os.IBinder; import android.os.PersistableBundle; import android.os.RemoteException; @@ -228,14 +229,14 @@ public final class UwbManager { * @param callbacks {@link RangingSession.Callback} to associate with the * {@link RangingSession} that is being opened. * - * @return an {@link AutoCloseable} that is able to be used to close or cancel the opening of a + * @return an {@link CancellationSignal} that is able to be used to cancel the opening of a * {@link RangingSession} that has been requested through {@link #openRangingSession} * but has not yet been made available by * {@link RangingSession.Callback#onOpened(RangingSession)}. */ @NonNull @RequiresPermission(Manifest.permission.UWB_PRIVILEGED) - public AutoCloseable openRangingSession(@NonNull PersistableBundle parameters, + public CancellationSignal openRangingSession(@NonNull PersistableBundle parameters, @NonNull @CallbackExecutor Executor executor, @NonNull RangingSession.Callback callbacks) { return mRangingManager.openSession(parameters, executor, callbacks); diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index a86984f44a41..31f6f6afdd53 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -80,5 +80,6 @@ per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS # Scroll Capture +per-file *ScrollCapture*.aidl = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 10f6c610d5d3..96818fa26a73 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -67,7 +67,7 @@ import java.util.function.Consumer; * <p>Content capture provides real-time, continuous capture of application activity, display and * events to an intelligence service that is provided by the Android system. The intelligence * service then uses that info to mediate and speed user journey through different apps. For - * example, when the user receives a restaurant address in a chat app and switchs to a map app + * example, when the user receives a restaurant address in a chat app and switches to a map app * to search for that restaurant, the intelligence service could offer an autofill dialog to * let the user automatically select its address. * diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS index 718076b49f77..64570a8ad155 100644 --- a/core/java/android/widget/OWNERS +++ b/core/java/android/widget/OWNERS @@ -5,6 +5,8 @@ alanv@google.com adamp@google.com aurimas@google.com siyamed@google.com +mount@google.com +njawad@google.com per-file TextView.java, EditText.java, Editor.java = siyamed@google.com, nona@google.com, clarabayarri@google.com diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java index 0b937fad7df1..364db06976a0 100644 --- a/core/java/com/android/internal/compat/AndroidBuildClassifier.java +++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java @@ -31,4 +31,14 @@ public class AndroidBuildClassifier { public boolean isFinalBuild() { return "REL".equals(Build.VERSION.CODENAME); } + + /** + * The current platform SDK version. + */ + public int platformTargetSdk() { + if (isFinalBuild()) { + return Build.VERSION.SDK_INT; + } + return Build.VERSION_CODES.CUR_DEVELOPMENT; + } } diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java index c0bbe5082131..e408be2ab471 100644 --- a/core/java/com/android/internal/compat/OverrideAllowedState.java +++ b/core/java/com/android/internal/compat/OverrideAllowedState.java @@ -34,7 +34,8 @@ public final class OverrideAllowedState implements Parcelable { DISABLED_NON_TARGET_SDK, DISABLED_TARGET_SDK_TOO_HIGH, DEFERRED_VERIFICATION, - LOGGING_ONLY_CHANGE + LOGGING_ONLY_CHANGE, + PLATFORM_TOO_OLD }) @Retention(RetentionPolicy.SOURCE) public @interface State { @@ -65,6 +66,10 @@ public final class OverrideAllowedState implements Parcelable { * Change is marked as logging only, and cannot be toggled. */ public static final int LOGGING_ONLY_CHANGE = 5; + /** + * Change is gated by a target sdk version newer than the current platform sdk version. + */ + public static final int PLATFORM_TOO_OLD = 6; @State public final int state; @@ -123,6 +128,11 @@ public final class OverrideAllowedState implements Parcelable { throw new SecurityException(String.format( "Cannot override %1$d because it is marked as a logging-only change.", changeId)); + case PLATFORM_TOO_OLD: + throw new SecurityException(String.format( + "Cannot override %1$d for %2$s because the change's targetSdk threshold " + + "(%3$d) is above the platform sdk.", + changeId, packageName, changeIdTargetSdk)); } } @@ -170,6 +180,8 @@ public final class OverrideAllowedState implements Parcelable { return "DEFERRED_VERIFICATION"; case LOGGING_ONLY_CHANGE: return "LOGGING_ONLY_CHANGE"; + case PLATFORM_TOO_OLD: + return "PLATFORM_TOO_OLD"; } return "UNKNOWN"; } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index fe87b64940fb..c220428df58b 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -648,8 +648,6 @@ public class ZygoteInit { */ private static void performSystemServerDexOpt(String classPath) { final String[] classPathElements = classPath.split(":"); - final IInstalld installd = IInstalld.Stub - .asInterface(ServiceManager.getService("installd")); final String instructionSet = VMRuntime.getRuntime().vmInstructionSet(); String classPathForElement = ""; @@ -686,6 +684,10 @@ public class ZygoteInit { final String uuid = StorageManager.UUID_PRIVATE_INTERNAL; final String seInfo = null; final int targetSdkVersion = 0; // SystemServer targets the system's SDK version + // Wait for installd to be made available + IInstalld installd = IInstalld.Stub.asInterface( + ServiceManager.waitForService("installd")); + try { installd.dexopt(classPathElement, Process.SYSTEM_UID, packageName, instructionSet, dexoptNeeded, outputPath, dexFlags, systemServerFilter, diff --git a/core/java/com/android/internal/view/inline/OWNERS b/core/java/com/android/internal/view/inline/OWNERS new file mode 100644 index 000000000000..edfb2112198a --- /dev/null +++ b/core/java/com/android/internal/view/inline/OWNERS @@ -0,0 +1 @@ +include /core/java/android/view/autofill/OWNERS diff --git a/core/java/com/android/internal/widget/OWNERS b/core/java/com/android/internal/widget/OWNERS index d284d5167843..8e68be0f742a 100644 --- a/core/java/com/android/internal/widget/OWNERS +++ b/core/java/com/android/internal/widget/OWNERS @@ -1,4 +1,6 @@ per-file PointerLocationView.java = michaelwr@google.com, svv@google.com +per-file RecyclerView.java = mount@google.com +per-file ViewPager.java = mount@google.com # LockSettings related per-file *LockPattern* = file:/services/core/java/com/android/server/locksettings/OWNERS |