diff options
47 files changed, 1104 insertions, 650 deletions
diff --git a/api/current.txt b/api/current.txt index e803640bf5c6..a18fab7ef865 100644 --- a/api/current.txt +++ b/api/current.txt @@ -19555,8 +19555,7 @@ package android.icu.number { method public T numberFormatterSecond(android.icu.number.UnlocalizedNumberFormatter); } - public abstract class Precision implements java.lang.Cloneable { - method public Object clone(); + public abstract class Precision { method public static android.icu.number.CurrencyPrecision currency(android.icu.util.Currency.CurrencyUsage); method public static android.icu.number.FractionPrecision fixedFraction(int); method public static android.icu.number.Precision fixedSignificantDigits(int); @@ -19579,8 +19578,7 @@ package android.icu.number { method public static android.icu.number.Scale powerOfTen(int); } - public class ScientificNotation extends android.icu.number.Notation implements java.lang.Cloneable { - method public Object clone(); + public class ScientificNotation extends android.icu.number.Notation { method public android.icu.number.ScientificNotation withExponentSignDisplay(android.icu.number.NumberFormatter.SignDisplay); method public android.icu.number.ScientificNotation withMinExponentDigits(int); } @@ -46010,6 +46008,7 @@ package android.telephony { field public static final int DATA_DISCONNECTING = 4; // 0x4 field public static final int DATA_SUSPENDED = 3; // 0x3 field public static final int DATA_UNKNOWN = -1; // 0xffffffff + field public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID"; field public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME"; @@ -46019,7 +46018,6 @@ package android.telephony { field public static final String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT"; field public static final String EXTRA_NETWORK_COUNTRY = "android.telephony.extra.NETWORK_COUNTRY"; field public static final String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT"; - field public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED"; field public static final String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE"; field public static final String EXTRA_SPECIFIC_CARRIER_ID = "android.telephony.extra.SPECIFIC_CARRIER_ID"; field public static final String EXTRA_SPECIFIC_CARRIER_NAME = "android.telephony.extra.SPECIFIC_CARRIER_NAME"; diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt index 1d646d476a77..7d137b90d467 100644 --- a/api/module-lib-current.txt +++ b/api/module-lib-current.txt @@ -29,7 +29,7 @@ package android.net { field @NonNull public static final android.os.Parcelable.Creator<android.net.TetheredClient.AddressInfo> CREATOR; } - public class TetheringConstants { + public final class TetheringConstants { field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType"; field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback"; field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType"; diff --git a/api/system-current.txt b/api/system-current.txt index 8de6290384ba..467b64f2de42 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -999,8 +999,8 @@ package android.app.compat { public final class CompatChanges { method public static boolean isChangeEnabled(long); - method public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle); - method public static boolean isChangeEnabled(long, int); + method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, @NonNull String, @NonNull android.os.UserHandle); + method @RequiresPermission(allOf={"android.permission.READ_COMPAT_CHANGE_CONFIG", "android.permission.LOG_COMPAT_CHANGE"}) public static boolean isChangeEnabled(long, int); } } @@ -1240,7 +1240,8 @@ package android.app.usage { } public class NetworkStatsManager { - method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public android.net.netstats.provider.NetworkStatsProviderCallback registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.AbstractNetworkStatsProvider); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider); } public static final class UsageEvents.Event { @@ -5181,21 +5182,17 @@ package android.net.metrics { package android.net.netstats.provider { - public abstract class AbstractNetworkStatsProvider { - ctor public AbstractNetworkStatsProvider(); - method public abstract void requestStatsUpdate(int); - method public abstract void setAlert(long); - method public abstract void setLimit(@NonNull String, long); + public abstract class NetworkStatsProvider { + ctor public NetworkStatsProvider(); + method public void notifyAlertReached(); + method public void notifyLimitReached(); + method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); + method public abstract void onRequestStatsUpdate(int); + method public abstract void onSetAlert(long); + method public abstract void onSetLimit(@NonNull String, long); field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff } - public class NetworkStatsProviderCallback { - method public void onAlertReached(); - method public void onLimitReached(); - method public void onStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats); - method public void unregister(); - } - } package android.net.sip { @@ -8949,19 +8946,6 @@ package android.telephony { field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000 } - public final class PinResult implements android.os.Parcelable { - ctor public PinResult(int, int); - method public int describeContents(); - method public int getAttemptsRemaining(); - method @NonNull public static android.telephony.PinResult getDefaultFailedResult(); - method public int getType(); - method public void writeToParcel(@NonNull android.os.Parcel, int); - field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PinResult> CREATOR; - field public static final int PIN_RESULT_TYPE_FAILURE = 2; // 0x2 - field public static final int PIN_RESULT_TYPE_INCORRECT = 1; // 0x1 - field public static final int PIN_RESULT_TYPE_SUCCESS = 0; // 0x0 - } - public final class PreciseCallState implements android.os.Parcelable { ctor public PreciseCallState(int, int, int, int, int); method public int describeContents(); @@ -9090,7 +9074,6 @@ package android.telephony { } public class ServiceState implements android.os.Parcelable { - method @NonNull public android.telephony.ServiceState createLocationInfoSanitizedCopy(boolean); method public void fillInNotifierBundle(@NonNull android.os.Bundle); method public int getDataNetworkType(); method public boolean getDataRoamingFromRegistration(); @@ -9274,7 +9257,7 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultVoiceSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean); - method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(boolean, int); + method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUiccApplicationsEnabled(int, boolean); field @RequiresPermission(android.Manifest.permission.MANAGE_SUBSCRIPTION_PLANS) public static final String ACTION_SUBSCRIPTION_PLANS_CHANGED = "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED"; field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff @@ -9444,10 +9427,8 @@ package android.telephony { method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoiceActivationState(int); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void shutdownAllRadios(); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPin(String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPinReportPinResult(@NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPinReportResult(String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean supplyPuk(String, String); - method @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public android.telephony.PinResult supplyPukReportPinResult(@NonNull String, @NonNull String); method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int[] supplyPukReportResult(String, String); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean switchSlots(int[]); method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff(); @@ -9615,23 +9596,6 @@ package android.telephony.cdma { package android.telephony.data { - public class ApnSetting implements android.os.Parcelable { - method @NonNull public static String getApnTypesStringFromBitmask(int); - field public static final String TYPE_ALL_STRING = "*"; - field public static final String TYPE_CBS_STRING = "cbs"; - field public static final String TYPE_DEFAULT_STRING = "default"; - field public static final String TYPE_DUN_STRING = "dun"; - field public static final String TYPE_EMERGENCY_STRING = "emergency"; - field public static final String TYPE_FOTA_STRING = "fota"; - field public static final String TYPE_HIPRI_STRING = "hipri"; - field public static final String TYPE_IA_STRING = "ia"; - field public static final String TYPE_IMS_STRING = "ims"; - field public static final String TYPE_MCX_STRING = "mcx"; - field public static final String TYPE_MMS_STRING = "mms"; - field public static final String TYPE_SUPL_STRING = "supl"; - field public static final String TYPE_XCAP_STRING = "xcap"; - } - public final class DataCallResponse implements android.os.Parcelable { method public int describeContents(); method @NonNull public java.util.List<android.net.LinkAddress> getAddresses(); diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java index e289a2775b79..6689507daadc 100644 --- a/core/java/android/app/compat/CompatChanges.java +++ b/core/java/android/app/compat/CompatChanges.java @@ -17,6 +17,7 @@ package android.app.compat; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.compat.Compatibility; import android.content.Context; @@ -59,14 +60,13 @@ public final class CompatChanges { * <p> Note that this involves a binder call to the system server (unless running in the system * server). If the binder call fails, a {@code RuntimeException} will be thrown. * - * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it - * doesn't, a {@code RuntimeException} will be thrown. - * * @param changeId The ID of the compatibility change in question. * @param packageName The package name of the app in question. * @param user The user that the operation is done for. * @return {@code true} if the change is enabled for the current app. */ + @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, + android.Manifest.permission.LOG_COMPAT_CHANGE}) public static boolean isChangeEnabled(long changeId, @NonNull String packageName, @NonNull UserHandle user) { IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( @@ -89,9 +89,6 @@ public final class CompatChanges { * <p> Note that this involves a binder call to the system server (unless running in the system * server). If the binder call fails, {@code RuntimeException} will be thrown. * - * <p> Caller must have android.permission.READ_COMPAT_CHANGE_CONFIG permission. If it - * doesn't, a {@code RuntimeException} will be thrown. - * * <p> Returns {@code true} if there are no installed packages for the required UID, or if the * change is enabled for ALL of the installed packages associated with the provided UID. Please * use a more specific API if you want a different behaviour for multi-package UIDs. @@ -100,6 +97,8 @@ public final class CompatChanges { * @param uid The UID of the app in question. * @return {@code true} if the change is enabled for the current app. */ + @RequiresPermission(allOf = {android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG, + android.Manifest.permission.LOG_COMPAT_CHANGE}) public static boolean isChangeEnabled(long changeId, int uid) { IPlatformCompat platformCompat = IPlatformCompat.Stub.asInterface( ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE)); diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java index 7d13f050a730..d6e77624a967 100644 --- a/core/java/android/app/usage/NetworkStatsManager.java +++ b/core/java/android/app/usage/NetworkStatsManager.java @@ -31,9 +31,8 @@ import android.net.INetworkStatsService; import android.net.NetworkIdentity; import android.net.NetworkStack; import android.net.NetworkTemplate; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; -import android.net.netstats.provider.NetworkStatsProviderWrapper; +import android.net.netstats.provider.INetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.os.Binder; import android.os.Handler; import android.os.Looper; @@ -528,34 +527,53 @@ public class NetworkStatsManager { /** * Registers a custom provider of {@link android.net.NetworkStats} to provide network statistics - * to the system. To unregister, invoke {@link NetworkStatsProviderCallback#unregister()}. + * to the system. To unregister, invoke {@link #unregisterNetworkStatsProvider}. * Note that no de-duplication of statistics between providers is performed, so each provider - * must only report network traffic that is not being reported by any other provider. + * must only report network traffic that is not being reported by any other provider. Also note + * that the provider cannot be re-registered after unregistering. * * @param tag a human readable identifier of the custom network stats provider. This is only * used for debugging. - * @param provider the subclass of {@link AbstractNetworkStatsProvider} that needs to be + * @param provider the subclass of {@link NetworkStatsProvider} that needs to be * registered to the system. - * @return a {@link NetworkStatsProviderCallback}, which can be used to report events to the - * system or unregister the provider. * @hide */ @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.NETWORK_STATS_PROVIDER, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) - @NonNull public NetworkStatsProviderCallback registerNetworkStatsProvider( + @NonNull public void registerNetworkStatsProvider( @NonNull String tag, - @NonNull AbstractNetworkStatsProvider provider) { + @NonNull NetworkStatsProvider provider) { try { - final NetworkStatsProviderWrapper wrapper = new NetworkStatsProviderWrapper(provider); - return new NetworkStatsProviderCallback( - mService.registerNetworkStatsProvider(tag, wrapper)); + if (provider.getProviderCallbackBinder() != null) { + throw new IllegalArgumentException("provider is already registered"); + } + final INetworkStatsProviderCallback cbBinder = + mService.registerNetworkStatsProvider(tag, provider.getProviderBinder()); + provider.setProviderCallbackBinder(cbBinder); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Unregisters an instance of {@link NetworkStatsProvider}. + * + * @param provider the subclass of {@link NetworkStatsProvider} that needs to be + * unregistered to the system. + * @hide + */ + @SystemApi + @RequiresPermission(anyOf = { + android.Manifest.permission.NETWORK_STATS_PROVIDER, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) + @NonNull public void unregisterNetworkStatsProvider(@NonNull NetworkStatsProvider provider) { + try { + provider.getProviderCallbackBinderOrThrow().unregister(); } catch (RemoteException e) { e.rethrowAsRuntimeException(); } - // Unreachable code, but compiler doesn't know about it. - return null; } private static NetworkTemplate createTemplate(int networkType, String subscriberId) { diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS new file mode 100644 index 000000000000..8ee72b577f3c --- /dev/null +++ b/core/java/android/hardware/usb/OWNERS @@ -0,0 +1,6 @@ +badhri@google.com +elaurent@google.com +moltmann@google.com +albertccwang@google.com +jameswei@google.com +howardyen@google.com
\ No newline at end of file diff --git a/core/java/android/inputmethodservice/OWNERS b/core/java/android/inputmethodservice/OWNERS new file mode 100644 index 000000000000..444719701df2 --- /dev/null +++ b/core/java/android/inputmethodservice/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/core/java/android/net/ConnectivityDiagnosticsManager.java b/core/java/android/net/ConnectivityDiagnosticsManager.java index d009144034f0..1710ccb31973 100644 --- a/core/java/android/net/ConnectivityDiagnosticsManager.java +++ b/core/java/android/net/ConnectivityDiagnosticsManager.java @@ -368,7 +368,14 @@ public class ConnectivityDiagnosticsManager { /** Class that includes information for a suspected data stall on a specific Network */ public static final class DataStallReport implements Parcelable { + /** + * Indicates that the Data Stall was detected using DNS events. + */ public static final int DETECTION_METHOD_DNS_EVENTS = 1; + + /** + * Indicates that the Data Stall was detected using TCP metrics. + */ public static final int DETECTION_METHOD_TCP_METRICS = 2; /** @hide */ diff --git a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java b/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java deleted file mode 100644 index 740aa92ad484..000000000000 --- a/core/java/android/net/netstats/provider/AbstractNetworkStatsProvider.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2020 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.netstats.provider; - -import android.annotation.NonNull; -import android.annotation.SystemApi; -import android.net.NetworkStats; - -/** - * A base class that allows external modules to implement a custom network statistics provider. - * @hide - */ -@SystemApi -public abstract class AbstractNetworkStatsProvider { - /** - * A value used by {@link #setLimit} and {@link #setAlert} indicates there is no limit. - */ - public static final int QUOTA_UNLIMITED = -1; - - /** - * Called by {@code NetworkStatsService} when global polling is needed. Custom - * implementation of providers MUST respond to it by calling - * {@link NetworkStatsProviderCallback#onStatsUpdated} within one minute. Responding - * later than this may cause the stats to be dropped. - * - * @param token a positive number identifying the new state of the system under which - * {@link NetworkStats} have to be gathered from now on. When this is called, - * custom implementations of providers MUST report the latest stats with the - * previous token, under which stats were being gathered so far. - */ - public abstract void requestStatsUpdate(int token); - - /** - * Called by {@code NetworkStatsService} when setting the interface quota for the specified - * upstream interface. When this is called, the custom implementation should block all egress - * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have - * been reached, and MUST respond to it by calling - * {@link NetworkStatsProviderCallback#onLimitReached()}. - * - * @param iface the interface requiring the operation. - * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting - * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. - */ - public abstract void setLimit(@NonNull String iface, long quotaBytes); - - /** - * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations - * MUST call {@link NetworkStatsProviderCallback#onAlertReached()} when {@code quotaBytes} bytes - * have been reached. Unlike {@link #setLimit(String, long)}, the custom implementation should - * not block all egress packets. - * - * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting - * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. - */ - public abstract void setAlert(long quotaBytes); -} diff --git a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl index 55b3d4edb157..4078b249218c 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProvider.aidl @@ -22,7 +22,7 @@ package android.net.netstats.provider; * @hide */ oneway interface INetworkStatsProvider { - void requestStatsUpdate(int token); - void setLimit(String iface, long quotaBytes); - void setAlert(long quotaBytes); + void onRequestStatsUpdate(int token); + void onSetLimit(String iface, long quotaBytes); + void onSetAlert(long quotaBytes); } diff --git a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl index 3ea9318f10d4..bd336dd348fe 100644 --- a/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl +++ b/core/java/android/net/netstats/provider/INetworkStatsProviderCallback.aidl @@ -24,8 +24,8 @@ import android.net.NetworkStats; * @hide */ oneway interface INetworkStatsProviderCallback { - void onStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); - void onAlertReached(); - void onLimitReached(); + void notifyStatsUpdated(int token, in NetworkStats ifaceStats, in NetworkStats uidStats); + void notifyAlertReached(); + void notifyLimitReached(); void unregister(); } diff --git a/core/java/android/net/netstats/provider/NetworkStatsProvider.java b/core/java/android/net/netstats/provider/NetworkStatsProvider.java new file mode 100644 index 000000000000..7639d2244cfe --- /dev/null +++ b/core/java/android/net/netstats/provider/NetworkStatsProvider.java @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2020 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.netstats.provider; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; +import android.net.NetworkStats; +import android.os.RemoteException; + +/** + * A base class that allows external modules to implement a custom network statistics provider. + * @hide + */ +@SystemApi +public abstract class NetworkStatsProvider { + /** + * A value used by {@link #onSetLimit} and {@link #onSetAlert} indicates there is no limit. + */ + public static final int QUOTA_UNLIMITED = -1; + + @NonNull private final INetworkStatsProvider mProviderBinder = + new INetworkStatsProvider.Stub() { + + @Override + public void onRequestStatsUpdate(int token) { + NetworkStatsProvider.this.onRequestStatsUpdate(token); + } + + @Override + public void onSetLimit(String iface, long quotaBytes) { + NetworkStatsProvider.this.onSetLimit(iface, quotaBytes); + } + + @Override + public void onSetAlert(long quotaBytes) { + NetworkStatsProvider.this.onSetAlert(quotaBytes); + } + }; + + // The binder given by the service when successfully registering. Only null before registering, + // never null once non-null. + @Nullable + private INetworkStatsProviderCallback mProviderCbBinder; + + /** + * Return the binder invoked by the service and redirect function calls to the overridden + * methods. + * @hide + */ + @NonNull + public INetworkStatsProvider getProviderBinder() { + return mProviderBinder; + } + + /** + * Store the binder that was returned by the service when successfully registering. Note that + * the provider cannot be re-registered. Hence this method can only be called once per provider. + * + * @hide + */ + public void setProviderCallbackBinder(@NonNull INetworkStatsProviderCallback binder) { + if (mProviderCbBinder != null) { + throw new IllegalArgumentException("provider is already registered"); + } + mProviderCbBinder = binder; + } + + /** + * Get the binder that was returned by the service when successfully registering. Or null if the + * provider was never registered. + * + * @hide + */ + @Nullable + public INetworkStatsProviderCallback getProviderCallbackBinder() { + return mProviderCbBinder; + } + + /** + * Get the binder that was returned by the service when successfully registering. Throw an + * {@link IllegalStateException} if the provider is not registered. + * + * @hide + */ + @NonNull + public INetworkStatsProviderCallback getProviderCallbackBinderOrThrow() { + if (mProviderCbBinder == null) { + throw new IllegalStateException("the provider is not registered"); + } + return mProviderCbBinder; + } + + /** + * Notify the system of new network statistics. + * + * Send the network statistics recorded since the last call to {@link #notifyStatsUpdated}. Must + * be called as soon as possible after {@link NetworkStatsProvider#onRequestStatsUpdate(int)} + * being called. Responding later increases the probability stats will be dropped. The + * provider can also call this whenever it wants to reports new stats for any reason. + * Note that the system will not necessarily immediately propagate the statistics to + * reflect the update. + * + * @param token the token under which these stats were gathered. Providers can call this method + * with the current token as often as they want, until the token changes. + * {@see NetworkStatsProvider#onRequestStatsUpdate()} + * @param ifaceStats the {@link NetworkStats} per interface to be reported. + * The provider should not include any traffic that is already counted by + * kernel interface counters. + * @param uidStats the same stats as above, but counts {@link NetworkStats} + * per uid. + */ + public void notifyStatsUpdated(int token, @NonNull NetworkStats ifaceStats, + @NonNull NetworkStats uidStats) { + try { + getProviderCallbackBinderOrThrow().notifyStatsUpdated(token, ifaceStats, uidStats); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code onSetAlert} has been reached. + */ + public void notifyAlertReached() { + try { + getProviderCallbackBinderOrThrow().notifyAlertReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Notify system that the quota set by {@code onSetLimit} has been reached. + */ + public void notifyLimitReached() { + try { + getProviderCallbackBinderOrThrow().notifyLimitReached(); + } catch (RemoteException e) { + e.rethrowAsRuntimeException(); + } + } + + /** + * Called by {@code NetworkStatsService} when it requires to know updated stats. + * The provider MUST respond by calling {@link #notifyStatsUpdated} as soon as possible. + * Responding later increases the probability stats will be dropped. Memory allowing, the + * system will try to take stats into account up to one minute after calling + * {@link #onRequestStatsUpdate}. + * + * @param token a positive number identifying the new state of the system under which + * {@link NetworkStats} have to be gathered from now on. When this is called, + * custom implementations of providers MUST tally and report the latest stats with + * the previous token, under which stats were being gathered so far. + */ + public abstract void onRequestStatsUpdate(int token); + + /** + * Called by {@code NetworkStatsService} when setting the interface quota for the specified + * upstream interface. When this is called, the custom implementation should block all egress + * packets on the {@code iface} associated with the provider when {@code quotaBytes} bytes have + * been reached, and MUST respond to it by calling + * {@link NetworkStatsProvider#notifyLimitReached()}. + * + * @param iface the interface requiring the operation. + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no limit. + */ + public abstract void onSetLimit(@NonNull String iface, long quotaBytes); + + /** + * Called by {@code NetworkStatsService} when setting the alert bytes. Custom implementations + * MUST call {@link NetworkStatsProvider#notifyAlertReached()} when {@code quotaBytes} bytes + * have been reached. Unlike {@link #onSetLimit(String, long)}, the custom implementation should + * not block all egress packets. + * + * @param quotaBytes the quota defined as the number of bytes, starting from zero and counting + * from now. A value of {@link #QUOTA_UNLIMITED} indicates there is no alert. + */ + public abstract void onSetAlert(long quotaBytes); +} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java b/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java deleted file mode 100644 index e17a8eee7ff0..000000000000 --- a/core/java/android/net/netstats/provider/NetworkStatsProviderCallback.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2020 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.netstats.provider; - -import android.annotation.NonNull; -import android.annotation.SuppressLint; -import android.annotation.SystemApi; -import android.net.NetworkStats; -import android.os.RemoteException; - -/** - * A callback class that allows callers to report events to the system. - * @hide - */ -@SystemApi -@SuppressLint("CallbackMethodName") -public class NetworkStatsProviderCallback { - @NonNull private final INetworkStatsProviderCallback mBinder; - - /** @hide */ - public NetworkStatsProviderCallback(@NonNull INetworkStatsProviderCallback binder) { - mBinder = binder; - } - - /** - * Notify the system of new network statistics. - * - * Send the network statistics recorded since the last call to {@link #onStatsUpdated}. Must be - * called within one minute of {@link AbstractNetworkStatsProvider#requestStatsUpdate(int)} - * being called. The provider can also call this whenever it wants to reports new stats for any - * reason. Note that the system will not necessarily immediately propagate the statistics to - * reflect the update. - * - * @param token the token under which these stats were gathered. Providers can call this method - * with the current token as often as they want, until the token changes. - * {@see AbstractNetworkStatsProvider#requestStatsUpdate()} - * @param ifaceStats the {@link NetworkStats} per interface to be reported. - * The provider should not include any traffic that is already counted by - * kernel interface counters. - * @param uidStats the same stats as above, but counts {@link NetworkStats} - * per uid. - */ - public void onStatsUpdated(int token, @NonNull NetworkStats ifaceStats, - @NonNull NetworkStats uidStats) { - try { - mBinder.onStatsUpdated(token, ifaceStats, uidStats); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Notify system that the quota set by {@code setAlert} has been reached. - */ - public void onAlertReached() { - try { - mBinder.onAlertReached(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Notify system that the quota set by {@code setLimit} has been reached. - */ - public void onLimitReached() { - try { - mBinder.onLimitReached(); - } catch (RemoteException e) { - e.rethrowAsRuntimeException(); - } - } - - /** - * Unregister the provider and the referencing callback. - */ - public void unregister() { - try { - mBinder.unregister(); - } catch (RemoteException e) { - // Ignore error. - } - } -} diff --git a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java b/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java deleted file mode 100644 index 4bf7c9bc086e..000000000000 --- a/core/java/android/net/netstats/provider/NetworkStatsProviderWrapper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2020 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.netstats.provider; - -import android.annotation.NonNull; - -/** - * A wrapper class of {@link INetworkStatsProvider} that hides the binder interface from exposing - * to outer world. - * - * @hide - */ -public class NetworkStatsProviderWrapper extends INetworkStatsProvider.Stub { - @NonNull final AbstractNetworkStatsProvider mProvider; - - public NetworkStatsProviderWrapper(AbstractNetworkStatsProvider provider) { - mProvider = provider; - } - - @Override - public void requestStatsUpdate(int token) { - mProvider.requestStatsUpdate(token); - } - - @Override - public void setLimit(@NonNull String iface, long quotaBytes) { - mProvider.setLimit(iface, quotaBytes); - } - - @Override - public void setAlert(long quotaBytes) { - mProvider.setAlert(quotaBytes); - } -} diff --git a/core/java/android/view/inputmethod/OWNERS b/core/java/android/view/inputmethod/OWNERS new file mode 100644 index 000000000000..244cc30e089e --- /dev/null +++ b/core/java/android/view/inputmethod/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/core/java/com/android/internal/inputmethod/OWNERS b/core/java/com/android/internal/inputmethod/OWNERS new file mode 100644 index 000000000000..fc0e5d4dea2b --- /dev/null +++ b/core/java/com/android/internal/inputmethod/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include ../../../../../../services/core/java/com/android/server/inputmethod/OWNERS diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 5fa14b56d321..e9d149db331d 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -233,6 +233,7 @@ applications that come with the platform </privapp-permissions> <privapp-permissions package="com.android.networkstack.tethering"> + <permission name="android.permission.BLUETOOTH_PRIVILEGED" /> <permission name="android.permission.MANAGE_USB"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/> diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp index 83f3b6ed6217..efeb3352d393 100644 --- a/media/jni/audioeffect/Visualizer.cpp +++ b/media/jni/audioeffect/Visualizer.cpp @@ -120,8 +120,9 @@ status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t } if (mCaptureThread != 0) { + sp<CaptureThread> t = mCaptureThread; mCaptureLock.unlock(); - mCaptureThread->requestExitAndWait(); + t->requestExitAndWait(); mCaptureLock.lock(); } diff --git a/media/tests/EffectsTest/res/layout/visualizertest.xml b/media/tests/EffectsTest/res/layout/visualizertest.xml index 50ac7bbd8cd0..18d7a3648fbf 100644 --- a/media/tests/EffectsTest/res/layout/visualizertest.xml +++ b/media/tests/EffectsTest/res/layout/visualizertest.xml @@ -56,6 +56,37 @@ android:layout_height="wrap_content" android:scaleType="fitXY"/> + <LinearLayout android:id="@+id/visuMultithreadedLayout" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="10dip" + android:layout_marginTop="10dip" + android:layout_marginRight="10dip" + android:layout_marginBottom="10dip" > + + <TextView android:id="@+id/visuMultithreaded" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_weight="1.0" + android:layout_gravity="center_vertical|left" + android:text="@string/effect_multithreaded" + style="@android:style/TextAppearance.Medium" /> + + <ToggleButton android:id="@+id/visuMultithreadedOnOff" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center_vertical|right" + android:layout_weight="0.0" /> + + </LinearLayout> + + <ImageView + android:src="@android:drawable/divider_horizontal_dark" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:scaleType="fitXY"/> + <LinearLayout android:id="@+id/visuControlLayout" android:orientation="horizontal" android:layout_width="fill_parent" diff --git a/media/tests/EffectsTest/res/values/strings.xml b/media/tests/EffectsTest/res/values/strings.xml index 2a8518417565..7c12da1274e3 100644 --- a/media/tests/EffectsTest/res/values/strings.xml +++ b/media/tests/EffectsTest/res/values/strings.xml @@ -35,4 +35,6 @@ <string name="effect_attach_off">Attach</string> <string name="effect_attach_on">Detach</string> <string name="send_level_name">Send Level</string> + <!-- Toggles use of a multi-threaded client for an effect [CHAR LIMIT=24] --> + <string name="effect_multithreaded">Multithreaded Use</string> </resources> diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java new file mode 100644 index 000000000000..817bd3d7bf5e --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstance.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.effectstest; + +interface VisualizerInstance { + void enableDataCaptureListener(boolean enable); + boolean getEnabled(); + void release(); + void setEnabled(boolean enabled); + void startStopCapture(boolean start); +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java new file mode 100644 index 000000000000..89cfbebe17ce --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceMT.java @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.effectstest; + +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +class VisualizerInstanceMT implements VisualizerInstance { + + private static final String TAG = "VisualizerInstanceMT"; + + private final Object mLock = new Object(); + private final int mThreadCount; + @GuardedBy("mLock") + private Handler mVisualizerHandler; + @GuardedBy("mLock") + private VisualizerInstanceSync mVisualizer; + + VisualizerInstanceMT(int session, Handler uiHandler, int extraThreadCount) { + Log.d(TAG, "Multi-threaded constructor"); + mThreadCount = 1 + extraThreadCount; + Thread t = new Thread() { + @Override public void run() { + Looper.prepare(); + VisualizerInstanceSync v = new VisualizerInstanceSync(session, uiHandler); + synchronized (mLock) { + mVisualizerHandler = new Handler(); + mVisualizer = v; + } + Looper.loop(); + } + }; + t.start(); + } + + private VisualizerInstance getVisualizer() { + synchronized (mLock) { + return mVisualizer != null ? new VisualizerInstanceSync(mVisualizer) : null; + } + } + + private interface VisualizerOperation { + void run(VisualizerInstance v); + } + + private void runOperationMt(VisualizerOperation op) { + final VisualizerInstance v = getVisualizer(); + if (v == null) return; + for (int i = 0; i < mThreadCount; ++i) { + Thread t = new Thread() { + @Override + public void run() { + op.run(v); + } + }; + t.start(); + } + } + + @Override + public void enableDataCaptureListener(boolean enable) { + runOperationMt(v -> v.enableDataCaptureListener(enable)); + } + + @Override + public boolean getEnabled() { + final VisualizerInstance v = getVisualizer(); + return v != null ? v.getEnabled() : false; + } + + @Override + public void release() { + runOperationMt(v -> v.release()); + synchronized (mLock) { + if (mVisualizerHandler == null) return; + mVisualizerHandler.post(() -> { + synchronized (mLock) { + mVisualizerHandler = null; + mVisualizer = null; + Looper.myLooper().quitSafely(); + } + Log.d(TAG, "Exiting looper"); + }); + } + } + + @Override + public void setEnabled(boolean enabled) { + runOperationMt(v -> v.setEnabled(enabled)); + } + + @Override + public void startStopCapture(boolean start) { + runOperationMt(v -> v.startStopCapture(start)); + } +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java new file mode 100644 index 000000000000..e64f4e5785c8 --- /dev/null +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerInstanceSync.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.effectstest; + +import android.media.audiofx.Visualizer; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +// This class only has `final' members, thus any thread-safety concerns +// can only come from the Visualizer effect class. +class VisualizerInstanceSync implements VisualizerInstance { + + private static final String TAG = "VisualizerInstance"; + + private final Handler mUiHandler; + private final Visualizer mVisualizer; + private final VisualizerTestHandler mVisualizerTestHandler; + private final VisualizerListener mVisualizerListener; + + VisualizerInstanceSync(int session, Handler uiHandler) { + mUiHandler = uiHandler; + try { + mVisualizer = new Visualizer(session); + } catch (UnsupportedOperationException e) { + Log.e(TAG, "Visualizer library not loaded"); + throw new RuntimeException("Cannot initialize effect"); + } catch (RuntimeException e) { + throw e; + } + mVisualizerTestHandler = new VisualizerTestHandler(); + mVisualizerListener = new VisualizerListener(); + } + + // Not a "deep" copy, only copies the references. + VisualizerInstanceSync(VisualizerInstanceSync other) { + mUiHandler = other.mUiHandler; + mVisualizer = other.mVisualizer; + mVisualizerTestHandler = other.mVisualizerTestHandler; + mVisualizerListener = other.mVisualizerListener; + } + + @Override + public void enableDataCaptureListener(boolean enable) { + mVisualizer.setDataCaptureListener(enable ? mVisualizerListener : null, + 10000, enable, enable); + } + + @Override + public boolean getEnabled() { + return mVisualizer.getEnabled(); + } + + @Override + public void release() { + mVisualizer.release(); + Log.d(TAG, "Visualizer released"); + } + + @Override + public void setEnabled(boolean enabled) { + mVisualizer.setEnabled(enabled); + } + + @Override + public void startStopCapture(boolean start) { + mVisualizerTestHandler.sendMessage(mVisualizerTestHandler.obtainMessage( + start ? MSG_START_CAPTURE : MSG_STOP_CAPTURE)); + } + + private static final int MSG_START_CAPTURE = 0; + private static final int MSG_STOP_CAPTURE = 1; + private static final int MSG_NEW_CAPTURE = 2; + private static final int CAPTURE_PERIOD_MS = 100; + + private static int[] dataToMinMaxCenter(byte[] data, int len) { + int[] minMaxCenter = new int[3]; + minMaxCenter[0] = data[0]; + minMaxCenter[1] = data[len - 1]; + minMaxCenter[2] = data[len / 2]; + return minMaxCenter; + } + + private class VisualizerTestHandler extends Handler { + private final int mCaptureSize; + private boolean mActive = false; + + VisualizerTestHandler() { + mCaptureSize = mVisualizer.getCaptureSize(); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_START_CAPTURE: + if (!mActive) { + Log.d(TAG, "Start capture"); + mActive = true; + sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS); + } + break; + case MSG_STOP_CAPTURE: + if (mActive) { + Log.d(TAG, "Stop capture"); + mActive = false; + } + break; + case MSG_NEW_CAPTURE: + if (mActive) { + if (mCaptureSize > 0) { + byte[] data = new byte[mCaptureSize]; + if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) { + int len = data.length < mCaptureSize ? data.length : mCaptureSize; + mUiHandler.sendMessage( + mUiHandler.obtainMessage( + VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL, + dataToMinMaxCenter(data, len))); + } + if (mVisualizer.getFft(data) == Visualizer.SUCCESS) { + int len = data.length < mCaptureSize ? data.length : mCaptureSize; + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL, + dataToMinMaxCenter(data, len))); + } + } + sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE), CAPTURE_PERIOD_MS); + } + break; + } + } + } + + private class VisualizerListener implements Visualizer.OnDataCaptureListener { + @Override + public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, + int samplingRate) { + if (visualizer == mVisualizer && waveform.length > 0) { + Log.d(TAG, "onWaveFormDataCapture(): " + waveform[0] + + " smp rate: " + samplingRate / 1000); + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_WAVEFORM_VAL, + dataToMinMaxCenter(waveform, waveform.length))); + } + } + + @Override + public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { + if (visualizer == mVisualizer && fft.length > 0) { + Log.d(TAG, "onFftDataCapture(): " + fft[0]); + mUiHandler.sendMessage( + mUiHandler.obtainMessage(VisualizerTest.MSG_DISPLAY_FFT_VAL, + dataToMinMaxCenter(fft, fft.length))); + } + } + } +} diff --git a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java index 7db1d8d8625e..2e141c5ef7c8 100644 --- a/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java +++ b/media/tests/EffectsTest/src/com/android/effectstest/VisualizerTest.java @@ -17,51 +17,42 @@ package com.android.effectstest; import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.media.audiofx.Visualizer; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; import android.view.KeyEvent; -import android.view.Menu; import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.Button; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.EditText; import android.widget.TextView; import android.widget.ToggleButton; -import android.widget.SeekBar; -import java.nio.ByteOrder; -import java.nio.ByteBuffer; import java.util.HashMap; -import java.util.Map; public class VisualizerTest extends Activity implements OnCheckedChangeListener { private final static String TAG = "Visualizer Test"; - private Visualizer mVisualizer; + private VisualizerInstance mVisualizer; + ToggleButton mMultithreadedButton; ToggleButton mOnOffButton; ToggleButton mReleaseButton; + boolean mUseMTInstance; boolean mEnabled; EditText mSessionText; static int sSession = 0; - int mCaptureSize; ToggleButton mCallbackButton; boolean mCallbackOn; - VisualizerListener mVisualizerListener; - private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10); - private VisualizerTestHandler mVisualizerTestHandler = null; + private static HashMap<Integer, VisualizerInstance> sInstances = + new HashMap<Integer, VisualizerInstance>(10); + private Handler mUiHandler; public VisualizerTest() { Log.d(TAG, "contructor"); + mUiHandler = new UiHandler(Looper.getMainLooper()); } @Override @@ -76,109 +67,45 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mSessionText.setOnKeyListener(mSessionKeyListener); mSessionText.setText(Integer.toString(sSession)); - mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton); - mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff); - mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff); + mMultithreadedButton = (ToggleButton) findViewById(R.id.visuMultithreadedOnOff); + mReleaseButton = (ToggleButton) findViewById(R.id.visuReleaseButton); + mOnOffButton = (ToggleButton) findViewById(R.id.visualizerOnOff); + mCallbackButton = (ToggleButton) findViewById(R.id.visuCallbackOnOff); mCallbackOn = false; mCallbackButton.setChecked(mCallbackOn); - mVisualizerTestHandler = new VisualizerTestHandler(); - mVisualizerListener = new VisualizerListener(); - - getEffect(sSession); - - if (mVisualizer != null) { + mMultithreadedButton.setOnCheckedChangeListener(this); + if (getEffect(sSession) != null) { mReleaseButton.setOnCheckedChangeListener(this); mOnOffButton.setOnCheckedChangeListener(this); mCallbackButton.setOnCheckedChangeListener(this); } } - private static final int MSG_START_CAPTURE = 0; - private static final int MSG_STOP_CAPTURE = 1; - private static final int MSG_NEW_CAPTURE = 2; - private static final int CAPTURE_PERIOD_MS = 100; + public static final int MSG_DISPLAY_WAVEFORM_VAL = 0; + public static final int MSG_DISPLAY_FFT_VAL = 1; + + private class UiHandler extends Handler { + UiHandler(Looper looper) { + super(looper); + } - private class VisualizerTestHandler extends Handler { - boolean mActive = false; @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_START_CAPTURE: - if (!mActive) { - Log.d(TAG, "Start capture"); - mActive = true; - sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); - } - break; - case MSG_STOP_CAPTURE: - if (mActive) { - Log.d(TAG, "Stop capture"); - mActive = false; - } - break; - case MSG_NEW_CAPTURE: - if (mActive && mVisualizer != null) { - if (mCaptureSize > 0) { - byte[] data = new byte[mCaptureSize]; - if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) { - int len = data.length < mCaptureSize ? data.length : mCaptureSize; - displayVal(R.id.waveformMin, data[0]); - displayVal(R.id.waveformMax, data[len-1]); - displayVal(R.id.waveformCenter, data[len/2]); - }; - if (mVisualizer.getFft(data) == Visualizer.SUCCESS) { - int len = data.length < mCaptureSize ? data.length : mCaptureSize; - displayVal(R.id.fftMin, data[0]); - displayVal(R.id.fftMax, data[len-1]); - displayVal(R.id.fftCenter, data[len/2]); - }; - } - sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); - } - break; - } - } - } - - private class VisualizerListener implements Visualizer.OnDataCaptureListener { - - public VisualizerListener() { - } - public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { - if (visualizer == mVisualizer) { - if (waveform.length > 0) { - Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000); - displayVal(R.id.waveformMin, waveform[0]); - displayVal(R.id.waveformMax, waveform[waveform.length - 1]); - displayVal(R.id.waveformCenter, waveform[waveform.length/2]); + case MSG_DISPLAY_WAVEFORM_VAL: + case MSG_DISPLAY_FFT_VAL: + int[] minMaxCenter = (int[]) msg.obj; + boolean waveform = msg.what == MSG_DISPLAY_WAVEFORM_VAL; + displayVal(waveform ? R.id.waveformMin : R.id.fftMin, minMaxCenter[0]); + displayVal(waveform ? R.id.waveformMax : R.id.fftMax, minMaxCenter[1]); + displayVal(waveform ? R.id.waveformCenter : R.id.fftCenter, minMaxCenter[2]); + break; } - } - } - public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { - if (visualizer == mVisualizer) { - if (fft.length > 0) { - Log.d(TAG, "onFftDataCapture(): "+fft[0]); - displayVal(R.id.fftMin, fft[0]); - displayVal(R.id.fftMax, fft[fft.length - 1]); - displayVal(R.id.fftCenter, fft[fft.length/2]); - } - } } } - @Override - public void onResume() { - super.onResume(); - } - - @Override - public void onPause() { - super.onPause(); - } - - private View.OnKeyListener mSessionKeyListener - = new View.OnKeyListener() { + private View.OnKeyListener mSessionKeyListener = new View.OnKeyListener() { public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (keyCode) { @@ -199,29 +126,26 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener }; // OnCheckedChangeListener + @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (buttonView.getId() == R.id.visuMultithreadedOnOff) { + mUseMTInstance = isChecked; + Log.d(TAG, "Multi-threaded client: " + (isChecked ? "enabled" : "disabled")); + } if (buttonView.getId() == R.id.visualizerOnOff) { if (mVisualizer != null) { mEnabled = isChecked; mCallbackButton.setEnabled(!mEnabled); if (mCallbackOn && mEnabled) { - mVisualizer.setDataCaptureListener(mVisualizerListener, - 10000, - true, - true); + mVisualizer.enableDataCaptureListener(true); } mVisualizer.setEnabled(mEnabled); if (mCallbackOn) { if (!mEnabled) { - mVisualizer.setDataCaptureListener(null, - 10000, - false, - false); + mVisualizer.enableDataCaptureListener(false); } } else { - int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE; - mVisualizerTestHandler.sendMessage( - mVisualizerTestHandler.obtainMessage(msg, 0, 0, null)); + mVisualizer.startStopCapture(isChecked); } } } @@ -248,16 +172,15 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener } - private void getEffect(int session) { + private VisualizerInstance getEffect(int session) { synchronized (sInstances) { if (sInstances.containsKey(session)) { mVisualizer = sInstances.get(session); } else { - try{ - mVisualizer = new Visualizer(session); - } catch (UnsupportedOperationException e) { - Log.e(TAG,"Visualizer library not loaded"); - throw (new RuntimeException("Cannot initialize effect")); + try { + mVisualizer = mUseMTInstance + ? new VisualizerInstanceMT(session, mUiHandler, 0 /*extraThreadCount*/) + : new VisualizerInstanceSync(session, mUiHandler); } catch (RuntimeException e) { throw e; } @@ -267,8 +190,6 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mReleaseButton.setEnabled(false); mOnOffButton.setEnabled(false); if (mVisualizer != null) { - mCaptureSize = mVisualizer.getCaptureSize(); - mReleaseButton.setChecked(true); mReleaseButton.setEnabled(true); @@ -278,6 +199,7 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener mCallbackButton.setEnabled(!mEnabled); } + return mVisualizer; } private void putEffect(int session) { @@ -286,9 +208,8 @@ public class VisualizerTest extends Activity implements OnCheckedChangeListener synchronized (sInstances) { if (mVisualizer != null) { mVisualizer.release(); - Log.d(TAG,"Visualizer released"); - mVisualizer = null; sInstances.remove(session); + mVisualizer = null; } } } diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml index 24374e80b211..df717f601763 100644 --- a/packages/SystemUI/res/layout/menu_ime.xml +++ b/packages/SystemUI/res/layout/menu_ime.xml @@ -17,13 +17,13 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:id="@+id/menu_container" - android:layout_width="@dimen/navigation_key_width" + android:layout_width="@dimen/navigation_side_padding" android:layout_height="match_parent" android:importantForAccessibility="no" > <!-- Use nav button width & height=match_parent for parent FrameLayout and buttons because they are placed inside a view that has a size controlled by weight. Ensure weight is large enough to - support icon size. --> + support icon size. Use layout_width=navigation_side_padding like other navbar buttons. --> <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index c08726de9b66..e3d8ea2f9048 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar.policy; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT; import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE; @@ -160,6 +161,7 @@ public class NetworkControllerImpl extends BroadcastReceiver ServiceState mLastServiceState; private boolean mUserSetup; private boolean mSimDetected; + private boolean mForceCellularValidated; /** * Construct this controller object and register for updates. @@ -275,12 +277,41 @@ public class NetworkControllerImpl extends BroadcastReceiver mPhoneStateListener = new PhoneStateListener(bgLooper) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { + // For data switching from A to B, we assume B is validated for up to 2 seconds iff: + // 1) A and B are in the same subscription group e.g. CBRS data switch. And + // 2) A was validated before the switch. + // This is to provide smooth transition for UI without showing cross during data + // switch. + if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) { + if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true."); + mForceCellularValidated = true; + mReceiverHandler.removeCallbacks(mClearForceValidated); + mReceiverHandler.postDelayed(mClearForceValidated, 2000); + } mActiveMobileDataSubscription = subId; doUpdateMobileControllers(); } }; } + private final Runnable mClearForceValidated = () -> { + if (DEBUG) Log.d(TAG, ": mClearForceValidated"); + mForceCellularValidated = false; + updateConnectivity(); + }; + + boolean isInGroupDataSwitch(int subId1, int subId2) { + SubscriptionInfo info1 = mSubscriptionManager.getActiveSubscriptionInfo(subId1); + SubscriptionInfo info2 = mSubscriptionManager.getActiveSubscriptionInfo(subId2); + return (info1 != null && info2 != null && info1.getGroupUuid() != null + && info1.getGroupUuid().equals(info2.getGroupUuid())); + } + + boolean keepCellularValidationBitInSwitch(int sourceSubId, int destSubId) { + return mValidatedTransports.get(TRANSPORT_CELLULAR) + && isInGroupDataSwitch(sourceSubId, destSubId); + } + public DataSaverController getDataSaverController() { return mDataSaverController; } @@ -794,6 +825,8 @@ public class NetworkControllerImpl extends BroadcastReceiver } } + if (mForceCellularValidated) mValidatedTransports.set(TRANSPORT_CELLULAR); + if (CHATTY) { Log.d(TAG, "updateConnectivity: mConnectedTransports=" + mConnectedTransports); Log.d(TAG, "updateConnectivity: mValidatedTransports=" + mValidatedTransports); diff --git a/packages/Tethering/AndroidManifest.xml b/packages/Tethering/AndroidManifest.xml index c71d0d7bc543..9328611f5d3f 100644 --- a/packages/Tethering/AndroidManifest.xml +++ b/packages/Tethering/AndroidManifest.xml @@ -27,7 +27,7 @@ added to the privileged permissions whitelist for that package. --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.MANAGE_USB" /> diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java index 8b8b9e57a500..48be0d96425c 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheredClient.java @@ -64,16 +64,26 @@ public final class TetheredClient implements Parcelable { dest.writeInt(mTetheringType); } + /** + * Get the MAC address used to identify the client. + */ @NonNull public MacAddress getMacAddress() { return mMacAddress; } + /** + * Get information on the list of addresses that are associated with the client. + */ @NonNull public List<AddressInfo> getAddresses() { return new ArrayList<>(mAddresses); } + /** + * Get the type of tethering used by the client. + * @return one of the {@code TetheringManager#TETHERING_*} constants. + */ public int getTetheringType() { return mTetheringType; } @@ -115,45 +125,47 @@ public final class TetheredClient implements Parcelable { private final LinkAddress mAddress; @Nullable private final String mHostname; - // TODO: use LinkAddress expiration time once it is supported - private final long mExpirationTime; /** @hide */ public AddressInfo(@NonNull LinkAddress address, @Nullable String hostname) { - this(address, hostname, 0); - } - - /** @hide */ - public AddressInfo(@NonNull LinkAddress address, String hostname, long expirationTime) { this.mAddress = address; this.mHostname = hostname; - this.mExpirationTime = expirationTime; } private AddressInfo(Parcel in) { - this(in.readParcelable(null), in.readString(), in.readLong()); + this(in.readParcelable(null), in.readString()); } @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mAddress, flags); dest.writeString(mHostname); - dest.writeLong(mExpirationTime); } + /** + * Get the link address (including prefix length and lifetime) used by the client. + * + * This may be an IPv4 or IPv6 address. + */ @NonNull public LinkAddress getAddress() { return mAddress; } + /** + * Get the hostname that was advertised by the client when obtaining its address, if any. + */ @Nullable public String getHostname() { return mHostname; } - /** @hide TODO: use expiration time in LinkAddress */ + /** + * Get the expiration time of the address assigned to the client. + * @hide + */ public long getExpirationTime() { - return mExpirationTime; + return mAddress.getExpirationTime(); } @Override @@ -163,7 +175,7 @@ public final class TetheredClient implements Parcelable { @Override public int hashCode() { - return Objects.hash(mAddress, mHostname, mExpirationTime); + return Objects.hash(mAddress, mHostname); } @Override @@ -173,8 +185,7 @@ public final class TetheredClient implements Parcelable { // Use .equals() for addresses as all changes, including address expiry changes, // should be included. return other.mAddress.equals(mAddress) - && Objects.equals(mHostname, other.mHostname) - && mExpirationTime == other.mExpirationTime; + && Objects.equals(mHostname, other.mHostname); } @NonNull diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java index a18f5da60cad..fd6f171487a9 100644 --- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java +++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringConstants.java @@ -32,7 +32,7 @@ import android.os.ResultReceiver; * @hide */ @SystemApi(client = MODULE_LIBRARIES) -public class TetheringConstants { +public final class TetheringConstants { /** An explicit private class to avoid exposing constructor.*/ private TetheringConstants() { } diff --git a/packages/Tethering/src/android/net/ip/IpServer.java b/packages/Tethering/src/android/net/ip/IpServer.java index 38f8609e217f..6c0c432d46dc 100644 --- a/packages/Tethering/src/android/net/ip/IpServer.java +++ b/packages/Tethering/src/android/net/ip/IpServer.java @@ -24,6 +24,7 @@ import static android.net.util.NetworkConstants.FF; import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH; import static android.net.util.NetworkConstants.asByte; import static android.net.util.TetheringMessageBase.BASE_IPSERVER; +import static android.system.OsConstants.RT_SCOPE_UNIVERSE; import android.net.INetd; import android.net.INetworkStackStatusCallback; @@ -448,7 +449,9 @@ public class IpServer extends StateMachine { final ArrayList<TetheredClient> leases = new ArrayList<>(); for (DhcpLeaseParcelable lease : leaseParcelables) { final LinkAddress address = new LinkAddress( - intToInet4AddressHTH(lease.netAddr), lease.prefixLength); + intToInet4AddressHTH(lease.netAddr), lease.prefixLength, + 0 /* flags */, RT_SCOPE_UNIVERSE /* as per RFC6724#3.2 */, + lease.expTime /* deprecationTime */, lease.expTime /* expirationTime */); final MacAddress macAddress; try { @@ -460,7 +463,7 @@ public class IpServer extends StateMachine { } final TetheredClient.AddressInfo addressInfo = new TetheredClient.AddressInfo( - address, lease.hostname, lease.expTime); + address, lease.hostname); leases.add(new TetheredClient( macAddress, Collections.singletonList(addressInfo), diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java index a402ffa47355..d43c5c682f67 100644 --- a/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java +++ b/packages/Tethering/src/com/android/server/connectivity/tethering/OffloadController.java @@ -39,8 +39,7 @@ import android.net.RouteInfo; import android.net.netlink.ConntrackMessage; import android.net.netlink.NetlinkConstants; import android.net.netlink.NetlinkSocket; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.net.util.SharedLog; import android.os.Handler; import android.provider.Settings; @@ -89,8 +88,8 @@ public class OffloadController { private final Handler mHandler; private final OffloadHardwareInterface mHwInterface; private final ContentResolver mContentResolver; - private final @NonNull OffloadTetheringStatsProvider mStatsProvider; - private final @Nullable NetworkStatsProviderCallback mStatsProviderCb; + @Nullable + private final OffloadTetheringStatsProvider mStatsProvider; private final SharedLog mLog; private final HashMap<String, LinkProperties> mDownstreams; private boolean mConfigInitialized; @@ -124,19 +123,18 @@ public class OffloadController { mHandler = h; mHwInterface = hwi; mContentResolver = contentResolver; - mStatsProvider = new OffloadTetheringStatsProvider(); mLog = log.forSubComponent(TAG); mDownstreams = new HashMap<>(); mExemptPrefixes = new HashSet<>(); mLastLocalPrefixStrs = new HashSet<>(); - NetworkStatsProviderCallback providerCallback = null; + OffloadTetheringStatsProvider provider = new OffloadTetheringStatsProvider(); try { - providerCallback = nsm.registerNetworkStatsProvider( - getClass().getSimpleName(), mStatsProvider); + nsm.registerNetworkStatsProvider(getClass().getSimpleName(), provider); } catch (RuntimeException e) { Log.wtf(TAG, "Cannot register offload stats provider: " + e); + provider = null; } - mStatsProviderCb = providerCallback; + mStatsProvider = provider; } /** Start hardware offload. */ @@ -185,7 +183,7 @@ public class OffloadController { // and we need to synchronize stats and limits between // software and hardware forwarding. updateStatsForAllUpstreams(); - mStatsProvider.pushTetherStats(); + if (mStatsProvider != null) mStatsProvider.pushTetherStats(); } @Override @@ -198,7 +196,7 @@ public class OffloadController { // limits set take into account any software tethering // traffic that has been happening in the meantime. updateStatsForAllUpstreams(); - mStatsProvider.pushTetherStats(); + if (mStatsProvider != null) mStatsProvider.pushTetherStats(); // [2] (Re)Push all state. computeAndPushLocalPrefixes(UpdateType.FORCE); pushAllDownstreamState(); @@ -217,10 +215,12 @@ public class OffloadController { // TODO: rev the HAL so that it provides an interface name. updateStatsForCurrentUpstream(); - mStatsProvider.pushTetherStats(); - // Push stats to service does not cause the service react to it immediately. - // Inform the service about limit reached. - if (mStatsProviderCb != null) mStatsProviderCb.onLimitReached(); + if (mStatsProvider != null) { + mStatsProvider.pushTetherStats(); + // Push stats to service does not cause the service react to it + // immediately. Inform the service about limit reached. + mStatsProvider.notifyLimitReached(); + } } @Override @@ -263,13 +263,17 @@ public class OffloadController { } @VisibleForTesting - class OffloadTetheringStatsProvider extends AbstractNetworkStatsProvider { + class OffloadTetheringStatsProvider extends NetworkStatsProvider { // These stats must only ever be touched on the handler thread. @NonNull private NetworkStats mIfaceStats = new NetworkStats(0L, 0); @NonNull private NetworkStats mUidStats = new NetworkStats(0L, 0); + /** + * A helper function that collect tether stats from local hashmap. Note that this does not + * invoke binder call. + */ @VisibleForTesting @NonNull NetworkStats getTetherStats(@NonNull StatsType how) { @@ -287,7 +291,7 @@ public class OffloadController { } @Override - public void setLimit(String iface, long quotaBytes) { + public void onSetLimit(String iface, long quotaBytes) { // Listen for all iface is necessary since upstream might be changed after limit // is set. mHandler.post(() -> { @@ -315,13 +319,12 @@ public class OffloadController { */ public void pushTetherStats() { // TODO: remove the accumulated stats and report the diff from HAL directly. - if (null == mStatsProviderCb) return; final NetworkStats ifaceDiff = getTetherStats(StatsType.STATS_PER_IFACE).subtract(mIfaceStats); final NetworkStats uidDiff = getTetherStats(StatsType.STATS_PER_UID).subtract(mUidStats); try { - mStatsProviderCb.onStatsUpdated(0 /* token */, ifaceDiff, uidDiff); + notifyStatsUpdated(0 /* token */, ifaceDiff, uidDiff); mIfaceStats = mIfaceStats.add(ifaceDiff); mUidStats = mUidStats.add(uidDiff); } catch (RuntimeException e) { @@ -330,7 +333,7 @@ public class OffloadController { } @Override - public void requestStatsUpdate(int token) { + public void onRequestStatsUpdate(int token) { // Do not attempt to update stats by querying the offload HAL // synchronously from a different thread than the Handler thread. http://b/64771555. mHandler.post(() -> { @@ -340,7 +343,7 @@ public class OffloadController { } @Override - public void setAlert(long quotaBytes) { + public void onSetAlert(long quotaBytes) { // TODO: Ask offload HAL to notify alert without stopping traffic. } } diff --git a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt index d85389aeb625..a20a0dfd9c89 100644 --- a/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt +++ b/packages/Tethering/tests/unit/src/android/net/TetheredClientTest.kt @@ -20,6 +20,7 @@ import android.net.InetAddresses.parseNumericAddress import android.net.TetheredClient.AddressInfo import android.net.TetheringManager.TETHERING_BLUETOOTH import android.net.TetheringManager.TETHERING_USB +import android.system.OsConstants.RT_SCOPE_UNIVERSE import androidx.test.filters.SmallTest import androidx.test.runner.AndroidJUnit4 import com.android.testutils.assertParcelSane @@ -30,11 +31,19 @@ import kotlin.test.assertNotEquals private val TEST_MACADDR = MacAddress.fromBytes(byteArrayOf(12, 23, 34, 45, 56, 67)) private val TEST_OTHER_MACADDR = MacAddress.fromBytes(byteArrayOf(23, 34, 45, 56, 67, 78)) -private val TEST_ADDR1 = LinkAddress(parseNumericAddress("192.168.113.3"), 24) -private val TEST_ADDR2 = LinkAddress(parseNumericAddress("fe80::1:2:3"), 64) +private val TEST_ADDR1 = makeLinkAddress("192.168.113.3", prefixLength = 24, expTime = 123L) +private val TEST_ADDR2 = makeLinkAddress("fe80::1:2:3", prefixLength = 64, expTime = 456L) private val TEST_ADDRINFO1 = AddressInfo(TEST_ADDR1, "test_hostname") private val TEST_ADDRINFO2 = AddressInfo(TEST_ADDR2, null) +private fun makeLinkAddress(addr: String, prefixLength: Int, expTime: Long) = LinkAddress( + parseNumericAddress(addr), + prefixLength, + 0 /* flags */, + RT_SCOPE_UNIVERSE, + expTime /* deprecationTime */, + expTime /* expirationTime */) + @RunWith(AndroidJUnit4::class) @SmallTest class TetheredClientTest { diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt index 56f3e21cbffe..1cdc3bbb9933 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/ConnectedClientsTrackerTest.kt @@ -46,23 +46,28 @@ class ConnectedClientsTrackerTest { private val client1Addr = MacAddress.fromString("01:23:45:67:89:0A") private val client1 = TetheredClient(client1Addr, listOf( - AddressInfo(LinkAddress("192.168.43.44/32"), null /* hostname */, clock.time + 20)), + makeAddrInfo("192.168.43.44/32", null /* hostname */, clock.time + 20)), TETHERING_WIFI) private val wifiClient1 = makeWifiClient(client1Addr) private val client2Addr = MacAddress.fromString("02:34:56:78:90:AB") - private val client2Exp30AddrInfo = AddressInfo( - LinkAddress("192.168.43.45/32"), "my_hostname", clock.time + 30) + private val client2Exp30AddrInfo = makeAddrInfo( + "192.168.43.45/32", "my_hostname", clock.time + 30) private val client2 = TetheredClient(client2Addr, listOf( client2Exp30AddrInfo, - AddressInfo(LinkAddress("2001:db8:12::34/72"), "other_hostname", clock.time + 10)), + makeAddrInfo("2001:db8:12::34/72", "other_hostname", clock.time + 10)), TETHERING_WIFI) private val wifiClient2 = makeWifiClient(client2Addr) private val client3Addr = MacAddress.fromString("03:45:67:89:0A:BC") private val client3 = TetheredClient(client3Addr, - listOf(AddressInfo(LinkAddress("2001:db8:34::34/72"), "other_other_hostname", - clock.time + 10)), + listOf(makeAddrInfo("2001:db8:34::34/72", "other_other_hostname", clock.time + 10)), TETHERING_USB) + private fun makeAddrInfo(addr: String, hostname: String?, expTime: Long) = + LinkAddress(addr).let { + AddressInfo(LinkAddress(it.address, it.prefixLength, it.flags, it.scope, + expTime /* deprecationTime */, expTime /* expirationTime */), hostname) + } + @Test fun testUpdateConnectedClients() { doReturn(emptyList<TetheredClient>()).`when`(server1).allLeases diff --git a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java index 7e62e5aca993..1d100e63215b 100644 --- a/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java +++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/OffloadControllerTest.java @@ -33,6 +33,8 @@ import static com.android.testutils.MiscAssertsKt.assertContainsAll; import static com.android.testutils.MiscAssertsKt.assertThrows; import static com.android.testutils.NetworkStatsUtilsKt.orderInsensitiveEquals; +import static junit.framework.Assert.assertNotNull; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; @@ -61,8 +63,7 @@ import android.net.LinkProperties; import android.net.NetworkStats; import android.net.NetworkStats.Entry; import android.net.RouteInfo; -import android.net.netstats.provider.AbstractNetworkStatsProvider; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.INetworkStatsProviderCallback; import android.net.util.SharedLog; import android.os.Handler; import android.os.Looper; @@ -108,12 +109,10 @@ public class OffloadControllerTest { @Mock private ApplicationInfo mApplicationInfo; @Mock private Context mContext; @Mock private NetworkStatsManager mStatsManager; - @Mock private NetworkStatsProviderCallback mTetherStatsProviderCb; + @Mock private INetworkStatsProviderCallback mTetherStatsProviderCb; + private OffloadController.OffloadTetheringStatsProvider mTetherStatsProvider; private final ArgumentCaptor<ArrayList> mStringArrayCaptor = ArgumentCaptor.forClass(ArrayList.class); - private final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> - mTetherStatsProviderCaptor = - ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); private final ArgumentCaptor<OffloadHardwareInterface.ControlCallback> mControlCallbackCaptor = ArgumentCaptor.forClass(OffloadHardwareInterface.ControlCallback.class); private MockContentResolver mContentResolver; @@ -126,8 +125,6 @@ public class OffloadControllerTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); FakeSettingsProvider.clearSettingsProvider(); - when(mStatsManager.registerNetworkStatsProvider(anyString(), any())) - .thenReturn(mTetherStatsProviderCb); } @After public void tearDown() throws Exception { @@ -154,8 +151,14 @@ public class OffloadControllerTest { private OffloadController makeOffloadController() throws Exception { OffloadController offload = new OffloadController(new Handler(Looper.getMainLooper()), mHardware, mContentResolver, mStatsManager, new SharedLog("test")); + final ArgumentCaptor<OffloadController.OffloadTetheringStatsProvider> + tetherStatsProviderCaptor = + ArgumentCaptor.forClass(OffloadController.OffloadTetheringStatsProvider.class); verify(mStatsManager).registerNetworkStatsProvider(anyString(), - mTetherStatsProviderCaptor.capture()); + tetherStatsProviderCaptor.capture()); + mTetherStatsProvider = tetherStatsProviderCaptor.getValue(); + assertNotNull(mTetherStatsProvider); + mTetherStatsProvider.setProviderCallbackBinder(mTetherStatsProviderCb); return offload; } @@ -413,9 +416,6 @@ public class OffloadControllerTest { final OffloadController offload = makeOffloadController(); offload.start(); - final OffloadController.OffloadTetheringStatsProvider provider = - mTetherStatsProviderCaptor.getValue(); - final String ethernetIface = "eth1"; final String mobileIface = "rmnet_data0"; @@ -443,8 +443,8 @@ public class OffloadControllerTest { inOrder.verify(mHardware, times(1)).getForwardedStats(eq(mobileIface)); // Verify that the fetched stats are stored. - final NetworkStats ifaceStats = provider.getTetherStats(STATS_PER_IFACE); - final NetworkStats uidStats = provider.getTetherStats(STATS_PER_UID); + final NetworkStats ifaceStats = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStats = mTetherStatsProvider.getTetherStats(STATS_PER_UID); final NetworkStats expectedIfaceStats = new NetworkStats(0L, 2) .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 12345, 54321)); @@ -462,13 +462,12 @@ public class OffloadControllerTest { NetworkStats.class); // Force pushing stats update to verify the stats reported. - provider.pushTetherStats(); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), - ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + mTetherStatsProvider.pushTetherStats(); + verify(mTetherStatsProviderCb, times(1)) + .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); assertTrue(orderInsensitiveEquals(expectedIfaceStats, ifaceStatsCaptor.getValue())); assertTrue(orderInsensitiveEquals(expectedUidStats, uidStatsCaptor.getValue())); - when(mHardware.getForwardedStats(eq(ethernetIface))).thenReturn( new ForwardedStats(100000, 100000)); offload.setUpstreamLinkProperties(null); @@ -483,8 +482,8 @@ public class OffloadControllerTest { inOrder.verifyNoMoreInteractions(); // Verify that the stored stats is accumulated. - final NetworkStats ifaceStatsAccu = provider.getTetherStats(STATS_PER_IFACE); - final NetworkStats uidStatsAccu = provider.getTetherStats(STATS_PER_UID); + final NetworkStats ifaceStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_IFACE); + final NetworkStats uidStatsAccu = mTetherStatsProvider.getTetherStats(STATS_PER_UID); final NetworkStats expectedIfaceStatsAccu = new NetworkStats(0L, 2) .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 999, 99999)) .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 112345, 154321)); @@ -498,7 +497,7 @@ public class OffloadControllerTest { // Verify that only diff of stats is reported. reset(mTetherStatsProviderCb); - provider.pushTetherStats(); + mTetherStatsProvider.pushTetherStats(); final NetworkStats expectedIfaceStatsDiff = new NetworkStats(0L, 2) .addValues(buildTestEntry(STATS_PER_IFACE, mobileIface, 0, 0)) .addValues(buildTestEntry(STATS_PER_IFACE, ethernetIface, 100000, 100000)); @@ -506,8 +505,8 @@ public class OffloadControllerTest { final NetworkStats expectedUidStatsDiff = new NetworkStats(0L, 2) .addValues(buildTestEntry(STATS_PER_UID, mobileIface, 0, 0)) .addValues(buildTestEntry(STATS_PER_UID, ethernetIface, 100000, 100000)); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), - ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); + verify(mTetherStatsProviderCb, times(1)) + .notifyStatsUpdated(anyInt(), ifaceStatsCaptor.capture(), uidStatsCaptor.capture()); assertTrue(orderInsensitiveEquals(expectedIfaceStatsDiff, ifaceStatsCaptor.getValue())); assertTrue(orderInsensitiveEquals(expectedUidStatsDiff, uidStatsCaptor.getValue())); } @@ -529,19 +528,18 @@ public class OffloadControllerTest { lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - AbstractNetworkStatsProvider provider = mTetherStatsProviderCaptor.getValue(); final InOrder inOrder = inOrder(mHardware); when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(true); when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(true); // Applying an interface quota to the current upstream immediately sends it to the hardware. - provider.setLimit(ethernetIface, ethernetLimit); + mTetherStatsProvider.onSetLimit(ethernetIface, ethernetLimit); waitForIdle(); inOrder.verify(mHardware).setDataLimit(ethernetIface, ethernetLimit); inOrder.verifyNoMoreInteractions(); // Applying an interface quota to another upstream does not take any immediate action. - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -554,7 +552,7 @@ public class OffloadControllerTest { // Setting a limit of ITetheringStatsProvider.QUOTA_UNLIMITED causes the limit to be set // to Long.MAX_VALUE. - provider.setLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); + mTetherStatsProvider.onSetLimit(mobileIface, ITetheringStatsProvider.QUOTA_UNLIMITED); waitForIdle(); inOrder.verify(mHardware).setDataLimit(mobileIface, Long.MAX_VALUE); @@ -562,7 +560,7 @@ public class OffloadControllerTest { when(mHardware.setUpstreamParameters(any(), any(), any(), any())).thenReturn(false); lp.setInterfaceName(ethernetIface); offload.setUpstreamLinkProperties(lp); - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware, never()).setDataLimit(anyString(), anyLong()); @@ -571,7 +569,7 @@ public class OffloadControllerTest { when(mHardware.setDataLimit(anyString(), anyLong())).thenReturn(false); lp.setInterfaceName(mobileIface); offload.setUpstreamLinkProperties(lp); - provider.setLimit(mobileIface, mobileLimit); + mTetherStatsProvider.onSetLimit(mobileIface, mobileLimit); waitForIdle(); inOrder.verify(mHardware).getForwardedStats(ethernetIface); inOrder.verify(mHardware).stopOffloadControl(); @@ -587,7 +585,7 @@ public class OffloadControllerTest { OffloadHardwareInterface.ControlCallback callback = mControlCallbackCaptor.getValue(); callback.onStoppedLimitReached(); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); } @Test @@ -691,7 +689,7 @@ public class OffloadControllerTest { verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); // TODO: verify the exact stats reported. - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); verifyNoMoreInteractions(mTetherStatsProviderCb); verifyNoMoreInteractions(mHardware); } @@ -756,7 +754,7 @@ public class OffloadControllerTest { // Verify forwarded stats behaviour. verify(mHardware, times(1)).getForwardedStats(eq(RMNET0)); verify(mHardware, times(1)).getForwardedStats(eq(WLAN0)); - verify(mTetherStatsProviderCb, times(1)).onStatsUpdated(anyInt(), any(), any()); + verify(mTetherStatsProviderCb, times(1)).notifyStatsUpdated(anyInt(), any(), any()); verifyNoMoreInteractions(mTetherStatsProviderCb); // TODO: verify local prefixes and downstreams are also pushed to the HAL. diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS new file mode 100644 index 000000000000..25ef9facb216 --- /dev/null +++ b/services/core/java/com/android/server/inputmethod/OWNERS @@ -0,0 +1,6 @@ +set noparent + +ogunwale@google.com +yukawa@google.com +tarandeep@google.com +lumark@google.com diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java index 563dcf7e1156..48f1ddb023fd 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java @@ -21,7 +21,7 @@ import static com.android.server.net.NetworkPolicyManagerService.isUidNetworking import android.annotation.NonNull; import android.net.Network; import android.net.NetworkTemplate; -import android.net.netstats.provider.AbstractNetworkStatsProvider; +import android.net.netstats.provider.NetworkStatsProvider; import android.telephony.SubscriptionPlan; import java.util.Set; @@ -130,8 +130,8 @@ public abstract class NetworkPolicyManagerInternal { Set<String> packageNames, int userId); /** - * Notifies that the specified {@link AbstractNetworkStatsProvider} has reached its quota - * which was set through {@link AbstractNetworkStatsProvider#setLimit(String, long)}. + * Notifies that the specified {@link NetworkStatsProvider} has reached its quota + * which was set through {@link NetworkStatsProvider#onSetLimit(String, long)}. * * @param tag the human readable identifier of the custom network stats provider. */ diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 10cf250acb14..a2a4e91aa9fe 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -75,7 +75,7 @@ import static android.net.NetworkTemplate.MATCH_MOBILE; import static android.net.NetworkTemplate.MATCH_WIFI; import static android.net.NetworkTemplate.buildTemplateMobileAll; import static android.net.TrafficStats.MB_IN_BYTES; -import static android.net.netstats.provider.AbstractNetworkStatsProvider.QUOTA_UNLIMITED; +import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.os.Trace.TRACE_TAG_NETWORK; import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED; import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED; diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index c5a48106fb4d..0ceaa69308a1 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -103,7 +103,7 @@ import android.net.NetworkTemplate; import android.net.TrafficStats; import android.net.netstats.provider.INetworkStatsProvider; import android.net.netstats.provider.INetworkStatsProviderCallback; -import android.net.netstats.provider.NetworkStatsProviderCallback; +import android.net.netstats.provider.NetworkStatsProvider; import android.os.BestClock; import android.os.Binder; import android.os.DropBoxManager; @@ -558,7 +558,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } catch (RemoteException e) { // ignored; service lives in system_server } - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setAlert(mGlobalAlertBytes)); + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetAlert(mGlobalAlertBytes)); } @Override @@ -1376,7 +1376,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { Trace.traceBegin(TRACE_TAG_NETWORK, "provider.requestStatsUpdate"); final int registeredCallbackCount = mStatsProviderCbList.getRegisteredCallbackCount(); mStatsProviderSem.drainPermits(); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.requestStatsUpdate(0 /* unused */)); + invokeForAllStatsProviderCallbacks( + (cb) -> cb.mProvider.onRequestStatsUpdate(0 /* unused */)); try { mStatsProviderSem.tryAcquire(registeredCallbackCount, MAX_STATS_PROVIDER_POLL_WAIT_TIME_MS, TimeUnit.MILLISECONDS); @@ -1551,7 +1552,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public void setStatsProviderLimitAsync(@NonNull String iface, long quota) { Slog.v(TAG, "setStatsProviderLimitAsync(" + iface + "," + quota + ")"); - invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.setLimit(iface, quota)); + invokeForAllStatsProviderCallbacks((cb) -> cb.mProvider.onSetLimit(iface, quota)); } } @@ -1820,12 +1821,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { * * @param tag a human readable identifier of the custom network stats provider. * @param provider the {@link INetworkStatsProvider} binder corresponding to the - * {@link android.net.netstats.provider.AbstractNetworkStatsProvider} to be - * registered. + * {@link NetworkStatsProvider} to be registered. * - * @return a binder interface of - * {@link android.net.netstats.provider.NetworkStatsProviderCallback}, which can be - * used to report events to the system. + * @return a {@link INetworkStatsProviderCallback} binder + * interface, which can be used to report events to the system. */ public @NonNull INetworkStatsProviderCallback registerNetworkStatsProvider( @NonNull String tag, @NonNull INetworkStatsProvider provider) { @@ -1931,7 +1930,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void onStatsUpdated(int token, @Nullable NetworkStats ifaceStats, + public void notifyStatsUpdated(int token, @Nullable NetworkStats ifaceStats, @Nullable NetworkStats uidStats) { // TODO: 1. Use token to map ifaces to correct NetworkIdentity. // 2. Store the difference and store it directly to the recorder. @@ -1943,12 +1942,12 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } @Override - public void onAlertReached() throws RemoteException { + public void notifyAlertReached() throws RemoteException { mAlertObserver.limitReached(LIMIT_GLOBAL_ALERT, null /* unused */); } @Override - public void onLimitReached() { + public void notifyLimitReached() { Log.d(TAG, mTag + ": onLimitReached"); LocalServices.getService(NetworkPolicyManagerInternal.class) .onStatsProviderLimitReached(mTag); diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java index 4c275ad92c87..1a55521cfa8b 100644 --- a/services/core/java/com/android/server/pm/StagingManager.java +++ b/services/core/java/com/android/server/pm/StagingManager.java @@ -39,6 +39,8 @@ import android.content.rollback.IRollbackManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; +import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.ParcelableException; import android.os.PowerManager; @@ -59,6 +61,7 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -73,7 +76,7 @@ public class StagingManager { private final PackageInstallerService mPi; private final ApexManager mApexManager; private final PowerManager mPowerManager; - private final Handler mBgHandler; + private final PreRebootVerificationHandler mPreRebootVerificationHandler; @GuardedBy("mStagedSessions") private final SparseArray<PackageInstallerSession> mStagedSessions = new SparseArray<>(); @@ -82,7 +85,8 @@ public class StagingManager { mPi = pi; mApexManager = am; mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mBgHandler = BackgroundThread.getHandler(); + mPreRebootVerificationHandler = new PreRebootVerificationHandler( + BackgroundThread.get().getLooper()); } private void updateStoredSession(@NonNull PackageInstallerSession sessionInfo) { @@ -250,75 +254,6 @@ public class StagingManager { return (session.params.installFlags & PackageManager.INSTALL_APEX) != 0; } - private void preRebootVerification(@NonNull PackageInstallerSession session) { - Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId); - final boolean hasApex = sessionContainsApex(session); - // APEX checks. For single-package sessions, check if they contain an APEX. For - // multi-package sessions, find all the child sessions that contain an APEX. - if (hasApex) { - try { - final List<PackageInfo> apexPackages = submitSessionToApexService(session); - for (PackageInfo apexPackage : apexPackages) { - validateApexSignature(apexPackage, session.params.installFlags); - } - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - return; - } - } - - if (sessionContainsApk(session)) { - try { - Slog.d(TAG, "Running a pre-reboot verification for APKs in session " - + session.sessionId + " by performing a dry-run install"); - installApksInSession(session, /* preReboot */ true); - // TODO(b/118865310): abort the session on apexd. - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - return; - } - } - - if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { - // If rollback is enabled for this session, we call through to the RollbackManager - // with the list of sessions it must enable rollback for. Note that notifyStagedSession - // is a synchronous operation. - final IRollbackManager rm = IRollbackManager.Stub.asInterface( - ServiceManager.getService(Context.ROLLBACK_SERVICE)); - try { - // NOTE: To stay consistent with the non-staged install flow, we don't fail the - // entire install if rollbacks can't be enabled. - if (!rm.notifyStagedSession(session.sessionId)) { - Slog.e(TAG, "Unable to enable rollback for session: " + session.sessionId); - } - } catch (RemoteException re) { - // Cannot happen, the rollback manager is in the same process. - } - } - - // Proactively mark session as ready before calling apexd. Although this call order looks - // counter-intuitive, this is the easiest way to ensure that session won't end up in the - // inconsistent state: - // - If device gets rebooted right before call to apexd, then apexd will never activate - // apex files of this staged session. This will result in StagingManager failing the - // session. - // On the other hand, if the order of the calls was inverted (first call apexd, then mark - // session as ready), then if a device gets rebooted right after the call to apexd, only - // apex part of the train will be applied, leaving device in an inconsistent state. - Slog.d(TAG, "Marking session " + session.sessionId + " as ready"); - session.setStagedSessionReady(); - if (!hasApex) { - // Session doesn't contain apex, nothing to do. - return; - } - try { - mApexManager.markStagedSessionReady(session.sessionId); - } catch (PackageManagerException e) { - session.setStagedSessionFailed(e.error, e.getMessage()); - } - } - - private boolean sessionContains(@NonNull PackageInstallerSession session, Predicate<PackageInstallerSession> filter) { if (!session.isMultiPackage()) { @@ -367,7 +302,7 @@ public class StagingManager { // Greedily re-trigger the pre-reboot verification. Slog.d(TAG, "Found pending staged session " + session.sessionId + " still to be " + "verified, resuming pre-reboot verification"); - mBgHandler.post(() -> preRebootVerification(session)); + mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId); return; } if (!apexSessionInfo.isActivated && !apexSessionInfo.isSuccess) { @@ -476,34 +411,53 @@ public class StagingManager { } private void commitApkSession(@NonNull PackageInstallerSession apkSession, - int originalSessionId, boolean preReboot) throws PackageManagerException { + PackageInstallerSession originalSession, boolean preReboot) + throws PackageManagerException { final int errorCode = preReboot ? SessionInfo.STAGED_SESSION_VERIFICATION_FAILED : SessionInfo.STAGED_SESSION_ACTIVATION_FAILED; - if (!preReboot) { - if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { - // If rollback is available for this session, notify the rollback - // manager of the apk session so it can properly enable rollback. - final IRollbackManager rm = IRollbackManager.Stub.asInterface( - ServiceManager.getService(Context.ROLLBACK_SERVICE)); - try { - rm.notifyStagedApkSession(originalSessionId, apkSession.sessionId); - } catch (RemoteException re) { - // Cannot happen, the rollback manager is in the same process. - } + if (preReboot) { + final LocalIntentReceiverAsync receiver = new LocalIntentReceiverAsync( + (Intent result) -> { + int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, + PackageInstaller.STATUS_FAILURE); + if (status != PackageInstaller.STATUS_SUCCESS) { + final String errorMessage = result.getStringExtra( + PackageInstaller.EXTRA_STATUS_MESSAGE); + Slog.e(TAG, "Failure to install APK staged session " + + originalSession.sessionId + " [" + errorMessage + "]"); + originalSession.setStagedSessionFailed(errorCode, errorMessage); + return; + } + mPreRebootVerificationHandler.notifyPreRebootVerification_Apk_Complete( + originalSession.sessionId); + }); + apkSession.commit(receiver.getIntentSender(), false); + return; + } + + if ((apkSession.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { + // If rollback is available for this session, notify the rollback + // manager of the apk session so it can properly enable rollback. + final IRollbackManager rm = IRollbackManager.Stub.asInterface( + ServiceManager.getService(Context.ROLLBACK_SERVICE)); + try { + rm.notifyStagedApkSession(originalSession.sessionId, apkSession.sessionId); + } catch (RemoteException re) { + Slog.e(TAG, "Failed to notifyStagedApkSession for session: " + + originalSession.sessionId, re); } } - final LocalIntentReceiver receiver = new LocalIntentReceiver(); + final LocalIntentReceiverSync receiver = new LocalIntentReceiverSync(); apkSession.commit(receiver.getIntentSender(), false); final Intent result = receiver.getResult(); final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); if (status != PackageInstaller.STATUS_SUCCESS) { - final String errorMessage = result.getStringExtra( PackageInstaller.EXTRA_STATUS_MESSAGE); - Slog.e(TAG, "Failure to install APK staged session " + originalSessionId + " [" - + errorMessage + "]"); + Slog.e(TAG, "Failure to install APK staged session " + + originalSession.sessionId + " [" + errorMessage + "]"); throw new PackageManagerException(errorCode, errorMessage); } } @@ -515,7 +469,7 @@ public class StagingManager { if (!session.isMultiPackage() && !isApexSession(session)) { // APK single-packaged staged session. Do a regular install. PackageInstallerSession apkSession = createAndWriteApkSession(session, preReboot); - commitApkSession(apkSession, session.sessionId, preReboot); + commitApkSession(apkSession, session, preReboot); } else if (session.isMultiPackage()) { // For multi-package staged sessions containing APKs, we identify which child sessions // contain an APK, and with those then create a new multi-package group of sessions, @@ -565,14 +519,14 @@ public class StagingManager { "Failed to add a child session " + apkChildSession.sessionId); } } - commitApkSession(apkParentSession, session.sessionId, preReboot); + commitApkSession(apkParentSession, session, preReboot); } // APEX single-package staged session, nothing to do. } void commitSession(@NonNull PackageInstallerSession session) { updateStoredSession(session); - mBgHandler.post(() -> preRebootVerification(session)); + mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId); } @Nullable @@ -699,7 +653,7 @@ public class StagingManager { if (!session.isStagedSessionReady()) { // The framework got restarted before the pre-reboot verification could complete, // restart the verification. - mBgHandler.post(() -> preRebootVerification(session)); + mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId); } else { // Session had already being marked ready. Start the checks to verify if there is any // follow-up work. @@ -707,14 +661,34 @@ public class StagingManager { } } - private static class LocalIntentReceiver { + private static class LocalIntentReceiverAsync { + final Consumer<Intent> mConsumer; + + LocalIntentReceiverAsync(Consumer<Intent> consumer) { + mConsumer = consumer; + } + + private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { + @Override + public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, + IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { + mConsumer.accept(intent); + } + }; + + public IntentSender getIntentSender() { + return new IntentSender((IIntentSender) mLocalSender); + } + } + + private static class LocalIntentReceiverSync { private final LinkedBlockingQueue<Intent> mResult = new LinkedBlockingQueue<>(); private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() { @Override public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, - IIntentReceiver finishedReceiver, String requiredPermission, - Bundle options) { + IIntentReceiver finishedReceiver, String requiredPermission, + Bundle options) { try { mResult.offer(intent, 5, TimeUnit.SECONDS); } catch (InterruptedException e) { @@ -735,4 +709,189 @@ public class StagingManager { } } } + + private final class PreRebootVerificationHandler extends Handler { + + PreRebootVerificationHandler(Looper looper) { + super(looper); + } + + /** + * Handler for states of pre reboot verification. The states are arranged linearly (shown + * below) with each state either calling the next state, or calling some other method that + * eventually calls the next state. + * + * <p><ul> + * <li>MSG_PRE_REBOOT_VERIFICATION_START</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_APEX</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_APK</li> + * <li>MSG_PRE_REBOOT_VERIFICATION_END</li> + * </ul></p> + * + * Details about each of state can be found in corresponding handler of node. + */ + private static final int MSG_PRE_REBOOT_VERIFICATION_START = 1; + private static final int MSG_PRE_REBOOT_VERIFICATION_APEX = 2; + private static final int MSG_PRE_REBOOT_VERIFICATION_APK = 3; + private static final int MSG_PRE_REBOOT_VERIFICATION_END = 4; + + @Override + public void handleMessage(Message msg) { + final int sessionId = msg.arg1; + final PackageInstallerSession session; + synchronized (mStagedSessions) { + session = mStagedSessions.get(sessionId); + } + // Maybe session was aborted before pre-reboot verification was complete + if (session == null) { + Slog.d(TAG, "Stopping pre-reboot verification for sessionId: " + sessionId); + return; + } + switch (msg.what) { + case MSG_PRE_REBOOT_VERIFICATION_START: + handlePreRebootVerification_Start(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_APEX: + handlePreRebootVerification_Apex(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_APK: + handlePreRebootVerification_Apk(session); + break; + case MSG_PRE_REBOOT_VERIFICATION_END: + handlePreRebootVerification_End(session); + break; + } + } + + // Method for starting the pre-reboot verification + private void startPreRebootVerification(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_START, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Start_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APEX, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Apex_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_APK, sessionId, 0).sendToTarget(); + } + + private void notifyPreRebootVerification_Apk_Complete(int sessionId) { + obtainMessage(MSG_PRE_REBOOT_VERIFICATION_END, sessionId, 0).sendToTarget(); + } + + /** + * A dummy state for starting the pre reboot verification. + * + * See {@link PreRebootVerificationHandler} to see all nodes of pre reboot verification + */ + private void handlePreRebootVerification_Start(@NonNull PackageInstallerSession session) { + Slog.d(TAG, "Starting preRebootVerification for session " + session.sessionId); + notifyPreRebootVerification_Start_Complete(session.sessionId); + } + + /** + * Pre-reboot verification state for apex files: + * + * <p><ul> + * <li>submits session to apex service</li> + * <li>validates signatures of apex files</li> + * </ul></p> + */ + private void handlePreRebootVerification_Apex(@NonNull PackageInstallerSession session) { + final boolean hasApex = sessionContainsApex(session); + + // APEX checks. For single-package sessions, check if they contain an APEX. For + // multi-package sessions, find all the child sessions that contain an APEX. + if (hasApex) { + try { + final List<PackageInfo> apexPackages = + submitSessionToApexService(session); + for (PackageInfo apexPackage : apexPackages) { + validateApexSignature( + apexPackage, session.params.installFlags); + } + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + return; + } + } + + notifyPreRebootVerification_Apex_Complete(session.sessionId); + } + + /** + * Pre-reboot verification state for apk files: + * <p><ul> + * <li>performs a dry-run install of apk</li> + * </ul></p> + */ + private void handlePreRebootVerification_Apk(@NonNull PackageInstallerSession session) { + if (!sessionContainsApk(session)) { + notifyPreRebootVerification_Apk_Complete(session.sessionId); + return; + } + + try { + Slog.d(TAG, "Running a pre-reboot verification for APKs in session " + + session.sessionId + " by performing a dry-run install"); + + // installApksInSession will notify the handler when APK verification is complete + installApksInSession(session, /* preReboot */ true); + // TODO(b/118865310): abort the session on apexd. + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + } + } + + /** + * Pre-reboot verification state for wrapping up: + * <p><ul> + * <li>enables rollback if required</li> + * <li>marks session as ready</li> + * </ul></p> + */ + private void handlePreRebootVerification_End(@NonNull PackageInstallerSession session) { + if ((session.params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) { + // If rollback is enabled for this session, we call through to the RollbackManager + // with the list of sessions it must enable rollback for. Note that + // notifyStagedSession is a synchronous operation. + final IRollbackManager rm = IRollbackManager.Stub.asInterface( + ServiceManager.getService(Context.ROLLBACK_SERVICE)); + try { + // NOTE: To stay consistent with the non-staged install flow, we don't fail the + // entire install if rollbacks can't be enabled. + if (!rm.notifyStagedSession(session.sessionId)) { + Slog.e(TAG, "Unable to enable rollback for session: " + + session.sessionId); + } + } catch (RemoteException re) { + Slog.e(TAG, "Failed to notifyStagedSession for session: " + + session.sessionId, re); + } + } + + // Proactively mark session as ready before calling apexd. Although this call order + // looks counter-intuitive, this is the easiest way to ensure that session won't end up + // in the inconsistent state: + // - If device gets rebooted right before call to apexd, then apexd will never activate + // apex files of this staged session. This will result in StagingManager failing + // the session. + // On the other hand, if the order of the calls was inverted (first call apexd, then + // mark session as ready), then if a device gets rebooted right after the call to apexd, + // only apex part of the train will be applied, leaving device in an inconsistent state. + Slog.d(TAG, "Marking session " + session.sessionId + " as ready"); + session.setStagedSessionReady(); + final boolean hasApex = sessionContainsApex(session); + if (!hasApex) { + // Session doesn't contain apex, nothing to do. + return; + } + try { + mApexManager.markStagedSessionReady(session.sessionId); + } catch (PackageManagerException e) { + session.setStagedSessionFailed(e.error, e.getMessage()); + } + } + } } diff --git a/services/usb/OWNERS b/services/usb/OWNERS index 7897a0c8555c..8ee72b577f3c 100644 --- a/services/usb/OWNERS +++ b/services/usb/OWNERS @@ -1,4 +1,6 @@ badhri@google.com elaurent@google.com moltmann@google.com -zhangjerry@google.com +albertccwang@google.com +jameswei@google.com +howardyen@google.com
\ No newline at end of file diff --git a/telephony/java/android/telephony/PinResult.java b/telephony/java/android/telephony/PinResult.java index 683e85387c08..68c9d998ba92 100644 --- a/telephony/java/android/telephony/PinResult.java +++ b/telephony/java/android/telephony/PinResult.java @@ -19,7 +19,6 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.os.Parcel; import android.os.Parcelable; @@ -32,7 +31,6 @@ import java.util.Objects; * * @hide */ -@SystemApi public final class PinResult implements Parcelable { /** @hide */ @IntDef({ diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index ab9269701a8e..5cf33dec25ea 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1992,7 +1992,6 @@ public class ServiceState implements Parcelable { * @return the copied ServiceState with location info sanitized. * @hide */ - @SystemApi @NonNull public ServiceState createLocationInfoSanitizedCopy(boolean removeCoarseLocation) { ServiceState state = new ServiceState(this); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 1c405918da60..d87df08ffc80 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -3186,13 +3186,13 @@ public class SubscriptionManager { * * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required * - * @param enabled whether uicc applications are enabled or disabled. * @param subscriptionId which subscription to operate on. + * @param enabled whether uicc applications are enabled or disabled. * @hide */ @SystemApi @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE) - public void setUiccApplicationsEnabled(boolean enabled, int subscriptionId) { + public void setUiccApplicationsEnabled(int subscriptionId, boolean enabled) { if (VDBG) { logd("setUiccApplicationsEnabled subId= " + subscriptionId + " enable " + enabled); } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index fbaf8d34ad8d..adecbfc7c3de 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -1031,7 +1031,7 @@ public class TelephonyManager { * or that all steps during multi-SIM change are done. To know those information you still need * to listen to SIM_STATE changes or active subscription changes. * - * See extra of {@link #EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED} for updated value. + * See extra of {@link #EXTRA_ACTIVE_SIM_SUPPORTED_COUNT} for updated value. */ public static final String ACTION_MULTI_SIM_CONFIG_CHANGED = "android.telephony.action.MULTI_SIM_CONFIG_CHANGED"; @@ -1041,6 +1041,8 @@ public class TelephonyManager { * The number of active SIM supported by current multi-SIM config. It's not related to how many * SIM/subscriptions are currently active. * + * Same value will be returned by {@link #getActiveModemCount()}. + * * For single SIM mode, it's 1. * For DSDS or DSDA mode, it's 2. * For triple-SIM mode, it's 3. @@ -1049,8 +1051,8 @@ public class TelephonyManager { * * type: integer */ - public static final String EXTRA_NUM_OF_ACTIVE_SIM_SUPPORTED = - "android.telephony.extra.NUM_OF_ACTIVE_SIM_SUPPORTED"; + public static final String EXTRA_ACTIVE_SIM_SUPPORTED_COUNT = + "android.telephony.extra.ACTIVE_SIM_SUPPORTED_COUNT"; /** * @hide @@ -8696,7 +8698,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public PinResult supplyPinReportPinResult(@NonNull String pin) { @@ -8721,7 +8722,6 @@ public class TelephonyManager { * * @hide */ - @SystemApi @Nullable @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public PinResult supplyPukReportPinResult(@NonNull String puk, @NonNull String pin) { diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 0e1a8df22d46..158ada94e3c6 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -18,7 +18,6 @@ package android.telephony.data; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.content.ContentValues; import android.database.Cursor; import android.hardware.radio.V1_5.ApnTypes; @@ -147,7 +146,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_ALL_STRING = "*"; /** @@ -155,7 +153,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_DEFAULT_STRING = "default"; @@ -164,7 +161,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_MMS_STRING = "mms"; @@ -173,7 +169,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_SUPL_STRING = "supl"; /** @@ -181,7 +176,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_DUN_STRING = "dun"; /** @@ -189,7 +183,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_HIPRI_STRING = "hipri"; /** @@ -197,7 +190,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_FOTA_STRING = "fota"; /** @@ -205,7 +197,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_IMS_STRING = "ims"; /** @@ -213,7 +204,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_CBS_STRING = "cbs"; /** @@ -221,7 +211,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_IA_STRING = "ia"; /** @@ -230,7 +219,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_EMERGENCY_STRING = "emergency"; /** @@ -238,7 +226,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_MCX_STRING = "mcx"; /** @@ -246,7 +233,6 @@ public class ApnSetting implements Parcelable { * * @hide */ - @SystemApi public static final String TYPE_XCAP_STRING = "xcap"; @@ -1421,7 +1407,6 @@ public class ApnSetting implements Parcelable { * @return comma delimited list of APN types. * @hide */ - @SystemApi @NonNull public static String getApnTypesStringFromBitmask(int apnTypeBitmask) { List<String> types = new ArrayList<>(); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 6985415a6a37..f9d66f9a26cf 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -3723,7 +3723,7 @@ public class ConnectivityServiceTest { mCm.requestNetwork(nr, networkCallback, timeoutMs); // pass timeout and validate that UNAVAILABLE is called - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null); + networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); // create a network satisfying request - validate that request not triggered mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); @@ -3814,7 +3814,7 @@ public class ConnectivityServiceTest { // Simulate the factory releasing the request as unfulfillable and expect onUnavailable! testFactory.triggerUnfulfillable(requests.get(newRequestId)); - networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, null); + networkCallback.expectCallback(CallbackEntry.UNAVAILABLE, (Network) null); testFactory.waitForRequests(); // unregister network callback - a no-op (since already freed by the diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java index 36deca3e37b7..a0f996fb7b11 100644 --- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java +++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java @@ -1026,7 +1026,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states), new VpnInfo[0]); // Verifies that one requestStatsUpdate will be called during iface update. - provider.expectStatsUpdate(0 /* unused */); + provider.expectOnRequestStatsUpdate(0 /* unused */); // Create some initial traffic and report to the service. incrementCurrentTime(HOUR_IN_MILLIS); @@ -1037,7 +1037,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { .addValues(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, 0xF00D, METERED_YES, ROAMING_NO, DEFAULT_NETWORK_YES, 64L, 1L, 64L, 1L, 1L)); - cb.onStatsUpdated(0 /* unused */, expectedStats, expectedStats); + cb.notifyStatsUpdated(0 /* unused */, expectedStats, expectedStats); // Make another empty mutable stats object. This is necessary since the new NetworkStats // object will be used to compare with the old one in NetworkStatsRecoder, two of them @@ -1047,8 +1047,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { forcePollAndWaitForIdle(); // Verifies that one requestStatsUpdate and setAlert will be called during polling. - provider.expectStatsUpdate(0 /* unused */); - provider.expectSetAlert(MB_IN_BYTES); + provider.expectOnRequestStatsUpdate(0 /* unused */); + provider.expectOnSetAlert(MB_IN_BYTES); // Verifies that service recorded history, does not verify uid tag part. assertUidTotal(sTemplateWifi, UID_RED, 128L, 2L, 128L, 2L, 1); @@ -1082,13 +1082,13 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest { assertNotNull(cb); // Simulates alert quota of the provider has been reached. - cb.onAlertReached(); + cb.notifyAlertReached(); HandlerUtilsKt.waitForIdle(mHandlerThread, WAIT_TIMEOUT); // Verifies that polling is triggered by alert reached. - provider.expectStatsUpdate(0 /* unused */); + provider.expectOnRequestStatsUpdate(0 /* unused */); // Verifies that global alert will be re-armed. - provider.expectSetAlert(MB_IN_BYTES); + provider.expectOnSetAlert(MB_IN_BYTES); } private static File getBaseDir(File statsDir) { |