Loading core/java/android/content/ContentResolver.java +21 −2 Original line number Diff line number Diff line Loading @@ -700,6 +700,27 @@ public abstract class ContentResolver implements ContentInterface { /** @hide */ public static final String REMOTE_CALLBACK_RESULT = "result"; /** * How long we wait for an attached process to publish its content providers * before we decide it must be hung. * @hide */ public static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS = 10 * 1000; /** * How long we wait for an provider to be published. Should be longer than * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS}. * @hide */ public static final int CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS = CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS + 10 * 1000; // Should be >= {@link #CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS}, because that's how // long ActivityManagerService is giving a content provider to get published if a new process // needs to be started for that. private static final int GET_TYPE_TIMEOUT_MILLIS = CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS + 5 * 1000; public ContentResolver(@Nullable Context context) { this(context, null); } Loading Loading @@ -849,8 +870,6 @@ public abstract class ContentResolver implements ContentInterface { } } private static final int GET_TYPE_TIMEOUT_MILLIS = 3000; private static class GetTypeResultListener implements RemoteCallback.OnResultListener { @GuardedBy("this") public boolean done; Loading core/tests/coretests/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -1330,6 +1330,12 @@ android:process=":FakeProvider"> </provider> <provider android:name="android.content.SlowProvider" android:authorities="android.content.SlowProvider" android:process=":SlowProvider"> </provider> <!-- Application components used for os tests --> <service android:name="android.os.MessengerService" Loading core/tests/coretests/src/android/content/ContentResolverTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -209,4 +209,13 @@ public class ContentResolverTest { String type = mResolver.getType(Uri.parse("content://android.content.FakeProviderRemote")); assertEquals("fake/remote", type); } @Test public void testGetType_slowProvider() { // This provider is running in a different process and is intentionally slow to start. // We are trying to confirm that it does not cause an ANR String type = mResolver.getType(Uri.parse("content://android.content.SlowProvider")); assertEquals("slow", type); } } core/tests/coretests/src/android/content/SlowProvider.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content; import android.database.Cursor; import android.net.Uri; /** * A dummy content provider for tests. This provider runs in a different process from the test and * is intentionally slow. */ public class SlowProvider extends ContentProvider { private static final int ON_CREATE_LATENCY_MILLIS = 3000; @Override public boolean onCreate() { try { Thread.sleep(ON_CREATE_LATENCY_MILLIS); } catch (InterruptedException e) { // Ignore } return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public String getType(Uri uri) { return "slow"; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } } services/core/java/com/android/server/am/ActivityManagerService.java +11 −16 Original line number Diff line number Diff line Loading @@ -466,18 +466,9 @@ public class ActivityManagerService extends IActivityManager.Stub // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; // How long we wait for an attached process to publish its content providers // before we decide it must be hung. static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; // How long we wait to kill an application zygote, after the last process using // it has gone away. static final int KILL_APP_ZYGOTE_DELAY_MS = 5 * 1000; /** * How long we wait for an provider to be published. Should be longer than * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}. */ static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000; // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real, when the process was Loading Loading @@ -4934,7 +4925,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (providers != null && checkAppInLaunchingProvidersLocked(app)) { Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); mHandler.sendMessageDelayed(msg, ContentResolver.CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS); } checkTime(startTime, "attachApplicationLocked: before bindApplication"); Loading Loading @@ -7201,7 +7193,8 @@ public class ActivityManagerService extends IActivityManager.Stub } // Wait for the provider to be published... final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT; final long timeout = SystemClock.uptimeMillis() + ContentResolver.CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS; boolean timedOut = false; synchronized (cpr) { while (cpr.provider == null) { Loading Loading @@ -7238,14 +7231,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (timedOut) { // Note we do it afer releasing the lock. // Note we do it after releasing the lock. String callerName = "unknown"; if (caller != null) { synchronized (this) { final ProcessRecord record = mProcessList.getLRURecordForAppLocked(caller); if (record != null) { callerName = record.processName; } } } Slog.wtf(TAG, "Timeout waiting for provider " + cpi.applicationInfo.packageName + "/" Loading Loading
core/java/android/content/ContentResolver.java +21 −2 Original line number Diff line number Diff line Loading @@ -700,6 +700,27 @@ public abstract class ContentResolver implements ContentInterface { /** @hide */ public static final String REMOTE_CALLBACK_RESULT = "result"; /** * How long we wait for an attached process to publish its content providers * before we decide it must be hung. * @hide */ public static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS = 10 * 1000; /** * How long we wait for an provider to be published. Should be longer than * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS}. * @hide */ public static final int CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS = CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS + 10 * 1000; // Should be >= {@link #CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS}, because that's how // long ActivityManagerService is giving a content provider to get published if a new process // needs to be started for that. private static final int GET_TYPE_TIMEOUT_MILLIS = CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS + 5 * 1000; public ContentResolver(@Nullable Context context) { this(context, null); } Loading Loading @@ -849,8 +870,6 @@ public abstract class ContentResolver implements ContentInterface { } } private static final int GET_TYPE_TIMEOUT_MILLIS = 3000; private static class GetTypeResultListener implements RemoteCallback.OnResultListener { @GuardedBy("this") public boolean done; Loading
core/tests/coretests/AndroidManifest.xml +6 −0 Original line number Diff line number Diff line Loading @@ -1330,6 +1330,12 @@ android:process=":FakeProvider"> </provider> <provider android:name="android.content.SlowProvider" android:authorities="android.content.SlowProvider" android:process=":SlowProvider"> </provider> <!-- Application components used for os tests --> <service android:name="android.os.MessengerService" Loading
core/tests/coretests/src/android/content/ContentResolverTest.java +9 −0 Original line number Diff line number Diff line Loading @@ -209,4 +209,13 @@ public class ContentResolverTest { String type = mResolver.getType(Uri.parse("content://android.content.FakeProviderRemote")); assertEquals("fake/remote", type); } @Test public void testGetType_slowProvider() { // This provider is running in a different process and is intentionally slow to start. // We are trying to confirm that it does not cause an ANR String type = mResolver.getType(Uri.parse("content://android.content.SlowProvider")); assertEquals("slow", type); } }
core/tests/coretests/src/android/content/SlowProvider.java 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.content; import android.database.Cursor; import android.net.Uri; /** * A dummy content provider for tests. This provider runs in a different process from the test and * is intentionally slow. */ public class SlowProvider extends ContentProvider { private static final int ON_CREATE_LATENCY_MILLIS = 3000; @Override public boolean onCreate() { try { Thread.sleep(ON_CREATE_LATENCY_MILLIS); } catch (InterruptedException e) { // Ignore } return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public String getType(Uri uri) { return "slow"; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
services/core/java/com/android/server/am/ActivityManagerService.java +11 −16 Original line number Diff line number Diff line Loading @@ -466,18 +466,9 @@ public class ActivityManagerService extends IActivityManager.Stub // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; // How long we wait for an attached process to publish its content providers // before we decide it must be hung. static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; // How long we wait to kill an application zygote, after the last process using // it has gone away. static final int KILL_APP_ZYGOTE_DELAY_MS = 5 * 1000; /** * How long we wait for an provider to be published. Should be longer than * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}. */ static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000; // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real, when the process was Loading Loading @@ -4934,7 +4925,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (providers != null && checkAppInLaunchingProvidersLocked(app)) { Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); msg.obj = app; mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); mHandler.sendMessageDelayed(msg, ContentResolver.CONTENT_PROVIDER_PUBLISH_TIMEOUT_MILLIS); } checkTime(startTime, "attachApplicationLocked: before bindApplication"); Loading Loading @@ -7201,7 +7193,8 @@ public class ActivityManagerService extends IActivityManager.Stub } // Wait for the provider to be published... final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT; final long timeout = SystemClock.uptimeMillis() + ContentResolver.CONTENT_PROVIDER_WAIT_TIMEOUT_MILLIS; boolean timedOut = false; synchronized (cpr) { while (cpr.provider == null) { Loading Loading @@ -7238,14 +7231,16 @@ public class ActivityManagerService extends IActivityManager.Stub } } if (timedOut) { // Note we do it afer releasing the lock. // Note we do it after releasing the lock. String callerName = "unknown"; if (caller != null) { synchronized (this) { final ProcessRecord record = mProcessList.getLRURecordForAppLocked(caller); if (record != null) { callerName = record.processName; } } } Slog.wtf(TAG, "Timeout waiting for provider " + cpi.applicationInfo.packageName + "/" Loading