diff options
34 files changed, 738 insertions, 220 deletions
diff --git a/Android.bp b/Android.bp index 3d087c08677f..3686053f14fb 100644 --- a/Android.bp +++ b/Android.bp @@ -328,6 +328,7 @@ java_defaults { "TeleService-platform-compat-config", "documents-ui-compat-config", "calendar-provider-compat-config", + "contacts-provider-platform-compat-config", ], libs: [ "app-compat-annotations", diff --git a/GAME_MANAGER_OWNERS b/GAME_MANAGER_OWNERS new file mode 100644 index 000000000000..502a9e362202 --- /dev/null +++ b/GAME_MANAGER_OWNERS @@ -0,0 +1,2 @@ +lpy@google.com +timvp@google.com diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index 4da51c13045b..2564228f23aa 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -29,6 +29,8 @@ per-file Service* = file:/services/core/java/com/android/server/am/OWNERS per-file SystemServiceRegistry.java = file:/services/core/java/com/android/server/am/OWNERS per-file *UserSwitchObserver* = file:/services/core/java/com/android/server/am/OWNERS per-file UiAutomation.java = file:/services/accessibility/OWNERS +per-file GameManager* = file:/GAME_MANAGER_OWNERS +per-file IGameManager* = file:/GAME_MANAGER_OWNERS # ActivityThread per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 6885c10b4889..1907d18f56c5 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5462,6 +5462,12 @@ public abstract class Context { public static final String STATS_COMPANION_SERVICE = "statscompanion"; /** + * Service to assist statsd in logging atoms from bootstrap atoms. + * @hide + */ + public static final String STATS_BOOTSTRAP_ATOM_SERVICE = "statsbootstrap"; + + /** * Use with {@link #getSystemService(String)} to retrieve an {@link android.app.StatsManager}. * @hide */ diff --git a/core/java/android/os/IStatsBootstrapAtomService.aidl b/core/java/android/os/IStatsBootstrapAtomService.aidl new file mode 100644 index 000000000000..9d1df67fa19d --- /dev/null +++ b/core/java/android/os/IStatsBootstrapAtomService.aidl @@ -0,0 +1,36 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os; + +import android.os.StatsBootstrapAtom; + +/** + * IBootstrapAtomService interface exposes an interface for processes that launch in the + * bootstrap namespace to push atoms to statsd. + * + * @hide + */ +oneway interface IStatsBootstrapAtomService { + /** + * Push an atom to StatsBootstrapAtomService, which will forward it to statsd. + * + * @param atom - parcelled representation of the atom to log. + * + * Errors are reported as service specific errors. + */ + void reportBootstrapAtom(in StatsBootstrapAtom atom); +}
\ No newline at end of file diff --git a/core/java/android/os/StatsBootstrapAtom.aidl b/core/java/android/os/StatsBootstrapAtom.aidl new file mode 100644 index 000000000000..47500af8eebf --- /dev/null +++ b/core/java/android/os/StatsBootstrapAtom.aidl @@ -0,0 +1,34 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.os; + +import android.os.StatsBootstrapAtomValue; + +/* + * Generic encapsulation of an atom for bootstrap processes to log. + * + * @hide + */ +parcelable StatsBootstrapAtom { + /* + * Atom ID. Must be between 1 - 10,000. + */ + int atomId; + /* + * Vector of fields in the order of the atom definition. + */ + StatsBootstrapAtomValue[] values; + }
\ No newline at end of file diff --git a/core/java/android/os/StatsBootstrapAtomValue.aidl b/core/java/android/os/StatsBootstrapAtomValue.aidl new file mode 100644 index 000000000000..a90dfa404ee9 --- /dev/null +++ b/core/java/android/os/StatsBootstrapAtomValue.aidl @@ -0,0 +1,29 @@ +/* + * Copyright 2021, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.os; +/* + * Supported field types. + * + * @hide + */ +union StatsBootstrapAtomValue { + boolean boolValue; + int intValue; + long longValue; + float floatValue; + String stringValue; + byte[] bytesValue; +}
\ No newline at end of file diff --git a/core/java/com/android/internal/net/OWNERS b/core/java/com/android/internal/net/OWNERS index 050cb5c2b44e..71f997bb57c5 100644 --- a/core/java/com/android/internal/net/OWNERS +++ b/core/java/com/android/internal/net/OWNERS @@ -1,9 +1,4 @@ set noparent +file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking -codewiz@google.com -ek@google.com -jchalard@google.com jsharkey@android.com -lorenzo@google.com -reminv@google.com -satk@google.com diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java index 8b0411de5477..8f5e97d40530 100644 --- a/core/java/com/android/internal/os/ClassLoaderFactory.java +++ b/core/java/com/android/internal/os/ClassLoaderFactory.java @@ -24,6 +24,7 @@ import dalvik.system.DelegateLastClassLoader; import dalvik.system.DexClassLoader; import dalvik.system.PathClassLoader; +import java.util.ArrayList; import java.util.List; /** @@ -100,14 +101,25 @@ public class ClassLoaderFactory { } /** - * Same as {@code createClassLoader} below, but passes a null list of shared - * libraries. + * Same as {@code createClassLoader} below, but passes a null list of shared libraries. This + * method is used only to load platform classes (i.e. those in framework.jar or services.jar), + * and MUST NOT be used for loading untrusted classes, especially the app classes. For the + * latter case, use the below method which accepts list of shared libraries so that the classes + * don't have unlimited access to all shared libraries. */ public static ClassLoader createClassLoader(String dexPath, String librarySearchPath, String libraryPermittedPath, ClassLoader parent, int targetSdkVersion, boolean isNamespaceShared, String classLoaderName) { + // b/205164833: allow framework classes to have access to all public vendor libraries. + // This is because those classes are part of the platform and don't have an app manifest + // where required libraries can be specified using the <uses-native-library> tag. + // Note that this still does not give access to "private" vendor libraries. + List<String> nativeSharedLibraries = new ArrayList<>(); + nativeSharedLibraries.add("ALL"); + return createClassLoader(dexPath, librarySearchPath, libraryPermittedPath, - parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null, null); + parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, + nativeSharedLibraries, null); } /** diff --git a/core/java/com/android/server/net/OWNERS b/core/java/com/android/server/net/OWNERS index d3836d4c6c57..62c5737a2e8e 100644 --- a/core/java/com/android/server/net/OWNERS +++ b/core/java/com/android/server/net/OWNERS @@ -1,8 +1,2 @@ set noparent - -codewiz@google.com -jchalard@google.com -junyulai@google.com -lorenzo@google.com -reminv@google.com -satk@google.com +file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index cf072b488efc..e81adecc3bad 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -225,6 +225,8 @@ applications that come with the platform <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.UPDATE_APP_OPS_STATS"/> <permission name="android.permission.USE_RESERVED_DISK"/> + <permission name="android.permission.READ_COMPAT_CHANGE_CONFIG" /> + <permission name="android.permission.LOG_COMPAT_CHANGE" /> </privapp-permissions> <privapp-permissions package="com.android.providers.downloads"> diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index 374cc7592faf..3c152fb68c0a 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -426,6 +426,12 @@ public final class MediaCodecInfo { /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ public static final int COLOR_Format24BitABGR6666 = 43; + /** @hide + * P010 is a 4:2:0 YCbCr semiplanar format comprised of a WxH Y plane + * followed by a Wx(H/2) CbCr plane. Each sample is represented by a 16-bit + * little-endian value, with the lower 6 bits set to zero. */ + public static final int COLOR_FormatYUVP010 = 54; + /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100; // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference. diff --git a/packages/PrintSpooler/jni/com_android_printspooler_util_BitmapSerializeUtils.cpp b/packages/PrintSpooler/jni/com_android_printspooler_util_BitmapSerializeUtils.cpp index 7ff9cedab5f7..b2c82c6fb846 100644 --- a/packages/PrintSpooler/jni/com_android_printspooler_util_BitmapSerializeUtils.cpp +++ b/packages/PrintSpooler/jni/com_android_printspooler_util_BitmapSerializeUtils.cpp @@ -30,11 +30,8 @@ static bool writeAllBytes(const int fd, void* buffer, const size_t byteCount) { char* writeBuffer = static_cast<char*>(buffer); size_t remainingBytes = byteCount; while (remainingBytes > 0) { - ssize_t writtenByteCount = write(fd, writeBuffer, remainingBytes); + ssize_t writtenByteCount = TEMP_FAILURE_RETRY(write(fd, writeBuffer, remainingBytes)); if (writtenByteCount == -1) { - if (errno == EINTR) { - continue; - } __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Error writing to buffer: %d", errno); return false; @@ -49,19 +46,17 @@ static bool readAllBytes(const int fd, void* buffer, const size_t byteCount) { char* readBuffer = static_cast<char*>(buffer); size_t remainingBytes = byteCount; while (remainingBytes > 0) { - ssize_t readByteCount = read(fd, readBuffer, remainingBytes); - - remainingBytes -= readByteCount; - readBuffer += readByteCount; - + ssize_t readByteCount = TEMP_FAILURE_RETRY(read(fd, readBuffer, remainingBytes)); if (readByteCount == -1) { - if (errno == EINTR) { - continue; - } __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Error reading from buffer: %d", errno); return false; - } else if (readByteCount == 0 && remainingBytes > 0) { + } + + remainingBytes -= readByteCount; + readBuffer += readByteCount; + + if (readByteCount == 0 && remainingBytes > 0) { __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "File closed before all bytes were read. %zu/%zu remaining", remainingBytes, byteCount); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 76b0b385dbda..97cc948e134b 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -575,6 +575,9 @@ <uses-permission android:name="android.permission.MANAGE_VIRTUAL_MACHINE" /> <uses-permission android:name="android.permission.DEBUG_VIRTUAL_MACHINE" /> + <!-- Permission required for CTS test - SettingsMultiPaneDeepLinkTest --> + <uses-permission android:name="android.permission.LAUNCH_MULTI_PANE_SETTINGS_DEEP_LINK" /> + <application android:label="@string/app_label" android:theme="@android:style/Theme.DeviceDefault.DayNight" android:defaultToDeviceProtectedStorage="true" diff --git a/services/core/java/com/android/server/app/OWNERS b/services/core/java/com/android/server/app/OWNERS new file mode 100644 index 000000000000..aaebbfa8e253 --- /dev/null +++ b/services/core/java/com/android/server/app/OWNERS @@ -0,0 +1 @@ +per-file GameManager* = file:/GAME_MANAGER_OWNERS diff --git a/services/core/java/com/android/server/connectivity/OWNERS b/services/core/java/com/android/server/connectivity/OWNERS index 7311eee32a4c..62c5737a2e8e 100644 --- a/services/core/java/com/android/server/connectivity/OWNERS +++ b/services/core/java/com/android/server/connectivity/OWNERS @@ -1,8 +1,2 @@ set noparent - -codewiz@google.com -ek@google.com -jchalard@google.com -lorenzo@google.com -reminv@google.com -satk@google.com +file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking diff --git a/services/core/java/com/android/server/health/HealthRegCallbackAidl.java b/services/core/java/com/android/server/health/HealthRegCallbackAidl.java new file mode 100644 index 000000000000..629011a86bb4 --- /dev/null +++ b/services/core/java/com/android/server/health/HealthRegCallbackAidl.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.health; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.hardware.health.HealthInfo; +import android.hardware.health.IHealth; +import android.hardware.health.IHealthInfoCallback; +import android.os.RemoteException; +import android.os.Trace; +import android.util.Slog; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * On service registration, {@link #onRegistration} is called, which registers {@code this}, an + * {@link IHealthInfoCallback}, to the health service. + * + * <p>When the health service has updates to health info via {@link IHealthInfoCallback}, {@link + * HealthInfoCallback#update} is called. + * + * <p>AIDL variant of {@link HealthHalCallbackHidl}. + * + * @hide + */ +// It is made public so Mockito can access this class. It should have been package private if not +// for testing. +@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) +public class HealthRegCallbackAidl { + private static final String TAG = "HealthRegCallbackAidl"; + private final HealthInfoCallback mServiceInfoCallback; + private final IHealthInfoCallback mHalInfoCallback = new HalInfoCallback(); + + HealthRegCallbackAidl(@Nullable HealthInfoCallback healthInfoCallback) { + mServiceInfoCallback = healthInfoCallback; + } + + /** + * Called when the service manager sees {@code newService} replacing {@code oldService}. + * This unregisters the health info callback from the old service (ignoring errors), then + * registers the health info callback to the new service. + * + * @param oldService the old IHealth service + * @param newService the new IHealth service + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + public void onRegistration(@Nullable IHealth oldService, @NonNull IHealth newService) { + if (mServiceInfoCallback == null) return; + + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthUnregisterCallbackAidl"); + try { + unregisterCallback(oldService, mHalInfoCallback); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "HealthRegisterCallbackAidl"); + try { + registerCallback(newService, mHalInfoCallback); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + } + + private static void unregisterCallback(@Nullable IHealth oldService, IHealthInfoCallback cb) { + if (oldService == null) return; + try { + oldService.unregisterCallback(cb); + } catch (RemoteException e) { + // Ignore errors. The service might have died. + Slog.w( + TAG, + "health: cannot unregister previous callback (transaction error): " + + e.getMessage()); + } + } + + private static void registerCallback(@NonNull IHealth newService, IHealthInfoCallback cb) { + try { + newService.registerCallback(cb); + } catch (RemoteException e) { + Slog.e( + TAG, + "health: cannot register callback, framework may cease to" + + " receive updates on health / battery info!", + e); + return; + } + // registerCallback does NOT guarantee that update is called immediately, so request a + // manual update here. + try { + newService.update(); + } catch (RemoteException e) { + Slog.e(TAG, "health: cannot update after registering health info callback", e); + } + } + + private class HalInfoCallback extends IHealthInfoCallback.Stub { + @Override + public void healthInfoChanged(HealthInfo healthInfo) throws RemoteException { + mServiceInfoCallback.update(healthInfo); + } + } +} diff --git a/services/core/java/com/android/server/health/HealthServiceWrapper.java b/services/core/java/com/android/server/health/HealthServiceWrapper.java index 9b97554ee259..25d1a885bc18 100644 --- a/services/core/java/com/android/server/health/HealthServiceWrapper.java +++ b/services/core/java/com/android/server/health/HealthServiceWrapper.java @@ -81,6 +81,8 @@ public abstract class HealthServiceWrapper { public static HealthServiceWrapper create(@Nullable HealthInfoCallback healthInfoCallback) throws RemoteException, NoSuchElementException { return create( + healthInfoCallback == null ? null : new HealthRegCallbackAidl(healthInfoCallback), + new HealthServiceWrapperAidl.ServiceManagerStub() {}, healthInfoCallback == null ? null : new HealthHalCallbackHidl(healthInfoCallback), new HealthServiceWrapperHidl.IServiceManagerSupplier() {}, new HealthServiceWrapperHidl.IHealthSupplier() {}); @@ -89,6 +91,9 @@ public abstract class HealthServiceWrapper { /** * Create a new HealthServiceWrapper instance for testing. * + * @param aidlRegCallback callback for AIDL service registration, or {@code null} if the client + * does not care about AIDL service registration notifications + * @param aidlServiceManager Stub for AIDL ServiceManager * @param hidlRegCallback callback for HIDL service registration, or {@code null} if the client * does not care about HIDL service registration notifications * @param hidlServiceManagerSupplier supplier of HIDL service manager @@ -97,10 +102,17 @@ public abstract class HealthServiceWrapper { */ @VisibleForTesting static @NonNull HealthServiceWrapper create( + @Nullable HealthRegCallbackAidl aidlRegCallback, + @NonNull HealthServiceWrapperAidl.ServiceManagerStub aidlServiceManager, @Nullable HealthServiceWrapperHidl.Callback hidlRegCallback, @NonNull HealthServiceWrapperHidl.IServiceManagerSupplier hidlServiceManagerSupplier, @NonNull HealthServiceWrapperHidl.IHealthSupplier hidlHealthSupplier) throws RemoteException, NoSuchElementException { + try { + return new HealthServiceWrapperAidl(aidlRegCallback, aidlServiceManager); + } catch (NoSuchElementException e) { + // Ignore, try HIDL + } return new HealthServiceWrapperHidl( hidlRegCallback, hidlServiceManagerSupplier, hidlHealthSupplier); } diff --git a/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java new file mode 100644 index 000000000000..4f2ed68974fa --- /dev/null +++ b/services/core/java/com/android/server/health/HealthServiceWrapperAidl.java @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.health; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.hardware.health.HealthInfo; +import android.hardware.health.IHealth; +import android.os.BatteryManager; +import android.os.BatteryProperty; +import android.os.Binder; +import android.os.HandlerThread; +import android.os.IBinder; +import android.os.IServiceCallback; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.ServiceSpecificException; +import android.os.Trace; +import android.util.Slog; + +import com.android.internal.annotations.VisibleForTesting; + +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Implement {@link HealthServiceWrapper} backed by the AIDL HAL. + * + * @hide + */ +class HealthServiceWrapperAidl extends HealthServiceWrapper { + private static final String TAG = "HealthServiceWrapperAidl"; + @VisibleForTesting static final String SERVICE_NAME = IHealth.DESCRIPTOR + "/default"; + private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceBinder"); + private final AtomicReference<IHealth> mLastService = new AtomicReference<>(); + private final IServiceCallback mServiceCallback = new ServiceCallback(); + private final HealthRegCallbackAidl mRegCallback; + + /** Stub interface into {@link ServiceManager} for testing. */ + interface ServiceManagerStub { + default @Nullable IHealth waitForDeclaredService(@NonNull String name) { + return IHealth.Stub.asInterface(ServiceManager.waitForDeclaredService(name)); + } + + default void registerForNotifications( + @NonNull String name, @NonNull IServiceCallback callback) throws RemoteException { + ServiceManager.registerForNotifications(name, callback); + } + } + + HealthServiceWrapperAidl( + @Nullable HealthRegCallbackAidl regCallback, @NonNull ServiceManagerStub serviceManager) + throws RemoteException, NoSuchElementException { + + traceBegin("HealthInitGetServiceAidl"); + IHealth newService; + try { + newService = serviceManager.waitForDeclaredService(SERVICE_NAME); + } finally { + traceEnd(); + } + if (newService == null) { + throw new NoSuchElementException( + "IHealth service instance isn't available. Perhaps no permission?"); + } + mLastService.set(newService); + mRegCallback = regCallback; + if (mRegCallback != null) { + mRegCallback.onRegistration(null /* oldService */, newService); + } + + traceBegin("HealthInitRegisterNotificationAidl"); + mHandlerThread.start(); + try { + serviceManager.registerForNotifications(SERVICE_NAME, mServiceCallback); + } finally { + traceEnd(); + } + Slog.i(TAG, "health: HealthServiceWrapper listening to AIDL HAL"); + } + + @Override + @VisibleForTesting + public HandlerThread getHandlerThread() { + return mHandlerThread; + } + + @Override + public int getProperty(int id, BatteryProperty prop) throws RemoteException { + traceBegin("HealthGetPropertyAidl"); + try { + return getPropertyInternal(id, prop); + } finally { + traceEnd(); + } + } + + private int getPropertyInternal(int id, BatteryProperty prop) throws RemoteException { + IHealth service = mLastService.get(); + if (service == null) throw new RemoteException("no health service"); + try { + switch (id) { + case BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER: + prop.setLong(service.getChargeCounterUah()); + break; + case BatteryManager.BATTERY_PROPERTY_CURRENT_NOW: + prop.setLong(service.getCurrentNowMicroamps()); + break; + case BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE: + prop.setLong(service.getCurrentAverageMicroamps()); + break; + case BatteryManager.BATTERY_PROPERTY_CAPACITY: + prop.setLong(service.getCapacity()); + break; + case BatteryManager.BATTERY_PROPERTY_STATUS: + prop.setLong(service.getChargeStatus()); + break; + case BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER: + prop.setLong(service.getEnergyCounterNwh()); + break; + } + } catch (UnsupportedOperationException e) { + // Leave prop untouched. + return -1; + } catch (ServiceSpecificException e) { + // Leave prop untouched. + return -2; + } + // throws RemoteException as-is. BatteryManager wraps it into a RuntimeException + // and throw it to apps. + + // If no error, return 0. + return 0; + } + + @Override + public void scheduleUpdate() throws RemoteException { + getHandlerThread() + .getThreadHandler() + .post( + () -> { + traceBegin("HealthScheduleUpdate"); + try { + IHealth service = mLastService.get(); + if (service == null) { + Slog.e(TAG, "no health service"); + return; + } + service.update(); + } catch (RemoteException | ServiceSpecificException ex) { + Slog.e(TAG, "Cannot call update on health AIDL HAL", ex); + } finally { + traceEnd(); + } + }); + } + + @Override + public HealthInfo getHealthInfo() throws RemoteException { + IHealth service = mLastService.get(); + if (service == null) return null; + try { + return service.getHealthInfo(); + } catch (UnsupportedOperationException | ServiceSpecificException ex) { + return null; + } + } + + private static void traceBegin(String name) { + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, name); + } + + private static void traceEnd() { + Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); + } + + private class ServiceCallback extends IServiceCallback.Stub { + @Override + public void onRegistration(String name, @NonNull final IBinder newBinder) + throws RemoteException { + if (!SERVICE_NAME.equals(name)) return; + // This runnable only runs on mHandlerThread and ordering is ensured, hence + // no locking is needed inside the runnable. + getHandlerThread() + .getThreadHandler() + .post( + () -> { + IHealth newService = + IHealth.Stub.asInterface(Binder.allowBlocking(newBinder)); + IHealth oldService = mLastService.getAndSet(newService); + IBinder oldBinder = + oldService != null ? oldService.asBinder() : null; + if (Objects.equals(newBinder, oldBinder)) return; + + Slog.i(TAG, "New health AIDL HAL service registered"); + mRegCallback.onRegistration(oldService, newService); + }); + } + } +} diff --git a/services/core/java/com/android/server/net/NetworkStatsFactory.java b/services/core/java/com/android/server/net/NetworkStatsFactory.java index 431b00914f02..e6433db11d7b 100644 --- a/services/core/java/com/android/server/net/NetworkStatsFactory.java +++ b/services/core/java/com/android/server/net/NetworkStatsFactory.java @@ -159,7 +159,7 @@ public class NetworkStatsFactory { } public NetworkStatsFactory() { - this(new File("/proc/"), new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists()); + this(new File("/proc/"), true); } @VisibleForTesting diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 097b0711eff7..f4b72a15d0e3 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -215,8 +215,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private final PowerManager.WakeLock mWakeLock; - private final boolean mUseBpfTrafficStats; - private final ContentObserver mContentObserver; private final ContentResolver mContentResolver; @@ -438,7 +436,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mStatsObservers = Objects.requireNonNull(statsObservers, "missing NetworkStatsObservers"); mSystemDir = Objects.requireNonNull(systemDir, "missing systemDir"); mBaseDir = Objects.requireNonNull(baseDir, "missing baseDir"); - mUseBpfTrafficStats = new File("/sys/fs/bpf/map_netd_app_uid_stats_map").exists(); mDeps = Objects.requireNonNull(deps, "missing Dependencies"); final HandlerThread handlerThread = mDeps.makeHandlerThread(); @@ -1084,13 +1081,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { if (callingUid != android.os.Process.SYSTEM_UID && callingUid != uid) { return UNSUPPORTED; } - return nativeGetUidStat(uid, type, checkBpfStatsEnable()); + return nativeGetUidStat(uid, type); } @Override public long getIfaceStats(@NonNull String iface, int type) { Objects.requireNonNull(iface); - long nativeIfaceStats = nativeGetIfaceStat(iface, type, checkBpfStatsEnable()); + long nativeIfaceStats = nativeGetIfaceStat(iface, type); if (nativeIfaceStats == -1) { return nativeIfaceStats; } else { @@ -1104,7 +1101,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public long getTotalStats(int type) { - long nativeTotalStats = nativeGetTotalStat(type, checkBpfStatsEnable()); + long nativeTotalStats = nativeGetTotalStat(type); if (nativeTotalStats == -1) { return nativeTotalStats; } else { @@ -1137,10 +1134,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - private boolean checkBpfStatsEnable() { - return mUseBpfTrafficStats; - } - /** * Update {@link NetworkStatsRecorder} and {@link #mGlobalAlertBytes} to * reflect current {@link #mPersistThreshold} value. Always defers to @@ -2249,7 +2242,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } } - private static native long nativeGetTotalStat(int type, boolean useBpfStats); - private static native long nativeGetIfaceStat(String iface, int type, boolean useBpfStats); - private static native long nativeGetUidStat(int uid, int type, boolean useBpfStats); + private static native long nativeGetTotalStat(int type); + private static native long nativeGetIfaceStat(String iface, int type); + private static native long nativeGetUidStat(int uid, int type); } diff --git a/services/core/java/com/android/server/net/OWNERS b/services/core/java/com/android/server/net/OWNERS index a15fc3eef539..9c96d46f15b8 100644 --- a/services/core/java/com/android/server/net/OWNERS +++ b/services/core/java/com/android/server/net/OWNERS @@ -1,6 +1,5 @@ set noparent - -include platform/packages/modules/Connectivity:/OWNERS +file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking jsharkey@android.com sudheersai@google.com diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 20bcc5e396eb..8e18508adc90 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3538,9 +3538,9 @@ public class PackageManagerService extends IPackageManager.Stub list.addAll(mApexManager.getFactoryPackages()); } else { list.addAll(mApexManager.getActivePackages()); - } - if (listUninstalled) { - list.addAll(mApexManager.getInactivePackages()); + if (listUninstalled) { + list.addAll(mApexManager.getInactivePackages()); + } } } return new ParceledListSlice<>(list); diff --git a/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java b/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java new file mode 100644 index 000000000000..0d420a535415 --- /dev/null +++ b/services/core/java/com/android/server/stats/bootstrap/StatsBootstrapAtomService.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.server.stats.bootstrap; + +import android.content.Context; +import android.os.IStatsBootstrapAtomService; +import android.os.StatsBootstrapAtom; +import android.os.StatsBootstrapAtomValue; +import android.util.Slog; +import android.util.StatsEvent; +import android.util.StatsLog; + +import com.android.server.SystemService; + +/** + * Proxy service for logging pushed atoms to statsd + * + * @hide + */ +public class StatsBootstrapAtomService extends IStatsBootstrapAtomService.Stub { + + private static final String TAG = "StatsBootstrapAtomService"; + private static final boolean DEBUG = false; + + @Override + public void reportBootstrapAtom(StatsBootstrapAtom atom) { + if (atom.atomId < 1 || atom.atomId >= 10000) { + Slog.e(TAG, "Atom ID " + atom.atomId + " is not a valid atom ID"); + return; + } + StatsEvent.Builder builder = StatsEvent.newBuilder().setAtomId(atom.atomId); + for (StatsBootstrapAtomValue value : atom.values) { + switch (value.getTag()) { + case StatsBootstrapAtomValue.boolValue: + builder.writeBoolean(value.getBoolValue()); + break; + case StatsBootstrapAtomValue.intValue: + builder.writeInt(value.getIntValue()); + break; + case StatsBootstrapAtomValue.longValue: + builder.writeLong(value.getLongValue()); + break; + case StatsBootstrapAtomValue.floatValue: + builder.writeFloat(value.getFloatValue()); + break; + case StatsBootstrapAtomValue.stringValue: + builder.writeString(value.getStringValue()); + break; + case StatsBootstrapAtomValue.bytesValue: + builder.writeByteArray(value.getBytesValue()); + break; + default: + Slog.e(TAG, "Unexpected value type " + value.getTag() + + " when logging atom " + atom.atomId); + return; + + } + } + StatsLog.write(builder.usePooledBuffer().build()); + } + + /** + * Lifecycle and related code + */ + public static final class Lifecycle extends SystemService { + private StatsBootstrapAtomService mStatsBootstrapAtomService; + + public Lifecycle(Context context) { + super(context); + } + + @Override + public void onStart() { + mStatsBootstrapAtomService = new StatsBootstrapAtomService(); + try { + publishBinderService(Context.STATS_BOOTSTRAP_ATOM_SERVICE, + mStatsBootstrapAtomService); + if (DEBUG) Slog.d(TAG, "Published " + Context.STATS_BOOTSTRAP_ATOM_SERVICE); + } catch (Exception e) { + Slog.e(TAG, "Failed to publishBinderService", e); + } + } + } + +} diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp index 10b248a70e7e..5178132e4a2e 100644 --- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp +++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp @@ -38,9 +38,6 @@ using android::bpf::bpfGetIfaceStats; namespace android { -static const char* QTAGUID_IFACE_STATS = "/proc/net/xt_qtaguid/iface_stat_fmt"; -static const char* QTAGUID_UID_STATS = "/proc/net/xt_qtaguid/stats"; - // NOTE: keep these in sync with TrafficStats.java static const uint64_t UNKNOWN = -1; @@ -72,102 +69,17 @@ static uint64_t getStatsType(Stats* stats, StatsType type) { } } -static int parseIfaceStats(const char* iface, Stats* stats) { - FILE *fp = fopen(QTAGUID_IFACE_STATS, "r"); - if (fp == NULL) { - return -1; - } - - char buffer[384]; - char cur_iface[32]; - bool foundTcp = false; - uint64_t rxBytes, rxPackets, txBytes, txPackets, tcpRxPackets, tcpTxPackets; - - while (fgets(buffer, sizeof(buffer), fp) != NULL) { - int matched = sscanf(buffer, "%31s %" SCNu64 " %" SCNu64 " %" SCNu64 - " %" SCNu64 " " "%*u %" SCNu64 " %*u %*u %*u %*u " - "%*u %" SCNu64 " %*u %*u %*u %*u", cur_iface, &rxBytes, - &rxPackets, &txBytes, &txPackets, &tcpRxPackets, &tcpTxPackets); - if (matched >= 5) { - if (matched == 7) { - foundTcp = true; - } - if (!iface || !strcmp(iface, cur_iface)) { - stats->rxBytes += rxBytes; - stats->rxPackets += rxPackets; - stats->txBytes += txBytes; - stats->txPackets += txPackets; - if (matched == 7) { - stats->tcpRxPackets += tcpRxPackets; - stats->tcpTxPackets += tcpTxPackets; - } - } - } - } - - if (!foundTcp) { - stats->tcpRxPackets = UNKNOWN; - stats->tcpTxPackets = UNKNOWN; - } - - if (fclose(fp) != 0) { - return -1; - } - return 0; -} - -static int parseUidStats(const uint32_t uid, Stats* stats) { - FILE *fp = fopen(QTAGUID_UID_STATS, "r"); - if (fp == NULL) { - return -1; - } - - char buffer[384]; - char iface[32]; - uint32_t idx, cur_uid, set; - uint64_t tag, rxBytes, rxPackets, txBytes, txPackets; - - while (fgets(buffer, sizeof(buffer), fp) != NULL) { - if (sscanf(buffer, - "%" SCNu32 " %31s 0x%" SCNx64 " %u %u %" SCNu64 " %" SCNu64 - " %" SCNu64 " %" SCNu64 "", - &idx, iface, &tag, &cur_uid, &set, &rxBytes, &rxPackets, - &txBytes, &txPackets) == 9) { - if (uid == cur_uid && tag == 0L) { - stats->rxBytes += rxBytes; - stats->rxPackets += rxPackets; - stats->txBytes += txBytes; - stats->txPackets += txPackets; - } - } - } - - if (fclose(fp) != 0) { - return -1; - } - return 0; -} - -static jlong getTotalStat(JNIEnv* env, jclass clazz, jint type, jboolean useBpfStats) { +static jlong getTotalStat(JNIEnv* env, jclass clazz, jint type) { Stats stats = {}; - if (useBpfStats) { - if (bpfGetIfaceStats(NULL, &stats) == 0) { - return getStatsType(&stats, (StatsType) type); - } else { - return UNKNOWN; - } - } - - if (parseIfaceStats(NULL, &stats) == 0) { + if (bpfGetIfaceStats(NULL, &stats) == 0) { return getStatsType(&stats, (StatsType) type); } else { return UNKNOWN; } } -static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type, - jboolean useBpfStats) { +static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type) { ScopedUtfChars iface8(env, iface); if (iface8.c_str() == NULL) { return UNKNOWN; @@ -175,33 +87,17 @@ static jlong getIfaceStat(JNIEnv* env, jclass clazz, jstring iface, jint type, Stats stats = {}; - if (useBpfStats) { - if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) { - return getStatsType(&stats, (StatsType) type); - } else { - return UNKNOWN; - } - } - - if (parseIfaceStats(iface8.c_str(), &stats) == 0) { + if (bpfGetIfaceStats(iface8.c_str(), &stats) == 0) { return getStatsType(&stats, (StatsType) type); } else { return UNKNOWN; } } -static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type, jboolean useBpfStats) { +static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type) { Stats stats = {}; - if (useBpfStats) { - if (bpfGetUidStats(uid, &stats) == 0) { - return getStatsType(&stats, (StatsType) type); - } else { - return UNKNOWN; - } - } - - if (parseUidStats(uid, &stats) == 0) { + if (bpfGetUidStats(uid, &stats) == 0) { return getStatsType(&stats, (StatsType) type); } else { return UNKNOWN; @@ -209,9 +105,9 @@ static jlong getUidStat(JNIEnv* env, jclass clazz, jint uid, jint type, jboolean } static const JNINativeMethod gMethods[] = { - {"nativeGetTotalStat", "(IZ)J", (void*) getTotalStat}, - {"nativeGetIfaceStat", "(Ljava/lang/String;IZ)J", (void*) getIfaceStat}, - {"nativeGetUidStat", "(IIZ)J", (void*) getUidStat}, + {"nativeGetTotalStat", "(I)J", (void*)getTotalStat}, + {"nativeGetIfaceStat", "(Ljava/lang/String;I)J", (void*)getIfaceStat}, + {"nativeGetUidStat", "(II)J", (void*)getUidStat}, }; int register_android_server_net_NetworkStatsService(JNIEnv* env) { diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index aca7cc9070b1..4435637c9ad8 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -264,6 +264,8 @@ public final class SystemServer implements Dumpable { "com.android.server.stats.StatsCompanion$Lifecycle"; private static final String STATS_PULL_ATOM_SERVICE_CLASS = "com.android.server.stats.pull.StatsPullAtomService"; + private static final String STATS_BOOTSTRAP_ATOM_SERVICE_LIFECYCLE_CLASS = + "com.android.server.stats.bootstrap.StatsBootstrapAtomService$Lifecycle"; private static final String USB_SERVICE_CLASS = "com.android.server.usb.UsbService$Lifecycle"; private static final String MIDI_SERVICE_CLASS = @@ -2487,6 +2489,11 @@ public final class SystemServer implements Dumpable { mSystemServiceManager.startService(STATS_PULL_ATOM_SERVICE_CLASS); t.traceEnd(); + // Log atoms to statsd from bootstrap processes. + t.traceBegin("StatsBootstrapAtomService"); + mSystemServiceManager.startService(STATS_BOOTSTRAP_ATOM_SERVICE_LIFECYCLE_CLASS); + t.traceEnd(); + // Incidentd and dumpstated helper t.traceBegin("StartIncidentCompanionService"); mSystemServiceManager.startService(IncidentCompanionService.class); diff --git a/services/net/OWNERS b/services/net/OWNERS index d3836d4c6c57..62c5737a2e8e 100644 --- a/services/net/OWNERS +++ b/services/net/OWNERS @@ -1,8 +1,2 @@ set noparent - -codewiz@google.com -jchalard@google.com -junyulai@google.com -lorenzo@google.com -reminv@google.com -satk@google.com +file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking diff --git a/services/people/java/com/android/server/people/data/CallLogQueryHelper.java b/services/people/java/com/android/server/people/data/CallLogQueryHelper.java index 45e0aac24ca7..ff901af3defa 100644 --- a/services/people/java/com/android/server/people/data/CallLogQueryHelper.java +++ b/services/people/java/com/android/server/people/data/CallLogQueryHelper.java @@ -93,6 +93,9 @@ class CallLogQueryHelper { hasResults = true; } } + } catch (SecurityException ex) { + Slog.e(TAG, "Query call log failed: " + ex); + return false; } return hasResults; } diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java index 8369319ec55d..fb7ef846f813 100644 --- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java +++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java @@ -234,14 +234,16 @@ public final class ProfcollectForwardingService extends SystemService { "applaunch_trace_freq", 2); int randomNum = ThreadLocalRandom.current().nextInt(100); if (randomNum < traceFrequency) { - try { - if (DEBUG) { - Log.d(LOG_TAG, "Tracing on app launch event: " + packageName); - } - mIProfcollect.trace_once("applaunch"); - } catch (RemoteException e) { - Log.e(LOG_TAG, e.getMessage()); + if (DEBUG) { + Log.d(LOG_TAG, "Tracing on app launch event: " + packageName); } + BackgroundThread.get().getThreadHandler().post(() -> { + try { + mIProfcollect.trace_once("applaunch"); + } catch (RemoteException e) { + Log.e(LOG_TAG, e.getMessage()); + } + }); } } diff --git a/services/tests/servicestests/src/com/android/server/health/HealthServiceWrapperTest.java b/services/tests/servicestests/src/com/android/server/health/HealthServiceWrapperTest.java index c97a67bad590..16d97a454050 100644 --- a/services/tests/servicestests/src/com/android/server/health/HealthServiceWrapperTest.java +++ b/services/tests/servicestests/src/com/android/server/health/HealthServiceWrapperTest.java @@ -19,11 +19,12 @@ package com.android.server.health; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.fail; +import static org.mockito.AdditionalMatchers.not; import static org.mockito.Mockito.*; -import android.hardware.health.V2_0.IHealth; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; +import android.os.IServiceCallback; import android.os.RemoteException; import androidx.test.filters.SmallTest; @@ -44,28 +45,47 @@ import java.util.NoSuchElementException; @RunWith(AndroidJUnit4.class) public class HealthServiceWrapperTest { - @Mock IServiceManager mMockedManager; - @Mock IHealth mMockedHal; - @Mock IHealth mMockedHal2; + @Mock android.hardware.health.V2_0.IHealth mMockedHal; + @Mock android.hardware.health.V2_0.IHealth mMockedHal2; @Mock HealthServiceWrapperHidl.Callback mCallback; @Mock HealthServiceWrapperHidl.IServiceManagerSupplier mManagerSupplier; @Mock HealthServiceWrapperHidl.IHealthSupplier mHealthServiceSupplier; + + @Mock android.hardware.health.IHealth.Stub mMockedAidlHal; + @Mock android.hardware.health.IHealth.Stub mMockedAidlHal2; + @Mock HealthServiceWrapperAidl.ServiceManagerStub mMockedAidlManager; + @Mock HealthRegCallbackAidl mRegCallbackAidl; + HealthServiceWrapper mWrapper; private static final String VENDOR = HealthServiceWrapperHidl.INSTANCE_VENDOR; + private static final String AIDL_SERVICE_NAME = HealthServiceWrapperAidl.SERVICE_NAME; @Before public void setUp() { MockitoAnnotations.initMocks(this); + + // Mocks the conversion between IHealth and IBinder. + when(mMockedAidlHal.asBinder()).thenCallRealMethod(); // returns mMockedAidlHal + when(mMockedAidlHal2.asBinder()).thenCallRealMethod(); // returns mMockedAidlHal2 + when(mMockedAidlHal.queryLocalInterface(android.hardware.health.IHealth.DESCRIPTOR)) + .thenReturn(mMockedAidlHal); + when(mMockedAidlHal2.queryLocalInterface(android.hardware.health.IHealth.DESCRIPTOR)) + .thenReturn(mMockedAidlHal2); } @After public void tearDown() { + validateMockitoUsage(); if (mWrapper != null) mWrapper.getHandlerThread().quitSafely(); } + public static <T> ArgumentMatcher<T> isOneOf(T[] collection) { + return isOneOf(Arrays.asList(collection)); + } + public static <T> ArgumentMatcher<T> isOneOf(Collection<T> collection) { return new ArgumentMatcher<T>() { @Override @@ -75,13 +95,39 @@ public class HealthServiceWrapperTest { @Override public String toString() { - return collection.toString(); + return "is one of " + collection.toString(); } }; } - private void initForInstances(String... instanceNamesArr) throws Exception { - final Collection<String> instanceNames = Arrays.asList(instanceNamesArr); + /** + * Set up mock objects to pretend that the given AIDL and HIDL instances exists. + * + * <p>Also, when registering service notifications, the mocked service managers immediately + * sends 3 registration notifications, including 2 referring to the original HAL and 1 referring + * to the new HAL. + * + * @param aidlInstances e.g. {"android.hardware.health.IHealth/default"} + * @param hidlInstances e.g. {"default", "backup"} + * @throws Exception + */ + private void initForInstances(String[] aidlInstances, String[] hidlInstances) throws Exception { + doAnswer( + (invocation) -> { + sendAidlRegCallback(invocation, mMockedAidlHal); + sendAidlRegCallback(invocation, mMockedAidlHal); + sendAidlRegCallback(invocation, mMockedAidlHal2); + return null; + }) + .when(mMockedAidlManager) + .registerForNotifications( + argThat(isOneOf(aidlInstances)), any(IServiceCallback.class)); + when(mMockedAidlManager.waitForDeclaredService(argThat(isOneOf(aidlInstances)))) + .thenReturn(mMockedAidlHal) + .thenThrow(new RuntimeException("waitForDeclaredService called more than once")); + when(mMockedAidlManager.waitForDeclaredService(not(argThat(isOneOf(aidlInstances))))) + .thenReturn(null); + doAnswer( (invocation) -> { // technically, preexisting is ignored by @@ -93,8 +139,8 @@ public class HealthServiceWrapperTest { }) .when(mMockedManager) .registerForNotifications( - eq(IHealth.kInterfaceName), - argThat(isOneOf(instanceNames)), + eq(android.hardware.health.V2_0.IHealth.kInterfaceName), + argThat(isOneOf(hidlInstances)), any(IServiceNotification.class)); doReturn(mMockedManager).when(mManagerSupplier).get(); @@ -104,7 +150,7 @@ public class HealthServiceWrapperTest { .doReturn(mMockedHal2) // notification 3 .doThrow(new RuntimeException("Should not call getService for more than 4 times")) .when(mHealthServiceSupplier) - .get(argThat(isOneOf(instanceNames))); + .get(argThat(isOneOf(hidlInstances))); } private void waitHandlerThreadFinish() throws Exception { @@ -121,19 +167,62 @@ public class HealthServiceWrapperTest { throws Exception { ((IServiceNotification) invocation.getArguments()[2]) .onRegistration( - IHealth.kInterfaceName, (String) invocation.getArguments()[1], preexisting); + android.hardware.health.V2_0.IHealth.kInterfaceName, + (String) invocation.getArguments()[1], + preexisting); + } + + private static void sendAidlRegCallback( + InvocationOnMock invocation, android.hardware.health.IHealth service) throws Exception { + ((IServiceCallback) invocation.getArguments()[1]) + .onRegistration((String) invocation.getArguments()[0], service.asBinder()); } private void createWrapper() throws RemoteException { - mWrapper = HealthServiceWrapper.create(mCallback, mManagerSupplier, mHealthServiceSupplier); + mWrapper = + HealthServiceWrapper.create( + mRegCallbackAidl, + mMockedAidlManager, + mCallback, + mManagerSupplier, + mHealthServiceSupplier); + } + + @SmallTest + @Test + public void testWrapAidlOnly() throws Exception { + initForInstances(new String[] {AIDL_SERVICE_NAME}, new String[0]); + createWrapper(); + waitHandlerThreadFinish(); + verify(mRegCallbackAidl, times(1)).onRegistration(same(null), same(mMockedAidlHal)); + verify(mRegCallbackAidl, never()) + .onRegistration(same(mMockedAidlHal), same(mMockedAidlHal)); + verify(mRegCallbackAidl, times(1)) + .onRegistration(same(mMockedAidlHal), same(mMockedAidlHal2)); + verify(mCallback, never()).onRegistration(any(), any(), anyString()); + } + + @SmallTest + @Test + public void testWrapPreferAidl() throws Exception { + initForInstances(new String[] {AIDL_SERVICE_NAME}, new String[] {VENDOR}); + createWrapper(); + waitHandlerThreadFinish(); + verify(mRegCallbackAidl, times(1)).onRegistration(same(null), same(mMockedAidlHal)); + verify(mRegCallbackAidl, never()) + .onRegistration(same(mMockedAidlHal), same(mMockedAidlHal)); + verify(mRegCallbackAidl, times(1)) + .onRegistration(same(mMockedAidlHal), same(mMockedAidlHal2)); + verify(mCallback, never()).onRegistration(any(), any(), anyString()); } @SmallTest @Test - public void testWrapPreferVendor() throws Exception { - initForInstances(VENDOR); + public void testWrapFallbackHidl() throws Exception { + initForInstances(new String[0], new String[] {VENDOR}); createWrapper(); waitHandlerThreadFinish(); + verify(mRegCallbackAidl, never()).onRegistration(any(), any()); verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(VENDOR)); verify(mCallback, never()).onRegistration(same(mMockedHal), same(mMockedHal), anyString()); verify(mCallback, times(1)).onRegistration(same(mMockedHal), same(mMockedHal2), eq(VENDOR)); @@ -142,7 +231,7 @@ public class HealthServiceWrapperTest { @SmallTest @Test public void testNoService() throws Exception { - initForInstances("unrelated"); + initForInstances(new String[0], new String[] {"unrelated"}); try { createWrapper(); fail("Expect NoSuchElementException"); diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 894bb8e15333..5ffe45f8c489 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -5141,16 +5141,6 @@ public class CarrierConfigManager { "call_composer_picture_server_url_string"; /** - * For Android 11, provide a temporary solution for OEMs to use the lower of the two MTU values - * for IPv4 and IPv6 if both are sent. - * TODO: remove in later release - * - * @hide - */ - public static final String KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED = - "use_lower_mtu_value_if_both_received"; - - /** * Determines the default RTT mode. * * Upon first boot, when the user has not yet set a value for their preferred RTT mode, @@ -5888,7 +5878,6 @@ public class CarrierConfigManager { sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, ""); sDefaults.putBoolean(KEY_SUPPORTS_CALL_COMPOSER_BOOL, false); sDefaults.putString(KEY_CALL_COMPOSER_PICTURE_SERVER_URL_STRING, ""); - sDefaults.putBoolean(KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED, false); sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false); sDefaults.putBoolean(KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, true); sDefaults.putInt(KEY_DEFAULT_RTT_MODE_INT, 0); diff --git a/tests/AttestationVerificationTest/OWNERS b/tests/AttestationVerificationTest/OWNERS new file mode 100644 index 000000000000..a7a6ef156eda --- /dev/null +++ b/tests/AttestationVerificationTest/OWNERS @@ -0,0 +1 @@ +include /core/java/android/security/attestationverification/OWNERS diff --git a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java index 84448333a8c6..525a78486efc 100644 --- a/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java +++ b/tests/utils/hostutils/src/com/android/internal/util/test/SystemPreparer.java @@ -207,17 +207,6 @@ public class SystemPreparer extends ExternalResource { default: device.executeShellCommand("stop"); device.executeShellCommand("start"); - ITestDevice.RecoveryMode cachedRecoveryMode = device.getRecoveryMode(); - device.setRecoveryMode(ITestDevice.RecoveryMode.ONLINE); - - if (device.isEncryptionSupported()) { - if (device.isDeviceEncrypted()) { - LogUtil.CLog.e("Device is encrypted after userspace reboot!"); - device.unlockDevice(); - } - } - - device.setRecoveryMode(cachedRecoveryMode); device.waitForDeviceAvailable(); break; } diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh index ac23c3d9cb4a..36bea57b710f 100755 --- a/tools/aosp/aosp_sha.sh +++ b/tools/aosp/aosp_sha.sh @@ -1,7 +1,7 @@ #!/bin/bash LOCAL_DIR="$( dirname "${BASH_SOURCE}" )" -if git branch -vv | grep -q -P "^\*[^\[]+\[aosp/"; then +if git branch -vv | grep -q -E "^\*[^\[]+\[aosp/"; then # Change appears to be in AOSP exit 0 elif git log -n 1 --format='%B' $1 | grep -q -E "^Ignore-AOSP-First: .+" ; then |