diff options
22 files changed, 356 insertions, 113 deletions
diff --git a/apex/jobscheduler/service/jni/Android.bp b/apex/jobscheduler/service/jni/Android.bp index 34a1fa2ebc13..e8acff739e52 100644 --- a/apex/jobscheduler/service/jni/Android.bp +++ b/apex/jobscheduler/service/jni/Android.bp @@ -28,4 +28,8 @@ cc_library_shared { "liblog", "libbase", ], + visibility: [ + "//frameworks/base/apex:__subpackages__", + "//visibility:any_system_partition", + ], } diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING index 7a449effdf76..af54a2decd89 100644 --- a/cmds/locksettings/TEST_MAPPING +++ b/cmds/locksettings/TEST_MAPPING @@ -11,5 +11,10 @@ } ] } + ], + "postsubmit": [ + { + "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes" + } ] } diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java index c14d8d805d29..8063be64f36d 100644 --- a/core/java/com/android/internal/os/BinderInternal.java +++ b/core/java/com/android/internal/os/BinderInternal.java @@ -45,8 +45,8 @@ public class BinderInternal { static ArrayList<Runnable> sGcWatchers = new ArrayList<>(); static Runnable[] sTmpWatchers = new Runnable[1]; static long sLastGcTime; - static final BinderProxyLimitListenerDelegate sBinderProxyLimitListenerDelegate = - new BinderProxyLimitListenerDelegate(); + static final BinderProxyCountEventListenerDelegate sBinderProxyCountEventListenerDelegate = + new BinderProxyCountEventListenerDelegate(); static final class GcWatcher { @Override @@ -226,15 +226,24 @@ public class BinderInternal { * @param low The threshold a binder count must drop below before the callback * can be called again. (This is to avoid many repeated calls to the * callback in a brief period of time) + * @param warning The threshold between {@code high} and {@code low} where if the binder count + * exceeds that, the warning callback would be triggered. */ - public static final native void nSetBinderProxyCountWatermarks(int high, int low); + public static final native void nSetBinderProxyCountWatermarks(int high, int low, int warning); /** * Interface for callback invocation when the Binder Proxy limit is reached. onLimitReached will * be called with the uid of the app causing too many Binder Proxies */ - public interface BinderProxyLimitListener { + public interface BinderProxyCountEventListener { public void onLimitReached(int uid); + + /** + * Call when the number of binder proxies from the uid of the app reaches + * the warning threshold. + */ + default void onWarningThresholdReached(int uid) { + } } /** @@ -243,7 +252,17 @@ public class BinderInternal { * @param uid The uid of the bad behaving app sending too many binders */ public static void binderProxyLimitCallbackFromNative(int uid) { - sBinderProxyLimitListenerDelegate.notifyClient(uid); + sBinderProxyCountEventListenerDelegate.notifyLimitReached(uid); + } + + /** + * Callback used by native code to trigger a callback in java code. The callback will be + * triggered when too many binder proxies from a uid hits the warning limit. + * @param uid The uid of the bad behaving app sending too many binders + */ + @SuppressWarnings("unused") + public static void binderProxyWarningCallbackFromNative(int uid) { + sBinderProxyCountEventListenerDelegate.notifyWarningReached(uid); } /** @@ -252,41 +271,45 @@ public class BinderInternal { * @param handler must not be null, callback will be posted through the handler; * */ - public static void setBinderProxyCountCallback(BinderProxyLimitListener listener, + public static void setBinderProxyCountCallback(BinderProxyCountEventListener listener, @NonNull Handler handler) { Preconditions.checkNotNull(handler, "Must provide NonNull Handler to setBinderProxyCountCallback when setting " - + "BinderProxyLimitListener"); - sBinderProxyLimitListenerDelegate.setListener(listener, handler); + + "BinderProxyCountEventListener"); + sBinderProxyCountEventListenerDelegate.setListener(listener, handler); } /** * Clear the Binder Proxy callback */ public static void clearBinderProxyCountCallback() { - sBinderProxyLimitListenerDelegate.setListener(null, null); + sBinderProxyCountEventListenerDelegate.setListener(null, null); } - static private class BinderProxyLimitListenerDelegate { - private BinderProxyLimitListener mBinderProxyLimitListener; + private static class BinderProxyCountEventListenerDelegate { + private BinderProxyCountEventListener mBinderProxyCountEventListener; private Handler mHandler; - void setListener(BinderProxyLimitListener listener, Handler handler) { + void setListener(BinderProxyCountEventListener listener, Handler handler) { synchronized (this) { - mBinderProxyLimitListener = listener; + mBinderProxyCountEventListener = listener; mHandler = handler; } } - void notifyClient(final int uid) { + void notifyLimitReached(final int uid) { + synchronized (this) { + if (mBinderProxyCountEventListener != null) { + mHandler.post(() -> mBinderProxyCountEventListener.onLimitReached(uid)); + } + } + } + + void notifyWarningReached(final int uid) { synchronized (this) { - if (mBinderProxyLimitListener != null) { - mHandler.post(new Runnable() { - @Override - public void run() { - mBinderProxyLimitListener.onLimitReached(uid); - } - }); + if (mBinderProxyCountEventListener != null) { + mHandler.post(() -> + mBinderProxyCountEventListener.onWarningThresholdReached(uid)); } } } diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index d2d5186eb8a1..2068bd7bc8ea 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -88,6 +88,7 @@ static struct binderinternal_offsets_t jclass mClass; jmethodID mForceGc; jmethodID mProxyLimitCallback; + jmethodID mProxyWarningCallback; } gBinderInternalOffsets; @@ -1240,7 +1241,7 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz) gCollectedAtRefs = gNumLocalRefsCreated + gNumDeathRefsCreated; } -static void android_os_BinderInternal_proxyLimitcallback(int uid) +static void android_os_BinderInternal_proxyLimitCallback(int uid) { JNIEnv *env = AndroidRuntime::getJNIEnv(); env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, @@ -1254,6 +1255,20 @@ static void android_os_BinderInternal_proxyLimitcallback(int uid) } } +static void android_os_BinderInternal_proxyWarningCallback(int uid) +{ + JNIEnv *env = AndroidRuntime::getJNIEnv(); + env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, + gBinderInternalOffsets.mProxyWarningCallback, + uid); + + if (env->ExceptionCheck()) { + ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred()); + binder_report_exception(env, excep.get(), + "*** Uncaught exception in binderProxyWarningCallbackFromNative"); + } +} + static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz, jboolean enable) { @@ -1278,9 +1293,10 @@ static jint android_os_BinderInternal_getBinderProxyCount(JNIEnv* env, jobject c } static void android_os_BinderInternal_setBinderProxyCountWatermarks(JNIEnv* env, jobject clazz, - jint high, jint low) + jint high, jint low, + jint warning) { - BpBinder::setBinderProxyCountWatermarks(high, low); + BpBinder::setBinderProxyCountWatermarks(high, low, warning); } // ---------------------------------------------------------------------------- @@ -1295,7 +1311,7 @@ static const JNINativeMethod gBinderInternalMethods[] = { { "nSetBinderProxyCountEnabled", "(Z)V", (void*)android_os_BinderInternal_setBinderProxyCountEnabled }, { "nGetBinderProxyPerUidCounts", "()Landroid/util/SparseIntArray;", (void*)android_os_BinderInternal_getBinderProxyPerUidCounts }, { "nGetBinderProxyCount", "(I)I", (void*)android_os_BinderInternal_getBinderProxyCount }, - { "nSetBinderProxyCountWatermarks", "(II)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} + { "nSetBinderProxyCountWatermarks", "(III)V", (void*)android_os_BinderInternal_setBinderProxyCountWatermarks} }; const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal"; @@ -1307,6 +1323,8 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz); gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V"); gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V"); + gBinderInternalOffsets.mProxyWarningCallback = + GetStaticMethodIDOrDie(env, clazz, "binderProxyWarningCallbackFromNative", "(I)V"); jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray"); gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass); @@ -1315,7 +1333,8 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put", "(II)V"); - BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback); + BpBinder::setBinderProxyCountEventCallback(android_os_BinderInternal_proxyLimitCallback, + android_os_BinderInternal_proxyWarningCallback); return RegisterMethodsOrDie( env, kBinderInternalPathName, diff --git a/core/res/OWNERS b/core/res/OWNERS index 6924248b33cf..3c2bc0dd31a2 100644 --- a/core/res/OWNERS +++ b/core/res/OWNERS @@ -4,7 +4,6 @@ austindelgado@google.com cinek@google.com dsandler@android.com dsandler@google.com -dupin@google.com hackbod@android.com hackbod@google.com ilyamaty@google.com @@ -46,7 +45,7 @@ per-file res/values/config_device_idle.xml = file:/apex/jobscheduler/OWNERS # Wear per-file res/*-watch/* = file:/WEAR_OWNERS -# Peformance +# Performance per-file res/values/config.xml = file:/PERFORMANCE_OWNERS per-file res/values/symbols.xml = file:/PERFORMANCE_OWNERS @@ -60,3 +59,11 @@ per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/ # TV Input Framework per-file res/values/config_tv_external_input_logging.xml = file:/services/core/java/com/android/server/tv/OWNERS + +# SysUi Color Team +per-file res/values/colors.xml = arteiro@google.com +per-file res/values/attrs.xml = arteiro@google.com +per-file res/values/styles.xml = arteiro@google.com +per-file res/values/symbols.xml = arteiro@google.com +per-file res/values/themes_device_defaults.xml = arteiro@google.com +per-file res/values/styles_material.xml = arteiro@google.com
\ No newline at end of file diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp index 1a3ec27418a6..871feb65bc75 100644 --- a/core/tests/coretests/Android.bp +++ b/core/tests/coretests/Android.bp @@ -116,6 +116,8 @@ android_test { ":BinderDeathRecipientHelperApp1", ":BinderDeathRecipientHelperApp2", ":com.android.cts.helpers.aosp", + ":BinderProxyCountingTestApp", + ":BinderProxyCountingTestService", ], } diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml index 05b309b2cd52..bf2a5b875dba 100644 --- a/core/tests/coretests/AndroidTest.xml +++ b/core/tests/coretests/AndroidTest.xml @@ -22,6 +22,8 @@ <option name="test-file-name" value="FrameworksCoreTests.apk" /> <option name="test-file-name" value="BinderDeathRecipientHelperApp1.apk" /> <option name="test-file-name" value="BinderDeathRecipientHelperApp2.apk" /> + <option name="test-file-name" value="BinderProxyCountingTestApp.apk" /> + <option name="test-file-name" value="BinderProxyCountingTestService.apk" /> </target_preparer> <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"> diff --git a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml index a971730f389d..c8407b80cfac 100644 --- a/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml +++ b/core/tests/coretests/BinderProxyCountingTestApp/AndroidManifest.xml @@ -16,6 +16,9 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.frameworks.coretests.binderproxycountingtestapp"> + <queries> + <package android:name="com.android.frameworks.coretests.binderproxycountingtestservice" /> + </queries> <application> <service android:name=".BpcTestAppCmdService" android:exported="true"/> diff --git a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java index 5aae1203e559..a7e97d3cd54e 100644 --- a/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java +++ b/core/tests/coretests/BinderProxyCountingTestApp/src/com/android/frameworks/coretests/binderproxycountingtestapp/BpcTestAppCmdService.java @@ -17,14 +17,15 @@ package com.android.frameworks.coretests.binderproxycountingtestapp; import android.app.Service; -import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.content.ServiceConnection; +import android.database.ContentObserver; +import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; +import android.provider.Settings; import android.util.Log; import com.android.frameworks.coretests.aidl.IBinderProxyCountingService; @@ -49,24 +50,20 @@ public class BpcTestAppCmdService extends Service { private IBpcTestAppCmdService.Stub mBinder = new IBpcTestAppCmdService.Stub() { - private ArrayList<BroadcastReceiver> mBrList = new ArrayList(); + private ArrayList<ContentObserver> mCoList = new ArrayList(); private ArrayList<ITestRemoteCallback> mTrcList = new ArrayList(); + private Handler mHandler = new Handler(); @Override public void createSystemBinders(int count) { int i = 0; while (i++ < count) { - BroadcastReceiver br = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - - } - }; - IntentFilter filt = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED); - synchronized (mBrList) { - mBrList.add(br); + final ContentObserver co = new ContentObserver(mHandler) {}; + synchronized (mCoList) { + mCoList.add(co); } - registerReceiver(br, filt); + getContentResolver().registerContentObserver( + Settings.System.CONTENT_URI, false, co); } } @@ -74,11 +71,11 @@ public class BpcTestAppCmdService extends Service { public void releaseSystemBinders(int count) { int i = 0; while (i++ < count) { - BroadcastReceiver br; - synchronized (mBrList) { - br = mBrList.remove(0); + ContentObserver co; + synchronized (mCoList) { + co = mCoList.remove(0); } - unregisterReceiver(br); + getContentResolver().unregisterContentObserver(co); } } @@ -117,9 +114,9 @@ public class BpcTestAppCmdService extends Service { @Override public void releaseAllBinders() { - synchronized (mBrList) { - while (mBrList.size() > 0) { - unregisterReceiver(mBrList.remove(0)); + synchronized (mCoList) { + while (mCoList.size() > 0) { + getContentResolver().unregisterContentObserver(mCoList.remove(0)); } } synchronized (mTrcList) { @@ -179,4 +176,4 @@ public class BpcTestAppCmdService extends Service { public IBinder onBind(Intent intent) { return mBinder; } -}
\ No newline at end of file +} diff --git a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java index 6bed2a2ec53f..0f1accc4a7e9 100644 --- a/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java +++ b/core/tests/coretests/BinderProxyCountingTestService/src/com/android/frameworks/coretests/binderproxycountingtestservice/BpcTestServiceCmdService.java @@ -55,8 +55,8 @@ public class BpcTestServiceCmdService extends Service { } @Override - public void setBinderProxyWatermarks(int high, int low) { - BinderInternal.nSetBinderProxyCountWatermarks(high, low); + public void setBinderProxyWatermarks(int high, int low, int warning) { + BinderInternal.nSetBinderProxyCountWatermarks(high, low, warning); } @Override @@ -68,12 +68,23 @@ public class BpcTestServiceCmdService extends Service { public void setBinderProxyCountCallback(IBpcCallbackObserver observer) { if (observer != null) { BinderInternal.setBinderProxyCountCallback( - new BinderInternal.BinderProxyLimitListener() { + new BinderInternal.BinderProxyCountEventListener() { @Override public void onLimitReached(int uid) { try { synchronized (observer) { - observer.onCallback(uid); + observer.onLimitReached(uid); + } + } catch (Exception e) { + Log.e(TAG, e.toString()); + } + } + + @Override + public void onWarningThresholdReached(int uid) { + try { + synchronized (observer) { + observer.onWarningThresholdReached(uid); } } catch (Exception e) { Log.e(TAG, e.toString()); @@ -98,4 +109,4 @@ public class BpcTestServiceCmdService extends Service { mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); } -}
\ No newline at end of file +} diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl index c4ebd56bed6c..ada7d92c89e1 100644 --- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl +++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcCallbackObserver.aidl @@ -17,5 +17,6 @@ package com.android.frameworks.coretests.aidl; interface IBpcCallbackObserver { - void onCallback(int uid); -}
\ No newline at end of file + void onLimitReached(int uid); + void onWarningThresholdReached(int uid); +} diff --git a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl index abdab41ce537..cdcda9d93bd2 100644 --- a/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl +++ b/core/tests/coretests/aidl/com/android/frameworks/coretests/aidl/IBpcTestServiceCmdService.aidl @@ -20,7 +20,7 @@ import com.android.frameworks.coretests.aidl.IBpcCallbackObserver; interface IBpcTestServiceCmdService { void forceGc(); int getBinderProxyCount(int uid); - void setBinderProxyWatermarks(int high, int low); + void setBinderProxyWatermarks(int high, int low, int warning); void enableBinderProxyLimit(boolean enable); void setBinderProxyCountCallback(IBpcCallbackObserver observer); -}
\ No newline at end of file +} diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java index bcd9521019e4..84d299592f26 100644 --- a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java +++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java @@ -88,9 +88,10 @@ public class BinderProxyCountingTest { private static final int BIND_SERVICE_TIMEOUT_SEC = 5; private static final int TOO_MANY_BINDERS_TIMEOUT_SEC = 2; + private static final int TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC = 30; - // Keep in sync with sBinderProxyCountLimit in BpBinder.cpp - private static final int BINDER_PROXY_LIMIT = 2500; + // Keep in sync with BINDER_PROXY_HIGH_WATERMARK in ActivityManagerService.java + private static final int BINDER_PROXY_LIMIT = 6000; private static Context sContext; private static UiDevice sUiDevice; @@ -175,18 +176,26 @@ public class BinderProxyCountingTest { } } - private CountDownLatch createBinderLimitLatch() throws RemoteException { - final CountDownLatch latch = new CountDownLatch(1); + private CountDownLatch[] createBinderLimitLatch() throws RemoteException { + final CountDownLatch[] latches = new CountDownLatch[] { + new CountDownLatch(1), new CountDownLatch(1) + }; sBpcTestServiceCmdService.setBinderProxyCountCallback( new IBpcCallbackObserver.Stub() { @Override - public void onCallback(int uid) { + public void onLimitReached(int uid) { if (uid == sTestPkgUid) { - latch.countDown(); + latches[0].countDown(); + } + } + @Override + public void onWarningThresholdReached(int uid) { + if (uid == sTestPkgUid) { + latches[1].countDown(); } } }); - return latch; + return latches; } /** @@ -227,6 +236,7 @@ public class BinderProxyCountingTest { @Test public void testBinderProxyLimitBoundary() throws Exception { final int binderProxyLimit = 2000; + final int binderProxyWarning = 1900; final int rearmThreshold = 1800; try { sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent); @@ -238,19 +248,33 @@ public class BinderProxyCountingTest { // Get the baseline of binders naturally held by the test Package int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); - final CountDownLatch binderLimitLatch = createBinderLimitLatch(); - sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold); + final CountDownLatch[] binderLatches = createBinderLimitLatch(); + sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold, + binderProxyWarning); + + // Create Binder Proxies up to the warning; + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount); + if (binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + + " when proxy warning should not have been triggered"); + } + + // Create one more Binder to trigger the warning + sBpcTestAppCmdService.createTestBinders(1); + if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning"); + } // Create Binder Proxies up to the limit - sBpcTestAppCmdService.createTestBinders(binderProxyLimit - baseBinderCount); - if (binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(binderProxyLimit - binderProxyWarning - 1); + if (binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + " when proxy limit should not have been reached"); } // Create one more Binder to cross the limit sBpcTestAppCmdService.createTestBinders(1); - if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -274,12 +298,20 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); for (int testLimit : testLimits) { - final CountDownLatch binderLimitLatch = createBinderLimitLatch(); + final CountDownLatch[] binderLatches = createBinderLimitLatch(); // Change the BinderProxyLimit - sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10); + sBpcTestServiceCmdService.setBinderProxyWatermarks(testLimit, baseBinderCount + 10, + testLimit - 10); + + // Trigger the new Binder Proxy warning + sBpcTestAppCmdService.createTestBinders(testLimit - 9 - baseBinderCount); + if (!binderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger the warning"); + } + // Exceed the new Binder Proxy Limit - sBpcTestAppCmdService.createTestBinders(testLimit + 1); - if (!binderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(10); + if (!binderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -297,6 +329,7 @@ public class BinderProxyCountingTest { public void testRearmCallbackThreshold() throws Exception { final int binderProxyLimit = 2000; final int exceedBinderProxyLimit = binderProxyLimit + 10; + final int binderProxyWarning = 1900; final int rearmThreshold = 1800; try { sTestAppConnection = bindService(sTestAppConsumer, sTestAppIntent); @@ -305,11 +338,19 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.enableBinderProxyLimit(true); sBpcTestServiceCmdService.forceGc(); - final CountDownLatch firstBinderLimitLatch = createBinderLimitLatch(); - sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold); + int baseBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); + final CountDownLatch[] firstBinderLatches = createBinderLimitLatch(); + sBpcTestServiceCmdService.setBinderProxyWatermarks(binderProxyLimit, rearmThreshold, + binderProxyWarning); + // Trigger the Binder Proxy Waring + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - baseBinderCount + 1); + if (!firstBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning"); + } + // Exceed the Binder Proxy Limit - sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit); - if (!firstBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning); + if (!firstBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } @@ -321,11 +362,20 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); - final CountDownLatch secondBinderLimitLatch = createBinderLimitLatch(); + final CountDownLatch[] secondBinderLatches = createBinderLimitLatch(); + + // Exceed the Binder Proxy warning which should not cause a callback since there has + // been no rearm + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1); + if (secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + + " when the callback has not been rearmed yet"); + } + // Exceed the Binder Proxy limit which should not cause a callback since there has // been no rearm - sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount); - if (secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - binderProxyWarning); + if (secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Received BinderProxyLimitCallback for uid " + sTestPkgUid + " when the callback has not been rearmed yet"); } @@ -337,10 +387,16 @@ public class BinderProxyCountingTest { sBpcTestServiceCmdService.forceGc(); currentBinderCount = sBpcTestServiceCmdService.getBinderProxyCount(sTestPkgUid); + // Trigger the Binder Proxy Waring + sBpcTestAppCmdService.createTestBinders(binderProxyWarning - currentBinderCount + 1); + if (!secondBinderLatches[1].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + fail("Timed out waiting for uid " + sTestPkgUid + " to trigger warning"); + } + // Exceed the Binder Proxy limit for the last time sBpcTestAppCmdService.createTestBinders(exceedBinderProxyLimit - currentBinderCount); - if (!secondBinderLimitLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!secondBinderLatches[0].await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { fail("Timed out waiting for uid " + sTestPkgUid + " to hit limit"); } sBpcTestAppCmdService.releaseTestBinders(currentBinderCount); @@ -373,7 +429,7 @@ public class BinderProxyCountingTest { // is not unexpected } - if (!binderDeathLatch.await(TOO_MANY_BINDERS_TIMEOUT_SEC, TimeUnit.SECONDS)) { + if (!binderDeathLatch.await(TOO_MANY_BINDERS_WITH_KILL_TIMEOUT_SEC, TimeUnit.SECONDS)) { sBpcTestAppCmdService.releaseSystemBinders(exceedBinderProxyLimit); fail("Timed out waiting for uid " + sTestPkgUid + " to die."); } diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java index efbbfc23736f..24aea371c094 100644 --- a/keystore/java/android/security/AndroidKeyStoreMaintenance.java +++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java @@ -229,4 +229,24 @@ public class AndroidKeyStoreMaintenance { "Keystore error while trying to get apps affected by SID."); } } + + /** + * Deletes all keys in all KeyMint devices. + * Called by RecoverySystem before rebooting to recovery in order to delete all KeyMint keys, + * including synthetic password protector keys (used by LockSettingsService), as well as keys + * protecting DE and metadata encryption keys (used by vold). This ensures that FBE-encrypted + * data is unrecoverable even if the data wipe in recovery is interrupted or skipped. + */ + public static void deleteAllKeys() throws KeyStoreException { + StrictMode.noteDiskWrite(); + try { + getService().deleteAllKeys(); + } catch (RemoteException | NullPointerException e) { + throw new KeyStoreException(SYSTEM_ERROR, + "Failure to connect to Keystore while trying to delete all keys."); + } catch (ServiceSpecificException e) { + throw new KeyStoreException(e.errorCode, + "Keystore error while trying to delete all keys."); + } + } } diff --git a/nfc/TEST_MAPPING b/nfc/TEST_MAPPING index 5b5ea3790010..49c778d22038 100644 --- a/nfc/TEST_MAPPING +++ b/nfc/TEST_MAPPING @@ -5,6 +5,9 @@ }, { "name": "CtsNfcTestCases" + }, + { + "name": "CtsNdefTestCases" } ] } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java index 76c228252484..d5962886266d 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java @@ -99,9 +99,10 @@ public class SystemUIService extends Service { if (Build.IS_DEBUGGABLE) { // b/71353150 - looking for leaked binder proxies BinderInternal.nSetBinderProxyCountEnabled(true); - BinderInternal.nSetBinderProxyCountWatermarks(1000,900); + BinderInternal.nSetBinderProxyCountWatermarks( + /* high= */ 1000, /* low= */ 900, /* warning= */ 950); BinderInternal.setBinderProxyCountCallback( - new BinderInternal.BinderProxyLimitListener() { + new BinderInternal.BinderProxyCountEventListener() { @Override public void onLimitReached(int uid) { Slog.w(SystemUIApplication.TAG, diff --git a/services/core/Android.bp b/services/core/Android.bp index d22427af7b79..7b0bc8f501d8 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -169,7 +169,9 @@ java_library_static { "android.hardware.health-V3-java", // AIDL "android.hardware.health-translate-java", "android.hardware.light-V1-java", + "android.hardware.security.authgraph-V1-java", "android.hardware.security.rkp-V3-java", + "android.hardware.security.secretkeeper-V1-java", "android.hardware.tv.cec-V1.1-java", "android.hardware.tv.hdmi.cec-V1-java", "android.hardware.tv.hdmi.connection-V1-java", diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0711b71e8b5d..d35892e152db 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -413,6 +413,7 @@ import com.android.internal.os.BackgroundThread; import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener; import com.android.internal.os.BinderCallHeavyHitterWatcher.HeavyHitterContainer; import com.android.internal.os.BinderInternal; +import com.android.internal.os.BinderInternal.BinderProxyCountEventListener; import com.android.internal.os.BinderTransactionNameResolver; import com.android.internal.os.ByteTransferPipe; import com.android.internal.os.IResultReceiver; @@ -610,8 +611,8 @@ public class ActivityManagerService extends IActivityManager.Stub private static final int MINIMUM_MEMORY_GROWTH_THRESHOLD = 10 * 1000; // 10 MB /** - * The number of binder proxies we need to have before we start warning and - * dumping debug info. + * The number of binder proxies we need to have before we start dumping debug info + * and kill the offenders. */ private static final int BINDER_PROXY_HIGH_WATERMARK = 6000; @@ -621,6 +622,11 @@ public class ActivityManagerService extends IActivityManager.Stub */ private static final int BINDER_PROXY_LOW_WATERMARK = 5500; + /** + * The number of binder proxies we need to have before we start warning. + */ + private static final int BINDER_PROXY_WARNING_WATERMARK = 5750; + // Max character limit for a notification title. If the notification title is larger than this // the notification will not be legible to the user. private static final int MAX_BUGREPORT_TITLE_SIZE = 100; @@ -8926,33 +8932,10 @@ public class ActivityManagerService extends IActivityManager.Stub t.traceBegin("setBinderProxies"); BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK, - BINDER_PROXY_LOW_WATERMARK); + BINDER_PROXY_LOW_WATERMARK, BINDER_PROXY_WARNING_WATERMARK); BinderInternal.nSetBinderProxyCountEnabled(true); - BinderInternal.setBinderProxyCountCallback( - (uid) -> { - Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " - + Process.myUid()); - BinderProxy.dumpProxyDebugInfo(); - if (uid == Process.SYSTEM_UID) { - Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); - } else { - killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), - ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, - ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS, - "Too many Binders sent to SYSTEM"); - // We need to run a GC here, because killing the processes involved - // actually isn't guaranteed to free up the proxies; in fact, if the - // GC doesn't run for a long time, we may even exceed the global - // proxy limit for a process (20000), resulting in system_server itself - // being killed. - // Note that the GC here might not actually clean up all the proxies, - // because the binder reference decrements will come in asynchronously; - // but if new processes belonging to the UID keep adding proxies, we - // will get another callback here, and run the GC again - this time - // cleaning up the old proxies. - VMRuntime.getRuntime().requestConcurrentGC(); - } - }, BackgroundThread.getHandler()); + BinderInternal.setBinderProxyCountCallback(new MyBinderProxyCountEventListener(), + BackgroundThread.getHandler()); t.traceEnd(); // setBinderProxies t.traceEnd(); // ActivityManagerStartApps @@ -8967,6 +8950,45 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private class MyBinderProxyCountEventListener implements BinderProxyCountEventListener { + @Override + public void onLimitReached(int uid) { + Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + + Process.myUid()); + BinderProxy.dumpProxyDebugInfo(); + if (uid == Process.SYSTEM_UID) { + Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); + } else { + killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), + ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE, + ApplicationExitInfo.SUBREASON_EXCESSIVE_BINDER_OBJECTS, + "Too many Binders sent to SYSTEM"); + // We need to run a GC here, because killing the processes involved + // actually isn't guaranteed to free up the proxies; in fact, if the + // GC doesn't run for a long time, we may even exceed the global + // proxy limit for a process (20000), resulting in system_server itself + // being killed. + // Note that the GC here might not actually clean up all the proxies, + // because the binder reference decrements will come in asynchronously; + // but if new processes belonging to the UID keep adding proxies, we + // will get another callback here, and run the GC again - this time + // cleaning up the old proxies. + VMRuntime.getRuntime().requestConcurrentGC(); + } + } + + @Override + public void onWarningThresholdReached(int uid) { + if (com.android.server.am.Flags.logExcessiveBinderProxies()) { + Slog.w(TAG, "Uid " + uid + " sent too many (" + + BINDER_PROXY_WARNING_WATERMARK + ") Binders to uid " + Process.myUid()); + FrameworkStatsLog.write( + FrameworkStatsLog.EXCESSIVE_BINDER_PROXY_COUNT_REPORTED, + uid); + } + } + } + private void watchDeviceProvisioning(Context context) { // setting system property based on whether device is provisioned diff --git a/services/core/java/com/android/server/am/flags.aconfig b/services/core/java/com/android/server/am/flags.aconfig index d9e8dddddae4..c666915ddca5 100644 --- a/services/core/java/com/android/server/am/flags.aconfig +++ b/services/core/java/com/android/server/am/flags.aconfig @@ -28,3 +28,10 @@ flag { description: "Restrict network access for certain applications in BFGS process state" bug: "304347838" } + +flag { + namespace: "backstage_power" + name: "log_excessive_binder_proxies" + description: "Log the excessive incoming binder proxies into statsd" + bug: "298263955" +} diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING index ddf3d76e97ae..256d9ba86a6f 100644 --- a/services/core/java/com/android/server/locksettings/TEST_MAPPING +++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING @@ -24,5 +24,11 @@ } ] } + ], + "postsubmit": [ + { + // TODO(b/332974906): Promote in presubmit-large. + "name": "CtsDevicePolicyManagerTestCases_LockSettings_NoFlakes" + } ] } diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index c2e2dadde857..dc4618413715 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -30,6 +30,7 @@ import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_NO_PROVIDER; import android.annotation.IntDef; +import android.annotation.Nullable; import android.apex.CompressedApexInfo; import android.apex.CompressedApexInfoList; import android.content.Context; @@ -37,6 +38,7 @@ import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.boot.IBootControl; +import android.hardware.security.secretkeeper.ISecretkeeper; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.Binder; @@ -52,6 +54,7 @@ import android.os.ServiceManager; import android.os.ShellCallback; import android.os.SystemProperties; import android.provider.DeviceConfig; +import android.security.AndroidKeyStoreMaintenance; import android.util.ArrayMap; import android.util.ArraySet; import android.util.FastImmutableArraySet; @@ -67,6 +70,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.pm.ApexManager; import com.android.server.recoverysystem.hal.BootControlHIDL; +import com.android.server.utils.Slogf; import libcore.io.IoUtils; @@ -118,6 +122,8 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo static final String LSKF_CAPTURED_TIMESTAMP_PREF = "lskf_captured_timestamp"; static final String LSKF_CAPTURED_COUNT_PREF = "lskf_captured_count"; + static final String RECOVERY_WIPE_DATA_COMMAND = "--wipe_data"; + private final Injector mInjector; private final Context mContext; @@ -521,18 +527,57 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo @Override // Binder call public void rebootRecoveryWithCommand(String command) { if (DEBUG) Slog.d(TAG, "rebootRecoveryWithCommand: [" + command + "]"); + + boolean isForcedWipe = command != null && command.contains(RECOVERY_WIPE_DATA_COMMAND); synchronized (sRequestLock) { if (!setupOrClearBcb(true, command)) { Slog.e(TAG, "rebootRecoveryWithCommand failed to setup BCB"); return; } + if (isForcedWipe) { + deleteSecrets(); + // TODO: consider adding a dedicated forced-wipe-reboot method to PowerManager and + // calling here. + } + // Having set up the BCB, go ahead and reboot. PowerManager pm = mInjector.getPowerManager(); pm.reboot(PowerManager.REBOOT_RECOVERY); } } + private static void deleteSecrets() { + Slogf.w(TAG, "deleteSecrets"); + try { + AndroidKeyStoreMaintenance.deleteAllKeys(); + } catch (android.security.KeyStoreException e) { + Log.wtf(TAG, "Failed to delete all keys from keystore.", e); + } + + try { + ISecretkeeper secretKeeper = getSecretKeeper(); + if (secretKeeper != null) { + Slogf.i(TAG, "ISecretkeeper.deleteAll();"); + secretKeeper.deleteAll(); + } + } catch (RemoteException e) { + Log.wtf(TAG, "Failed to delete all secrets from secretkeeper.", e); + } + } + + private static @Nullable ISecretkeeper getSecretKeeper() { + ISecretkeeper result = null; + try { + result = ISecretkeeper.Stub.asInterface( + ServiceManager.waitForDeclaredService(ISecretkeeper.DESCRIPTOR + "/default")); + } catch (SecurityException e) { + Slog.w(TAG, "Does not have permissions to get AIDL secretkeeper service"); + } + + return result; + } + private void enforcePermissionForResumeOnReboot() { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.RECOVERY) != PackageManager.PERMISSION_GRANTED diff --git a/services/devicepolicy/TEST_MAPPING b/services/devicepolicy/TEST_MAPPING index 0d5534ba74df..b8cb4a91d6f1 100644 --- a/services/devicepolicy/TEST_MAPPING +++ b/services/devicepolicy/TEST_MAPPING @@ -26,5 +26,12 @@ } ] } + ], + "postsubmit": [ + { + // TODO(b/332974906): Promote in presubmit presubmit-devicepolicy. + "name": "CtsDevicePolicyManagerTestCases_NoFlakes_NoLarge", + "name": "CtsDevicePolicyManagerTestCases_ParentProfileApiDisabled" + } ] } |